Harden ABAC with two-tier boundary and team isolation#97
Merged
Conversation
Two-tier permission boundary:
- Org boundary (human-applied): structural denies for all roles
- Developer boundary (CI-applied): org denies + team ABAC + naming enforcement
Developer boundary adds: DenyXTeam (cross-team tag isolation), DenyShared,
DenyTagStrip, DenyPassRole, DenyXLogs, DenyModCI, DenyBadName (naming),
DenyNoTag (SG tag enforcement), DenySecSvcs (security + Bedrock),
DenyPlatSSM, DenyPlatInfra
CI role changes:
- Team roles use developer boundary, AllowAll + backend (boundary does denies)
- Deploy roles trust via broker only (not direct OIDC)
- ECR scoped to {team}-*, PassRole to {team}-*, logs to /ecs/{team}/*
- Removed redundant inline deny policies (boundary handles it)
The org boundary doesn't exist yet (human-applied), so the data source fails during plan. Construct the ARN from variables instead.
Terraform Plan🚧 Changes detected — Plan: 1 to add, 77 to change, 1 to destroy. Plan outputLLM ReviewRisk: 🟡 MEDIUM Terraform plan updates tags across 50+ resources from "javabin" to "platform", creates a new developer permission boundary policy, updates IAM role permission boundaries, and removes a team-specific deny policy.
|
Alexanderamiri
added a commit
that referenced
this pull request
May 9, 2026
## Summary
- Split permission boundary into two tiers: **org boundary**
(human-applied, structural denies) and **developer boundary**
(CI-applied, org denies + team ABAC + naming enforcement)
- Developer boundary adds 12 deny statements: DenyXTeam, DenyShared,
DenyTagStrip, DenyPassRole, DenyXLogs, DenyModCI, DenyBadName,
DenyNoTag, DenySecSvcs, DenyPlatSSM, DenyPlatInfra, plus structural
denies
- CI team roles simplified to AllowAll + backend access (boundary
handles all deny logic)
- Deploy roles trust changed from direct OIDC to broker-mediated
(apply-gate Lambda only)
- Deploy role scoping tightened: ECR `{team}-*`, PassRole `{team}-*`,
logs `/ecs/{team}/*`
- Bedrock denied for team roles (platform-only for plan review/cost
narratives)
- SG creation requires team tag via `aws:RequestTag`
- Policy fits in 6,142/6,144 bytes
## Test plan
- [ ] `terraform plan` on `terraform/platform/` — verify no unexpected
destroys (moved block handles boundary rename)
- [ ] `terraform plan` on `terraform/org/` — verify org boundary changes
- [ ] Verify developer boundary JSON < 6,144 bytes after variable
substitution
- [ ] Test team CI role can create resources with `{team}-*` prefix
- [ ] Test team CI role CANNOT create resources with wrong prefix
- [ ] Test deploy role can push to `{team}-*` ECR repo
- [ ] Test deploy role CANNOT push to other team's ECR repo
- [ ] Verify platform SSM secrets are unreadable by team roles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
{team}-*, PassRole{team}-*, logs/ecs/{team}/*aws:RequestTagTest plan
terraform planonterraform/platform/— verify no unexpected destroys (moved block handles boundary rename)terraform planonterraform/org/— verify org boundary changes{team}-*prefix{team}-*ECR repo