ADR: Zone-Scoped IAM Access via Azure Entra ID and AWS IAM Identity Center
- Status: Research / RFC
- Date: 2026-03-09
- Decision Makers: Entigo RnD Team
Context
Entigo Platform organizes customer workloads into zones — logical isolation boundaries that map to sets of AWS resources tagged with entigo:zone. Users need zone-scoped access to AWS services for imperative operations that the platform's declarative API does not mediate — for example, restarting an RDS instance or managing secrets in AWS Secrets Manager.
The desired model: a user's Azure Entra ID group membership (e.g., entigo-zone-prod-1) dynamically determines which zone's AWS resources they can operate on. The integration path is Azure Entra ID → SAML/SCIM → AWS IAM Identity Center → session tags → IAM policy conditions.
This ADR builds on the ABAC capability established in Permission Boundaries ADR, which defines workspace and zone isolation using AWS IAM Permission Boundaries and resource tags. The permission boundary and zone-scoped identity policies described there apply to IAM roles used by the platform. This ADR addresses how human users accessing AWS through SSO can get equivalent zone-scoped access.
Scale
- 100–200 zones, managed by different departments
- Zone lifecycle is decentralized — departments create zones independently
- Individual users may have access to tens of zones simultaneously
- Users need to perform imperative AWS operations (RDS restart, Secrets Manager CRUD) scoped to their zones
Problem Statement
The platform needs a mechanism where:
- Zone access is derived from Entra ID group membership
- IAM policies enforce that users can only operate on resources tagged with their zone(s)
- New zones can be onboarded without central IAM reconfiguration
- Users with multi-zone access can operate across their authorized zones
Research Findings
AWS Session Tags Do Not Support Multiple Values Per Key
AWS STS explicitly states: "You must pass a single value for each session tag. AWS STS does not support multi-valued session tags." A new session tag with the same key overwrites the previous value. The aws:PrincipalTag/tag-key context key is single-valued — there is no ForAnyValue operator available for it.
Consequence: The original design concept — emitting multiple entigo:zone session tags from multiple group memberships — is not possible. A user in both entigo-zone-prod-1 and entigo-zone-staging-1 cannot carry both zone values in a single AWS session.
No Regex-Based Attribute Extraction in IAM Identity Center
Neither IAM Identity Center's "Attributes for access control" nor the IAM SAML PrincipalTag mapping supports regex pattern extraction from group names. SAML-to-session-tag mapping requires a specific SAML attribute name per tag key (https://aws.amazon.com/SAML/Attributes/PrincipalTag:{TagKey} or AccessControl:{TagKey}). There is no built-in mechanism on the AWS side that extracts values from multi-valued group membership attributes.
Regex-based claim transformation exists on the Entra ID side (SAML claim rules support regex replacement), but this transforms individual claim values — it cannot aggregate multiple group memberships into a structured output.
SCIM Does Not Carry Custom Attributes to Identity Center
SCIM provisioning between Entra and IAM Identity Center syncs users, groups, and group membership. It does not carry arbitrary custom attributes or ABAC tags. AWS's SCIM implementation does not support custom schema extensions. IAM Identity Center also does not support multi-valued attributes via SCIM.
Consequence: There is no way to derive a tag value from a group name pattern via SCIM and attach it to the user or group in Identity Center.
ABAC Attributes for Access Control — Two Sources, Both Limited
ABAC tags in IAM Identity Center originate from:
- Identity Store attributes — configured in "Attributes for access control" settings, mapping from fixed SCIM user attributes (e.g.,
${path:enterprise.department}). These are user-level, not group-level, and limited to the standard SCIM schema. - SAML assertions — the external IdP emits attributes with the
AccessControl:{TagKey}prefix at login time. These are passed directly to the AWS account. However, IAM Identity Center does not support multi-value attributes for ABAC.
Neither source supports deriving tag values from group membership patterns or carrying multiple values for a single tag key.
IAM Policy Variable Substitution Is Single-Valued
Even if multiple tag values could be attached to a session, IAM policy variable substitution (${aws:PrincipalTag/key}) resolves to a single value. There is no IAM policy mechanism to express "does the user have any tag key matching this resource's zone tag" across a dynamic set of keys.
Options Evaluated
Option 1: Multi-Valued Session Tags (Original Design)
Approach: Entra emits group membership as multiple SAML attributes mapping to session tags with the same key. A user in multiple zone groups gets multiple entigo:zone tags.
Status: Not viable. AWS STS does not support multiple values per session tag key. The second value overwrites the first.
Option 2: Separate Boolean Session Tags Per Zone
Approach: Emit individual tags per zone: entigo-zone-prod-1=true, entigo-zone-staging-1=true. Policy checks aws:PrincipalTag/entigo-zone-{zone}.
Challenges:
- 50 session tags maximum per session — with tens of zones per user plus other tags, this is tight
- IAM policy cannot dynamically resolve
aws:PrincipalTag/entigo-zone-${rds:ResourceTag/entigo:zone}— nested variable substitution is not supported - Each zone requires a separate SAML claim rule in Entra — doesn't scale to 200 zones without automation
Status: Not viable due to the nested variable substitution limitation. The policy cannot generically match "user has a tag for this resource's zone" without hardcoding every zone name in the policy.
Option 3: Concatenated Tag Value with StringLike
Approach: Entra emits a single SAML claim AccessControl:entigo-zones with a delimited value like |prod-1|staging-1|prod-2|. IAM policy uses StringLike to check if the resource's zone tag value appears in the user's concatenated zone list.
Example policy condition:
"Condition": {
"StringLike": {
"aws:PrincipalTag/entigo-zones": "*|${rds:ResourceTag/entigo-zone}|*"
}
}
Challenges:
- Tag value limit is 256 characters — with ~12 chars per zone (name + delimiters), fits ~20 zones per user
- Requires custom logic to compute the concatenated value — Entra's native SAML claim rules cannot aggregate multiple group memberships into a single delimited string
- Implementation requires either a custom SAML claims provider (Entra API connector) or an Azure Function that maintains a computed user attribute synced with group membership
- Introduces a custom component in the authentication path that must be built, monitored, and kept reliable
Status: Partially viable for users with fewer than ~20 zones. Not viable for users with more zones without tiered wildcards (e.g., |prod-*| for broad access). Requires custom middleware in all cases.
Option 4: PermissionSet Per Zone with Automation
Approach: Each zone maps to a dedicated PermissionSet with zone-specific inline policy. Entra groups are synced via SCIM, and automation creates the PermissionSet and account assignments when a new zone group appears.
Flow:
- Department creates Entra group
entigo-zone-{name} - SCIM syncs group to IAM Identity Center
- Automation (Lambda/EventBridge or platform controller) detects new group and:
- Creates PermissionSet
zone-{name}from template - Creates account assignments: group → PermissionSet → target account(s)
- Provisions the PermissionSet
- Creates PermissionSet
Policy template (identical for all zones, only tag value differs):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["rds:RebootDBInstance", "rds:DescribeDBInstances"],
"Resource": "*",
"Condition": {
"StringEquals": {
"rds:ResourceTag/entigo:zone": "{zone-name}"
}
}
},
{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue", "secretsmanager:CreateSecret", "secretsmanager:PutSecretValue"],
"Resource": "*",
"Condition": {
"StringEquals": {
"secretsmanager:ResourceTag/entigo:zone": "{zone-name}"
}
}
}
]
}
Advantages:
- Uses native AWS mechanisms — no custom middleware in the auth path
- Clear audit trail — each role assumption is zone-specific in CloudTrail
- Works within all documented AWS limits (2,000 PermissionSets, 10,240 byte inline policy)
- Zone lifecycle can be fully automated
Challenges:
- 100–200 PermissionSets to manage (within quota but operationally significant)
- Requires automation for zone onboarding — Identity Center API calls (
CreatePermissionSet,PutInlinePolicyToPermissionSet,CreateAccountAssignment,ProvisionPermissionSet) - UX: users with access to many zones see many roles in the SSO portal — poor discoverability
- Users can only operate in one zone per session — switching zones requires assuming a different role
- Each new zone requires PermissionSet provisioning, which is currently not part of the zone lifecycle — departments who own zones would depend on this automation
CreateAccountAssignmentAPI is throttled at 10 concurrent async calls — provisioning many assignments takes time
Status: Viable. Most operationally mature option despite management overhead.
Option 5: Coarse IAM Scoping + Platform-Level Zone Enforcement
Approach: PermissionSets scoped to environment tiers (e.g., prod, staging, dev) — 3–5 PermissionSets total. Zone-level access enforced by the platform layer (Kyverno, kcp workspace RBAC, platform admission control).
Advantages:
- Minimal PermissionSet management
- Scales to any number of zones without IAM changes
Challenges:
- Does not work for imperative AWS operations (RDS restart, Secrets Manager) — the platform cannot mediate these
- Shifts trust from IAM to the platform — users with
prodPermissionSet can access all prod-tier resources at the AWS level - May not satisfy compliance requirements that expect IAM-level enforcement
Status: Not viable as standalone solution for the stated requirements (imperative operations must be zone-scoped at IAM level). Could complement other options as part of a layered approach.
Current Assessment
No AWS-native mechanism supports dynamic multi-zone ABAC from group membership without custom middleware or per-zone IAM configuration. The fundamental constraint is that AWS session tags are single-valued key-value pairs with no multi-value or set-membership semantics.
| Requirement | Option 3 (Concatenated) | Option 4 (PermissionSet/Zone) |
|---|---|---|
| Multi-zone access | ~20 zones/user (256-char limit) | Unlimited (separate sessions) |
| Zone onboarding | Entra claim config only | Automation: PermissionSet + assignments |
| Custom components | SAML claims provider or sync function | Zone provisioning Lambda/controller |
| Auth path dependency | Custom component in login flow | None (native AWS) |
| User experience | Single role, all zones in one session | Multiple roles, one zone per session |
| Auditability | Zone access visible only in tag value | Each zone assumption logged separately |
| Compliance posture | Custom auth component requires review | Standard AWS IAM patterns |
Open Questions
- What is the realistic maximum number of zones a single user would need? If bounded to ~15–20, Option 3 becomes viable but still requires custom middleware.
- Is per-session zone selection acceptable? Option 4 requires users to switch roles to switch zones — does this conflict with operational workflows?
- Can zone provisioning automation be integrated into the existing platform zone lifecycle? If zones are already defined as platform resources (kcp workspaces, CRDs), the PermissionSet creation could be a controller side-effect.
- What is the compliance requirement for zone boundary enforcement? Must it be at the IAM level, or would platform-level enforcement (Option 5) satisfy auditors for some operations?
- Should a hybrid approach be considered? For example, Option 4 for write/mutate operations (RDS restart, Secrets Manager write) and Option 5 for read-only operations (describe, list).
References
- Permission Boundaries ADR — workspace and zone ABAC isolation that this ADR builds on
- Cloud Resource Tagging ADR — defines
entigo:zonetag semantics - AWS: Pass session tags in STS — single-value constraint documented here
- AWS: Quotas in IAM Identity Center — 2,000 PermissionSet limit, API throttling
- AWS: SAML assertions for authentication response — PrincipalTag and AccessControl attribute format
- AWS: IAM Identity Center SCIM limitations — no multi-valued attributes, no custom schema extensions
- AWS Blog: Custom attributes for ABAC with Entra ID and Identity Center — single-attribute ABAC pattern
- AWS re:Post: ABAC with IAM Identity Center and Entra — community discussion confirming multi-value limitations