- Newest
- Most votes
- Most comments
As far as I remember, YES this is a known, "hard incompatibility" between Entra ID's native group-claims formatting and AWS IAM's expected PrincipalTag format.
My understanding is:
AWS IAM requires multi-value session tags (like PrincipalTag:groups) to be passed as a single string separated by a delimiter (like a colon). However, Entra ID natively emits an array of groups as multiple, separate <AttributeValue> XML nodes. AWS IAM rejects this because it does not support multiple <AttributeValue> elements for the same session tag.
Unfortunately, Entra ID's built-in SAML claim transformations do not support iterating over an array of group memberships to flatten or join them into a single delimited string. Unlike Okta (which allows String.join expressions for groups), Entra ID has no native way to produce the expected GroupA:GroupB format dynamically directly from group claims.
AWS explicitly acknowledges this limitation in their official architecture blog post for this exact scenario: Dynamic multi-group entitlements in WorkSpaces applications with Entra ID.
The post states clearly: "Entra ID does not natively pass group names as a colon-separated string."
To solve this, you have to use the workaround you already suspected. The AWS-recommended approach (detailed in the blog post linked above) is to use a scheduled script (e.g., an AWS Lambda function calling the Microsoft Graph API) to sync a user's group memberships into a single, colon-separated string within a custom extension attribute in Entra ID. You then map that specific custom attribute to the PrincipalTag:groups claim in your Enterprise Application's SAML configuration instead of using the native group claims feature.
So your assumption is correct: it cannot be solved purely on the Entra ID side without a custom attribute and a sync script.
Thanks, this confirms what I found, tested Join() against the groups claim directly, and also ruled out dynamic groups, custom claims providers, and app roles. Looks to be a platform gap.
I'll go with the Lambda with custom extension attribute approach from that post you provided.
Marking this as resolved, appreciate your help on this.
Relevant content
asked 7 months ago
- AWS OFFICIALUpdated 2 months ago
- AWS OFFICIALUpdated 5 months ago
