The Problem
Your management account has an S3 bucket with project reports. You want all accounts in your AWS Organization to be able to access it — including future accounts you have not created yet — with the least operational overhead.
The Solution
Add the aws:PrincipalOrgID global condition key to the bucket policy. One static policy, evaluated against the caller’s organization at request time.
How It Works
The Bucket Policy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowOrgAccess",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::project-reports/*",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-abcd1234"
}
}
}]
}
At request time, AWS looks up the caller’s organization ID and compares it to o-abcd1234. Match → allowed. Mismatch or not in an org → denied.
Why This Beats Enumerating Accounts
Without aws:PrincipalOrgID, you would list every account ID in the Principal field:
1
2
3
4
5
6
7
8
"Principal": {
"AWS": [
"arn:aws:iam::111111111111:root",
"arn:aws:iam::222222222222:root",
"arn:aws:iam::333333333333:root",
...
]
}
Every new account requires a policy update. aws:PrincipalOrgID eliminates this entirely.
Related Condition Keys
| Key | Purpose |
|---|---|
aws:PrincipalOrgID |
Match a specific organization |
aws:PrincipalOrgPaths |
Match a specific OU path (e.g., only Finance OU) |
aws:SourceOrgID |
Match the caller’s org (for cross-account service calls) |
aws:PrincipalAccount |
Match a specific account ID |
aws:PrincipalTag/<key> |
Match a tag on the caller |
Use PrincipalOrgID when you want everyone in the org. Use PrincipalOrgPaths when you want a specific OU subtree.
Getting Your Organization ID
1
2
aws organizations describe-organization \
--query 'Organization.Id' --output text
Returns something like o-abcd1234.
Why Not the Alternatives?
aws:PrincipalOrgPaths with per-department OUs — Works but more complex than needed. Use PrincipalOrgID when the whole org gets access.
CloudTrail monitoring account events + policy updates — Reactive and high overhead. Every account change triggers a policy rewrite. Terrible operational model.
Tagging every user + aws:PrincipalTag — Requires tagging every principal in every account, then keeping the tags in sync. Massive management burden.
Key Takeaways
aws:PrincipalOrgIDis the least-overhead way to grant org-wide access- One policy, no updates when accounts are added or removed
- Use
aws:PrincipalOrgPathsfor OU-level scoping,aws:PrincipalOrgIDfor org-wide - These condition keys work in any resource-based policy: S3, SNS, SQS, KMS, Secrets Manager
- Combine with
aws:SecureTransportand other conditions for defense in depth
Never miss a story from us, subscribe to our newsletter