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.
| Difficulty | Intermediate |
| Study time | 180 minutes |
| Prerequisites | IAM 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.
- The pipeline or action role in the tooling account needs permission to call
sts:AssumeRolefor the target role. - The target role trust policy must trust the exact approved tooling principal.
- AWS STS returns temporary credentials for an assumed-role session.
- The target role permissions policy must allow the required deployment actions.
- Resource policies must allow access when the target service uses them.
- A KMS key policy and IAM permission must allow cryptographic operations for encrypted data.
- 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:
- Pipeline action role: Can assume the target deployment role.
- Target deployment role: Can call the required S3 actions for the artifact object and bucket where needed.
- S3 bucket policy: Allows the approved target principal and does not contain a conflicting deny.
- KMS IAM permission: Allows required operations such as
kms:Decryptfor the key. - KMS key policy: Recognizes the target role or delegates permission appropriately.
- Encryption context and conditions: Match the request if policies restrict them.
- 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.
| Identity | Purpose | Typical permissions |
|---|---|---|
| Federated human role | Investigate or perform approved operations | Read access plus narrowly controlled operational actions |
| Pipeline service role | Orchestrate pipeline actions | Start actions, pass approved roles, access pipeline artifacts |
| Cross-account deployment role | Change resources for one deployment method | Scoped deployment APIs and artifact access |
| Workload runtime role | Let the application call dependencies | Only application runtime APIs |
| Break-glass role | Emergency recovery under exceptional control | Time-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.
- CodePipeline invokes an action using
CodePipelineActionRole. - That role calls
sts:AssumeRoleforProductionDeploymentRole. - STS evaluates the caller permission and the target trust policy.
- The assumed target role requests the artifact from the tooling S3 bucket.
- S3 evaluates IAM and bucket policy.
- KMS evaluates IAM permission and the key policy before decryption.
- The target deployment service evaluates the target role permissions and resource conditions.
- 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
- Record the exact API, resource ARN, account, Region, principal ARN, and error time.
- Confirm the caller is the expected assumed-role session, not a human or service role with a similar name.
- For role assumption, check both caller permission and target trust policy.
- For the target action, check the role permissions policy and any permissions boundary or session policy.
- Check the resource policy for S3, KMS, ECR, Secrets Manager, or another resource-based service.
- Check the KMS key policy separately for encrypted data.
- Check SCPs and explicit deny conditions.
- Validate condition keys such as account, ARN, Region, tag, source ARN, encryption context, and VPC endpoint.
- Use CloudTrail and service events to locate the first denied request.
- Change the narrowest incorrect statement and retest; do not attach broad administrator access as a diagnostic shortcut.
Decision matrix
| Requirement | Preferred direction | Reason |
|---|---|---|
| Strong environment isolation | Separate accounts | Reduces blast radius and clarifies ownership |
| Cross-account deployment | STS AssumeRole | Provides temporary scoped sessions |
| Human production access | Federation into a dedicated role | Central lifecycle and session evidence |
| Encrypted shared artifacts | S3 plus a customer managed KMS key and explicit policies | Supports controlled cross-account authorization |
| Independent application runtime | Separate workload role | Prevents deployment privileges at runtime |
| Emergency access | Monitored break-glass role | Keeps exceptional access separate from normal delivery |
Failure modes and troubleshooting
| Symptom | Likely missing boundary |
|---|---|
AssumeRole is denied | Caller policy, target trust policy, boundary, or SCP |
S3 GetObject is denied | Role policy, bucket policy, object ARN, or explicit deny |
| S3 succeeds but decrypt fails | KMS IAM permission, key policy, key identifier, or encryption context |
| Deployment can modify unrelated resources | Target role policy is too broad |
| Pipeline works but audit owner is unclear | Roles are shared or session metadata is weak |
| Deployment service cannot access artifact | Service 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
- Draw the tooling and production accounts, artifact bucket, KMS key, action role, deployment role, and target service.
- Write the caller policy that permits only the production role assumption.
- Write the target role trust policy for the exact tooling role.
- Define least-privilege target deployment permissions.
- List required S3 bucket, object, and KMS permissions.
- Add relevant SCP and permissions-boundary assumptions to the diagram.
- Define CloudTrail evidence for role assumption, artifact access, decryption, and deployment.
- Test or simulate these failures separately: bad trusted principal, missing S3 object permission, missing KMS key policy permission, and SCP deny.
- For each failure, record the first failed API and the narrow policy correction.
- 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
- Remove inline and attached test policies.
- Delete test roles after confirming that no pipeline uses them.
- Empty and delete the test artifact bucket if it is dedicated to the lab.
- Schedule deletion of a test KMS key only after checking for dependent encrypted data.
- Retain or export audit evidence only according to the intended retention policy.
Exam traps
- Fixing
AccessDeniedwithAdministratorAccess. - Assuming the role trust policy also grants target service permissions.
- Forgetting the caller-side
sts:AssumeRolepermission. - 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
- What does a role trust policy control?
- Why does the caller also need
sts:AssumeRolepermission? - What permissions does an assumed session receive?
- Why can S3 access succeed while artifact decryption fails?
- Why does
AdministratorAccessnot solve every cross-account deny? - What is the danger of reusing a deployment role as a runtime role?
- Which evidence connects a pipeline execution to production API calls?
- In what order should you investigate an
AccessDeniedresponse?
Model answers
- It defines which principals may assume the role and under which conditions.
- 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.
- Temporary credentials receive the permissions of the assumed role, limited further by session policy, permissions boundaries, SCPs, resource policies, and explicit denies.
- S3 and KMS perform separate authorization. The role and bucket can allow
GetObjectwhile the KMS key policy or IAM policy deniesDecrypt. - 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.
- A compromised workload could obtain infrastructure-change permissions, and runtime activity becomes difficult to distinguish from deployment activity.
- CloudTrail role-assumption and API events combined with the pipeline execution ID, source revision, role session name, artifact digest, account, and Region.
- 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.