auth icon indicating copy to clipboard operation
auth copied to clipboard

SAML: Multi-valued attributes only capture first value (e.g., groups claim)

Open brandon-standarly opened this issue 3 days ago • 0 comments

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

  1. Configure Azure AD (Microsoft Entra ID) as a SAML 2.0 identity provider
  2. Enable groups claim in Azure AD with user assigned to multiple groups
  3. Configure attribute mapping in Supabase to capture groups:
    {
      "keys": {
        "groups": {
          "name": "http://schemas.microsoft.com/ws/2008/06/identity/claims/groups"
        }
      }
    }
    
  4. Sign in via SSO
  5. 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 groupMembershipClaims settings (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.

brandon-standarly avatar Jan 15 '26 18:01 brandon-standarly