SAML: Multi-valued attributes only capture first value (e.g., groups claim)
Bug Report
Describe the bug
When using SAML 2.0 SSO with an identity provider that sends multi-valued attributes (e.g., Azure AD groups claim), Supabase Auth/gotrue only captures the first <AttributeValue> element and stores it as a string, instead of collecting all values into an array.
To Reproduce
- Configure Azure AD (Microsoft Entra ID) as a SAML 2.0 identity provider
- Enable groups claim in Azure AD with user assigned to multiple groups
- Configure attribute mapping in Supabase to capture groups:
{ "keys": { "groups": { "name": "http://schemas.microsoft.com/ws/2008/06/identity/claims/groups" } } } - Sign in via SSO
- Check
auth.users.raw_user_meta_data.custom_claims.groups
Expected behavior
When Azure AD sends:
<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groups">
<AttributeValue>0b430838-9034-454d-ab07-43f8e1b9ff1d</AttributeValue>
<AttributeValue>6e7a4320-6f27-417f-b51d-b9720f537f3d</AttributeValue>
</Attribute>
Supabase should store:
{
"custom_claims": {
"groups": ["0b430838-9034-454d-ab07-43f8e1b9ff1d", "6e7a4320-6f27-417f-b51d-b9720f537f3d"]
}
}
Actual behavior
Supabase stores only the first value as a string:
{
"custom_claims": {
"groups": "0b430838-9034-454d-ab07-43f8e1b9ff1d"
}
}
Evidence
Raw SAML assertion from Azure AD (captured via SAML-tracer):
<AttributeStatement>
<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groups">
<AttributeValue>0b430838-9034-454d-ab07-43f8e1b9ff1d</AttributeValue>
<AttributeValue>6e7a4320-6f27-417f-b51d-b9720f537f3d</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role">
<AttributeValue>ASG-Wiki-Admin</AttributeValue>
<AttributeValue>ASG-Wiki-Owner</AttributeValue>
</Attribute>
</AttributeStatement>
Database query result:
SELECT raw_user_meta_data->'custom_claims'->'groups' as groups_claim,
jsonb_typeof(raw_user_meta_data->'custom_claims'->'groups') as groups_type
FROM auth.users WHERE email = '[email protected]';
Returns:
groups_claim: "0b430838-9034-454d-ab07-43f8e1b9ff1d"
groups_type: "string"
Configurations tried (all failed)
- Standard groups claim (
http://schemas.microsoft.com/ws/2008/06/identity/claims/groups) - "Emit groups as role claims" (
http://schemas.microsoft.com/ws/2008/06/identity/claims/role) - Various Azure AD
groupMembershipClaimssettings (All,SecurityGroup,ApplicationGroup) - "Expose claim in JWT tokens in addition to SAML tokens" option
Environment
- Supabase Cloud (hosted)
- Identity Provider: Microsoft Entra ID (Azure AD)
- Protocol: SAML 2.0
Impact
Organizations cannot sync multiple IdP group memberships via SSO, breaking role-based access control workflows where users belong to multiple groups. This is a common enterprise requirement.
Suggested Fix
When parsing SAML <Attribute> elements, if there are multiple <AttributeValue> children, collect them into an array instead of taking only the first value.