IAM Roles and Cross-Account Access
IAM Roles and Cross-Account Access are fundamental concepts in AWS identity and access management that enable secure delegation of permissions without sharing long-term credentials. **IAM Roles** are AWS identities with specific permission policies that determine what actions are allowed or denied… IAM Roles and Cross-Account Access are fundamental concepts in AWS identity and access management that enable secure delegation of permissions without sharing long-term credentials. **IAM Roles** are AWS identities with specific permission policies that determine what actions are allowed or denied. Unlike IAM users, roles do not have permanent credentials (passwords or access keys). Instead, they provide temporary security credentials through AWS Security Token Service (STS) when assumed. Roles can be assumed by IAM users, AWS services, applications, or federated users. Key components of an IAM Role include: - **Trust Policy**: Defines which principals (accounts, users, or services) are allowed to assume the role. - **Permission Policy**: Specifies what actions and resources the role grants access to. - **Session Duration**: Configurable timeout for temporary credentials (default 1 hour, max 12 hours). **Cross-Account Access** allows users or services in one AWS account (trusted account) to access resources in another account (trusting account). This is achieved by: 1. **Creating a role** in the trusting account with a trust policy that references the trusted account's ID. 2. **Granting assume-role permissions** to users/roles in the trusted account. 3. **Assuming the role** using `sts:AssumeRole` API call, which returns temporary credentials. This pattern is critical for organizations managing multiple AWS accounts, enabling centralized access management, resource sharing, and least-privilege enforcement. **Security Best Practices:** - Use **External ID** conditions in trust policies to mitigate the confused deputy problem. - Implement **MFA requirements** (aws:MultiFactorAuthPresent condition) for sensitive cross-account roles. - Apply **least-privilege permissions** to roles. - Monitor role assumption using **AWS CloudTrail** logs. - Use **IAM Access Analyzer** to identify unintended cross-account access. - Leverage **AWS Organizations SCPs** to restrict which accounts can assume specific roles. Cross-account access via IAM roles is preferred over sharing credentials, as it provides auditability, temporary access, and granular control over permissions across organizational boundaries.
IAM Roles and Cross-Account Access – AWS Security Specialty Guide
Why IAM Roles and Cross-Account Access Matter
In modern cloud environments, organizations rarely operate with a single AWS account. Multi-account strategies are the norm for separating workloads, environments, and teams. IAM Roles and Cross-Account Access form the backbone of secure identity delegation in AWS, enabling principals in one account to securely access resources in another without sharing long-term credentials. For the AWS Security Specialty exam, this topic is foundational — it appears in questions about least-privilege design, federation, incident response, and secure architectures.
Without IAM roles, teams would need to create IAM users with permanent access keys in every account, dramatically increasing the attack surface. Roles eliminate this risk by providing temporary, automatically rotated credentials through the AWS Security Token Service (STS).
What Are IAM Roles?
An IAM Role is an AWS identity with specific permissions, but unlike an IAM user, it does not have long-term credentials (passwords or access keys). Instead, when a principal assumes a role, AWS STS issues temporary security credentials consisting of an access key ID, a secret access key, and a session token. These credentials expire automatically after a configurable duration (from 15 minutes to 12 hours, depending on the method of assumption).
Key components of an IAM Role:
1. Trust Policy (AssumeRole Policy): A resource-based JSON policy attached to the role that defines who is allowed to assume the role. This can include AWS accounts, IAM users, IAM roles, AWS services, federated identities, or even specific conditions like MFA requirements or source IP restrictions.
2. Permissions Policy: One or more identity-based policies (managed or inline) attached to the role that define what the role can do once assumed — for example, reading from an S3 bucket or managing EC2 instances.
3. Session Duration: The maximum time the temporary credentials remain valid.
4. External ID (optional): A unique identifier used in cross-account scenarios to mitigate the confused deputy problem.
What Is Cross-Account Access?
Cross-Account Access is the mechanism by which a principal (user, role, or service) in one AWS account (the trusting account or source account) can access resources in another AWS account (the trusted account or target account). This is primarily accomplished using IAM roles combined with STS AssumeRole.
How Cross-Account Access Works — Step by Step
Step 1: Create a Role in the Target Account (Account B)
- In Account B (the account that owns the resources), create an IAM role.
- Attach a trust policy that allows Account A's principal(s) to assume it:
Example Trust Policy:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::ACCOUNT_A_ID:root"},
"Action": "sts:AssumeRole",
"Condition": {"StringEquals": {"sts:ExternalId": "UniqueExternalID123"}}
}]
}
- Attach permissions policies that grant the necessary access to resources in Account B.
Step 2: Grant Permission in the Source Account (Account A)
- In Account A, the IAM user or role that needs cross-account access must have an IAM policy that allows calling sts:AssumeRole on the role ARN in Account B.
Example Permission in Account A:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNT_B_ID:role/CrossAccountRole"
}]
}
Step 3: Assume the Role
- The principal in Account A calls sts:AssumeRole, specifying the role ARN in Account B (and the ExternalId if required).
- STS validates: (a) The caller in Account A has permission to call AssumeRole. (b) The trust policy on the role in Account B allows the caller. (c) Any conditions (MFA, ExternalId, source IP, etc.) are met.
- STS returns temporary credentials scoped to the permissions of the assumed role.
Step 4: Access Resources
- The caller uses the temporary credentials to make API calls against resources in Account B.
- All actions are logged in both accounts' CloudTrail logs — the AssumeRole event in Account A and the subsequent API calls in Account B.
The Confused Deputy Problem
This is a critical security concept for the exam. The confused deputy problem occurs when a third-party service (the deputy) is tricked into acting on resources it shouldn't. For example, if a third-party SaaS provider uses a cross-account role to access your account, another customer of that provider could potentially trick the provider into accessing your resources instead of theirs.
Solution: External ID. The External ID is a secret shared between you and the third party. It is included as a condition in the trust policy, so even if an attacker knows the role ARN, they cannot assume the role without the correct External ID. The External ID is not a replacement for other security measures but an additional layer of protection.
Key Concepts for the Exam
1. STS AssumeRole vs. AssumeRoleWithSAML vs. AssumeRoleWithWebIdentity:
- AssumeRole: Used for cross-account access, delegation, and role chaining.
- AssumeRoleWithSAML: Used for enterprise federation via SAML 2.0 identity providers.
- AssumeRoleWithWebIdentity: Used for web/mobile federation (Cognito, Google, Facebook, etc.). AWS recommends using Cognito for this.
2. Role Chaining: A role can assume another role. However, role chaining limits session duration to a maximum of 1 hour, and you cannot pass session tags as transitive tags in every scenario. Each hop in the chain creates a new set of temporary credentials.
3. Service-Linked Roles: Predefined roles that are linked directly to an AWS service. You cannot modify the permissions. They are auto-created when you enable certain services. Important for the exam when a question asks about permissions for services like AWS Config, GuardDuty, or Organizations.
4. Resource-Based Policies vs. Role-Based Cross-Account Access:
- Some services (S3, SNS, SQS, KMS, Lambda) support resource-based policies that can grant cross-account access directly without assuming a role.
- Key difference: When using a resource-based policy, the principal retains its original permissions AND gains the permissions from the resource policy. When assuming a role, the principal gives up its original permissions and operates solely with the assumed role's permissions.
- This distinction is heavily tested.
5. AWS Organizations and SCPs: Service Control Policies (SCPs) in AWS Organizations apply to all accounts in the organization. Even if a role's permissions policy allows an action, an SCP can deny it. SCPs do not grant permissions — they set maximum permission boundaries. Cross-account access within an organization still requires proper IAM role configuration, but SCPs add an additional evaluation layer.
6. Permission Boundaries: These set the maximum permissions an IAM entity can have. The effective permissions are the intersection of the identity-based policy, the permission boundary, and any applicable SCPs. Exam questions may test scenarios where a role has broad permissions but a permission boundary restricts the effective actions.
7. Session Policies: Optional policies passed as parameters when assuming a role. They further restrict the session's effective permissions to the intersection of the role's policies and the session policy.
8. MFA with AssumeRole: You can require MFA in the trust policy using the condition key aws:MultiFactorAuthPresent or aws:MultiFactorAuthAge. This is a common exam scenario for adding security to cross-account access.
Cross-Account Access Patterns Tested in the Exam
- Centralized Logging Account: Multiple accounts send logs (CloudTrail, VPC Flow Logs, Config) to a central S3 bucket. The bucket policy grants cross-account write access, and the logging accounts assume a role or use resource-based policies.
- Centralized Security Account: A security account assumes roles in member accounts to run audits, read configurations, or respond to incidents (e.g., GuardDuty master/member, Security Hub).
- Third-Party Access: Granting a vendor or partner access to your account using a cross-account role with an External ID.
- AWS Organizations Cross-Account: Using aws:PrincipalOrgID condition key to restrict resource-based policies to only accounts within your organization.
- KMS Cross-Account Access: Sharing KMS keys across accounts requires both a key policy in the target account AND an IAM policy in the source account. This is frequently tested.
- S3 Cross-Account Object Ownership: When Account A writes objects to Account B's bucket, Account B may not own those objects unless the bucket has Object Ownership set to BucketOwnerEnforced or the writer includes the bucket-owner-full-control ACL.
CloudTrail and Monitoring Cross-Account Role Assumption
- sts:AssumeRole events appear in CloudTrail in both the source and target accounts.
- The CloudTrail event includes the role ARN, the calling principal, the source IP, and any conditions like ExternalId.
- You can create CloudWatch alarms or EventBridge rules to detect unauthorized cross-account role assumptions.
- GuardDuty can detect unusual cross-account activity.
Best Practices
- Always use the principle of least privilege for role permissions.
- Always use External IDs for third-party cross-account roles.
- Require MFA for sensitive cross-account operations.
- Use condition keys in trust policies (aws:PrincipalOrgID, aws:SourceIp, aws:PrincipalTag, etc.).
- Monitor cross-account role assumptions with CloudTrail, CloudWatch, and GuardDuty.
- Use permission boundaries to limit the maximum permissions of roles created by delegated administrators.
- Prefer cross-account roles over sharing long-term credentials (access keys) — never share access keys across accounts.
- Use aws:PrincipalOrgID in resource-based policies to restrict access to your organization only.
Exam Tips: Answering Questions on IAM Roles and Cross-Account Access
1. Read the trust policy carefully. Many questions present a trust policy and ask why access is being denied. Common issues include: missing or incorrect Principal ARN, missing condition keys (ExternalId, MFA), or the trust policy specifying a specific IAM user but the caller is a different user or role.
2. Remember the two-sided requirement. Cross-account access requires configuration in BOTH accounts: a trust policy in the target account AND an IAM permission in the source account. If a question describes only one side being configured, that is likely the issue.
3. Confused deputy = External ID. If a question mentions third-party access and asks how to prevent the confused deputy problem, the answer is always External ID in the trust policy condition.
4. Resource-based policy vs. AssumeRole. If the question asks about accessing resources without giving up the caller's original permissions, the answer is resource-based policies. If the question requires the caller to operate under a different set of permissions, the answer is AssumeRole.
5. KMS cross-account questions require both key policy AND IAM policy. If the question says a user in Account A cannot decrypt data encrypted with a KMS key in Account B, check for: (a) Key policy in Account B granting Account A access, (b) IAM policy in Account A allowing kms:Decrypt on the key ARN.
6. SCP restrictions. If a question involves AWS Organizations and a role has the right permissions but access is still denied, consider whether an SCP is blocking the action.
7. Role chaining = 1-hour max session. If a question mentions session duration issues with chained roles, remember the 1-hour limit.
8. Temporary credentials are always preferred. Any answer choice involving long-term access keys for cross-account access is almost certainly wrong. Prefer roles and temporary credentials.
9. For S3 cross-account writes, remember object ownership. If Account B cannot read objects written by Account A, the solution is either BucketOwnerEnforced object ownership or requiring the bucket-owner-full-control ACL.
10. When in doubt, apply least privilege. The most restrictive option that still meets the requirements is usually the correct answer. Avoid answers that use wildcard (*) principals in trust policies or overly broad permissions.
11. Look for aws:PrincipalOrgID. When a question asks about restricting cross-account access to only accounts within your AWS Organization, this condition key is the answer — it is more scalable than listing individual account IDs.
12. Revocation of temporary credentials. If a question asks how to immediately revoke access from a compromised cross-account role session, the answer involves adding a deny-all inline policy to the role with a condition on aws:TokenIssueTime to invalidate sessions issued before a certain time. Simply deleting the role or changing the trust policy does not revoke already-issued temporary credentials until they expire.
Unlock Premium Access
AWS Certified Security – Specialty (SCS-C02) + ALL Certifications
- Access to ALL Certifications: Study for any certification on our platform with one subscription
- 2160 Superior-grade AWS Certified Security – Specialty (SCS-C02) practice questions
- Unlimited practice tests across all certifications
- Detailed explanations for every question
- AWS SCS-C02: 5 full exams plus all other certification exams
- 100% Satisfaction Guaranteed: Full refund if unsatisfied
- Risk-Free: 7-day free trial with all premium features!