AWS - IAM
Configure AWS IAM at Scale
IAM Cross Account Access
In this guide, we'll configure cross-account access between a Production AWS account (owns an S3 log bucket) and a Development AWS account (hosts a Log Analysts group). This setup enables secure, temporary access to logs without sharing long-term credentials.
Scenario
AWS Account | Resource | Purpose |
---|---|---|
Production Account | S3 bucket (log-bucket ) | Stores application log files |
Development Account | IAM Group (Log Analysts ) | Needs permission to list and read log files |
Our objective is to let the Log Analysts
group assume a role in the Production account to retrieve logs.
High-Level Architecture
- Create an IAM Role in the Production Account
- Attach an inline S3 policy to that role
- Update the S3 Bucket Policy to trust the role
- Assume the role from the Development Account and verify access
Cross-Account Access Components
Component | Description |
---|---|
Trust Relationship | IAM Role trust policy in the Production account allowing Dev account to assume it |
Role Assumption | sts:AssumeRole call from Dev account for temporary credentials |
Permissions Boundary | Inline policy (or managed) on the role controls S3 access |
Resource Policy | S3 Bucket policy grants the role s3:ListBucket and s3:GetObject |
Note
Be explicit in your trust policy to avoid granting unintended access. Restrict Principal
to specific IAM roles or account IDs.
Demo Walkthrough
Follow these steps to implement and test cross-account S3 access.
1. Create the IAM Role in Production
Create a trust policy (trust-policy.json
):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::DEV_ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole"
}
]
}
Use the AWS CLI to create the role:
aws iam create-role \
--role-name DevLogAccessRole \
--assume-role-policy-document file://trust-policy.json \
--description "Allows Dev account to access logs" \
--profile prod-account
2. Attach an Inline S3 Access Policy
Define s3-access-policy.json
:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::log-bucket",
"arn:aws:s3:::log-bucket/*"
]
}
]
}
Attach it to the role:
aws iam put-role-policy \
--role-name DevLogAccessRole \
--policy-name S3LogAccess \
--policy-document file://s3-access-policy.json \
--profile prod-account
3. Update the S3 Bucket Policy
Create or edit your bucket policy (bucket-policy.json
):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowDevRoleAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::PROD_ACCOUNT_ID:role/DevLogAccessRole"
},
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::log-bucket",
"arn:aws:s3:::log-bucket/*"
]
}
]
}
Apply it:
aws s3api put-bucket-policy \
--bucket log-bucket \
--policy file://bucket-policy.json \
--profile prod-account
Warning
Ensure the bucket policy’s Principal
matches the exact ARN of the role. Using wildcards may expose your bucket to unintended access.
4. Assume the Role and Verify Access
From the Development account, assume the role:
aws sts assume-role \
--role-arn arn:aws:iam::PROD_ACCOUNT_ID:role/DevLogAccessRole \
--role-session-name LogAnalysisSession \
--profile dev-account > assume-role-output.json
Export temporary credentials:
export AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' assume-role-output.json)
export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' assume-role-output.json)
export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' assume-role-output.json)
List and retrieve logs:
aws s3 ls s3://log-bucket
aws s3 cp s3://log-bucket/example.log .
References
Watch Video
Watch video content