Skip to main content

Accounts, environments, and IAM boundaries

Exam alignment: Domain 1.1 and 1.4: implement secure pipelines and deployment strategies across environments and accounts.

Learning objective

Design and troubleshoot a multi-account deployment path using AWS accounts, IAM roles, trust policies, permissions policies, STS temporary credentials, S3 artifact access, KMS key policies, and organization guardrails.

DifficultyIntermediate
Study time180 minutes
PrerequisitesIAM roles and policies, AWS Organizations basics, and pipeline artifacts

Professional scenario

Development and production share one AWS account and one administrator role. Developers can change production resources, and the pipeline uses the same permissions as the application at runtime. Artifacts are copied manually before release.

The organization wants a centralized delivery account, separate development and production accounts, encrypted artifacts, no stored deployment keys, and evidence of every production role session.

This is not solved by “use multiple accounts” alone. The full request must be authorized across every boundary that it crosses.

Why accounts are environment boundaries

An AWS account is a strong boundary for identity, quotas, billing, service configuration, and resource ownership. Separate production and non-production accounts reduce the chance that a development identity, automation error, quota event, or compromised workload affects production.

A common delivery layout is:

Organization
|
+-- Tooling account
| +-- source connection
| +-- CodePipeline
| +-- CodeBuild
| +-- encrypted artifact bucket
|
+-- Development account
| +-- deployment role
| +-- development workload
|
+-- Production account
+-- deployment role
+-- production workload

The tooling account orchestrates. Target accounts own their resources and decide what the tooling pipeline may do. The pipeline does not receive permanent credentials for either target account.

The cross-account authorization chain

For a principal in the tooling account to use a deployment role in production, both sides of the relationship must agree.

  1. The pipeline or action role in the tooling account needs permission to call sts:AssumeRole for the target role.
  2. The target role trust policy must trust the exact approved tooling principal.
  3. AWS STS returns temporary credentials for an assumed-role session.
  4. The target role permissions policy must allow the required deployment actions.
  5. Resource policies must allow access when the target service uses them.
  6. A KMS key policy and IAM permission must allow cryptographic operations for encrypted data.
  7. SCPs, permissions boundaries, session policies, and explicit denies must not block the request.

An allow in one layer never cancels an explicit deny in another. Adding AdministratorAccess to the target role does not fix an SCP deny or a KMS key policy that does not authorize the role.

Trust policy versus permissions policy

The trust policy answers who may obtain a session for this role. The role permissions policy answers what that session may do after assumption.

Example trust policy on a production deployment role:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/CodePipelineActionRole"
},
"Action": "sts:AssumeRole"
}
]
}

The tooling action role also needs an identity policy that permits the call:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::222222222222:role/ProductionDeploymentRole"
}
]
}

These policies establish role assumption; they do not grant deployment permissions. A separate policy on ProductionDeploymentRole should allow only the services, actions, and resources required by the chosen deployment mechanism.

Avoid trusting an entire account when one specific role is sufficient. Also avoid a broad target permissions policy merely because the pipeline is trusted. Trust and authorization are separate least-privilege decisions.

Temporary credentials and session evidence

AssumeRole returns an access key ID, secret access key, and session token with a limited lifetime. The pipeline uses those credentials for the target action and discards them when the session ends.

CloudTrail records the role-assumption event and subsequent API calls made by the assumed-role session. A useful session name and consistent pipeline metadata improve traceability. Evidence should connect:

  • pipeline and execution ID
  • source revision and artifact digest
  • original action role
  • target role and session
  • target account and Region
  • deployment API calls and result

Temporary credentials reduce the risk of a leaked long-lived key, but they do not compensate for an overprivileged role. Session duration and permissions should both match the task.

Encrypted cross-account artifacts

Cross-account deployments often fail at the artifact path rather than at AssumeRole.

For an encrypted artifact in the tooling account, consider each authorization point:

  1. Pipeline action role: Can assume the target deployment role.
  2. Target deployment role: Can call the required S3 actions for the artifact object and bucket where needed.
  3. S3 bucket policy: Allows the approved target principal and does not contain a conflicting deny.
  4. KMS IAM permission: Allows required operations such as kms:Decrypt for the key.
  5. KMS key policy: Recognizes the target role or delegates permission appropriately.
  6. Encryption context and conditions: Match the request if policies restrict them.
  7. Organization guardrails: Do not deny S3, KMS, STS, or deployment actions.

For cross-account CodePipeline actions, use a customer managed KMS key for the artifact store and identify it with a key ID or ARN as required by the design. A KMS alias is meaningful only in the account that owns it and should not be treated as a universal cross-account identifier.

Human, pipeline, deployment, and runtime identities

Do not combine identities merely because they access the same application.

IdentityPurposeTypical permissions
Federated human roleInvestigate or perform approved operationsRead access plus narrowly controlled operational actions
Pipeline service roleOrchestrate pipeline actionsStart actions, pass approved roles, access pipeline artifacts
Cross-account deployment roleChange resources for one deployment methodScoped deployment APIs and artifact access
Workload runtime roleLet the application call dependenciesOnly application runtime APIs
Break-glass roleEmergency recovery under exceptional controlTime-bound, monitored, and separately approved

If the deployment role becomes the runtime role, a compromised application may gain infrastructure-change permissions. If developers use the pipeline role interactively, the audit trail no longer represents automated delivery accurately.

Worked request path

Suppose CodePipeline in account 111111111111 deploys an encrypted artifact to production account 222222222222.

  1. CodePipeline invokes an action using CodePipelineActionRole.
  2. That role calls sts:AssumeRole for ProductionDeploymentRole.
  3. STS evaluates the caller permission and the target trust policy.
  4. The assumed target role requests the artifact from the tooling S3 bucket.
  5. S3 evaluates IAM and bucket policy.
  6. KMS evaluates IAM permission and the key policy before decryption.
  7. The target deployment service evaluates the target role permissions and resource conditions.
  8. CloudTrail in the relevant accounts records the role session and service calls.

When the request fails, identify the first failed arrow. Do not start by expanding every policy.

Systematic AccessDenied investigation

  1. Record the exact API, resource ARN, account, Region, principal ARN, and error time.
  2. Confirm the caller is the expected assumed-role session, not a human or service role with a similar name.
  3. For role assumption, check both caller permission and target trust policy.
  4. For the target action, check the role permissions policy and any permissions boundary or session policy.
  5. Check the resource policy for S3, KMS, ECR, Secrets Manager, or another resource-based service.
  6. Check the KMS key policy separately for encrypted data.
  7. Check SCPs and explicit deny conditions.
  8. Validate condition keys such as account, ARN, Region, tag, source ARN, encryption context, and VPC endpoint.
  9. Use CloudTrail and service events to locate the first denied request.
  10. Change the narrowest incorrect statement and retest; do not attach broad administrator access as a diagnostic shortcut.

Decision matrix

RequirementPreferred directionReason
Strong environment isolationSeparate accountsReduces blast radius and clarifies ownership
Cross-account deploymentSTS AssumeRoleProvides temporary scoped sessions
Human production accessFederation into a dedicated roleCentral lifecycle and session evidence
Encrypted shared artifactsS3 plus a customer managed KMS key and explicit policiesSupports controlled cross-account authorization
Independent application runtimeSeparate workload rolePrevents deployment privileges at runtime
Emergency accessMonitored break-glass roleKeeps exceptional access separate from normal delivery

Failure modes and troubleshooting

SymptomLikely missing boundary
AssumeRole is deniedCaller policy, target trust policy, boundary, or SCP
S3 GetObject is deniedRole policy, bucket policy, object ARN, or explicit deny
S3 succeeds but decrypt failsKMS IAM permission, key policy, key identifier, or encryption context
Deployment can modify unrelated resourcesTarget role policy is too broad
Pipeline works but audit owner is unclearRoles are shared or session metadata is weak
Deployment service cannot access artifactService role, deployment role, or artifact ownership is incorrect

Security and operations

  • Trust exact role ARNs where practical instead of whole accounts.
  • Scope target permissions by action, resource, Region, and conditions.
  • Separate production and non-production deployment roles.
  • Prevent direct human assumption of automation roles unless explicitly required and controlled.
  • Protect artifact deletion and KMS key administration separately from deployment.
  • Monitor failed and unusual role assumptions.
  • Review unused permissions and shorten session duration to the operational need.

Hands-on lab: design and test a two-account trust model

Goal: Produce a complete authorization design for a tooling account and a production account.

Tasks

  1. Draw the tooling and production accounts, artifact bucket, KMS key, action role, deployment role, and target service.
  2. Write the caller policy that permits only the production role assumption.
  3. Write the target role trust policy for the exact tooling role.
  4. Define least-privilege target deployment permissions.
  5. List required S3 bucket, object, and KMS permissions.
  6. Add relevant SCP and permissions-boundary assumptions to the diagram.
  7. Define CloudTrail evidence for role assumption, artifact access, decryption, and deployment.
  8. Test or simulate these failures separately: bad trusted principal, missing S3 object permission, missing KMS key policy permission, and SCP deny.
  9. For each failure, record the first failed API and the narrow policy correction.
  10. Verify that a developer identity and the workload runtime role cannot assume the deployment role.

Validation checklist

  • The pipeline can assume only the intended target role.
  • The trust policy does not grant deployment actions by itself.
  • The target role can modify only intended resources.
  • Artifact and KMS authorization are both explicit.
  • Human, pipeline, deployment, and runtime identities remain separate.
  • CloudTrail evidence identifies the session and resulting calls.
  • An explicit organization deny is not “fixed” with a broader IAM allow.

Cost control: Policy design and IAM simulation are free. If using live resources, use an empty encrypted S3 object and delete test roles, policies, bucket objects, and keys according to their deletion rules.

Cleanup

  1. Remove inline and attached test policies.
  2. Delete test roles after confirming that no pipeline uses them.
  3. Empty and delete the test artifact bucket if it is dedicated to the lab.
  4. Schedule deletion of a test KMS key only after checking for dependent encrypted data.
  5. Retain or export audit evidence only according to the intended retention policy.

Exam traps

  • Fixing AccessDenied with AdministratorAccess.
  • Assuming the role trust policy also grants target service permissions.
  • Forgetting the caller-side sts:AssumeRole permission.
  • Allowing S3 access but forgetting KMS authorization.
  • Treating an SCP as a policy that grants access.
  • Using stored access keys for cross-account deployment.
  • Reusing the deployment role as the workload runtime role.

Key takeaways

  • Accounts isolate environments, but every cross-account request still needs complete authorization.
  • Role assumption requires caller permission and target trust.
  • The assumed role permissions determine target actions.
  • Encrypted artifacts add independent S3 and KMS authorization layers.
  • Explicit denies and organization guardrails override otherwise valid allows.
  • Separate identities preserve least privilege and reliable audit evidence.

Review questions

  1. What does a role trust policy control?
  2. Why does the caller also need sts:AssumeRole permission?
  3. What permissions does an assumed session receive?
  4. Why can S3 access succeed while artifact decryption fails?
  5. Why does AdministratorAccess not solve every cross-account deny?
  6. What is the danger of reusing a deployment role as a runtime role?
  7. Which evidence connects a pipeline execution to production API calls?
  8. In what order should you investigate an AccessDenied response?
Model answers
  1. It defines which principals may assume the role and under which conditions.
  2. Cross-account role assumption is an agreement between both accounts. The trusted caller must be allowed to request the role, and the trusting role must accept that caller.
  3. Temporary credentials receive the permissions of the assumed role, limited further by session policy, permissions boundaries, SCPs, resource policies, and explicit denies.
  4. S3 and KMS perform separate authorization. The role and bucket can allow GetObject while the KMS key policy or IAM policy denies Decrypt.
  5. An SCP, resource policy, KMS key policy, permissions boundary, session policy, or explicit deny can still block the request. A broad identity allow cannot override an explicit deny.
  6. A compromised workload could obtain infrastructure-change permissions, and runtime activity becomes difficult to distinguish from deployment activity.
  7. CloudTrail role-assumption and API events combined with the pipeline execution ID, source revision, role session name, artifact digest, account, and Region.
  8. Capture the exact failed request, verify the actual principal, then evaluate caller permission, trust policy, target permissions, resource policy, KMS policy, boundaries, SCPs, and conditions until the first deny is found.

Further reading