Skip to content

Clarify SAML NameID stability, scope, and non-NameID resolution#105

Open
mcguinness wants to merge 2 commits into
mainfrom
saml-nameid-stability
Open

Clarify SAML NameID stability, scope, and non-NameID resolution#105
mcguinness wants to merge 2 commits into
mainfrom
saml-nameid-stability

Conversation

@mcguinness

Copy link
Copy Markdown
Collaborator

Closes #104.

Summary

Addresses @sdesen's feedback in #104 that the SAML NameID Subject Identifier section did not make its assumptions about immutability and uniqueness of the NameID explicit, and did not acknowledge that some real-world IdP deployments (for example Microsoft Entra ID) resolve users by a SAML attribute outside the <Subject> element rather than by the <NameID> itself.

What changed

  1. Format intro tightening. The Format section's "intended for deployments" sentence now refers specifically to "a SAML <NameID> from its SSO trust relationship with the IdP Authorization Server" instead of the vague "SAML SSO subject identifiers."

  2. New requirements block in Subject Identifier Processing, inserted between the IdP construction rule and the Resource Authorization Server consumption rules. The block adds three normative bullets covering the assumptions the format depends on: stability of the NameID value (banning transient NameID Formats, allowing emailAddress and persistent with caveats inherited from the underlying Format), uniqueness scope (per SAML issuer plus Service Provider, with explicit handling of pairwise vs public NameIDs and the OAuth client_id to SAML SP entity ID mapping the IdP must maintain), and non-NameID subject resolution (citing Microsoft Entra ID's objectidentifier attribute as a real-world example, directing IdPs to convey the relevant attribute as an additional claim in the ID-JAG when SSO does not resolve by the <NameID>).

How this responds to #104

Issue concern Resolution
Immutability of the NameID is critical but the spec did not require it Stability requirement bans transient NameIDs and anchors stability to the Resource Authorization Server's SSO subject-resolution behavior
A SAML implementation might not break if the NameID is modified Stability requirement notes the SAML NameID Subject Identifier inherits the underlying Format's mutability properties; the same emailAddress caveats apply to ID-JAG as to SAML SSO
NameID is not globally unique to an IdP, only to the relying party Identifier scope requirement states this explicitly, requires the IdP to use the per-SP value for pairwise NameIDs, and requires the OAuth client_id to SAML SP entity ID mapping
Microsoft docs show SSO can use a different claim than NameID Non-NameID subject resolution requirement acknowledges this case, cites Entra ID's objectidentifier, and directs IdPs to use an additional ID-JAG claim instead of forcing the value into the SAML NameID Subject Identifier Format

Test plan

  • Render with kramdown-rfc / xml2rfc and confirm the new bullets render correctly
  • Confirm cross-references ({{OASIS.saml-core-2.0-os}}, {{saml-nameid-format}}, etc.) all resolve
  • Confirm no anchor IDs changed

Addresses review feedback that the SAML NameID Subject Identifier
section did not make its assumptions about uniqueness and
immutability of the NameID explicit, and did not acknowledge that
some real-world IdP deployments (for example Microsoft Entra ID)
resolve users by a SAML attribute outside the `<Subject>` element
rather than by the SAML `<NameID>` itself.

Tightens the Format intro from the vague "SAML SSO subject
identifiers" to "a SAML `<NameID>` from its SSO trust relationship
with the IdP Authorization Server."

Adds a three-bullet requirements block to the Processing section,
inserted between the IdP construction rule and the Resource
Authorization Server consumption rules:

- Stability: bans transient NameID Formats explicitly. Allows
  `emailAddress`, `persistent`, and other Formats, with a note that
  the SAML NameID Subject Identifier inherits the lifecycle and
  subject-resolution properties of the underlying Format (so for
  example email reassignment and email change risks propagate the
  same way they do for SAML SSO with `emailAddress`).

- Identifier scope: covers SAML NameID uniqueness (scoped to issuer
  plus Service Provider via `sp_name_qualifier`), the distinction
  between public and pairwise NameIDs, and the mapping the IdP
  Authorization Server MUST maintain between OAuth `client_id` for
  the Resource Authorization Server and the SAML Service Provider
  entity ID used for SSO. For pairwise NameIDs the IdP MUST use the
  value scoped to the corresponding SAML SP.

- Non-NameID subject resolution: acknowledges deployments where SSO
  resolution is by a SAML attribute outside the `<Subject>` element
  (citing Entra ID's `objectidentifier` as a real-world example).
  Directs IdPs to convey the relevant attribute as an additional
  claim in the ID-JAG rather than as a SAML NameID Subject
  Identifier. Notes that the choice between pairwise and public,
  and the choice between immutable and mutable identifiers, is
  deployment-specific, with immutable preferred.
Replaces semicolon joins with sentence breaks in the Stability and
Non-NameID subject resolution bullets added in the previous commit
on this branch.

* **Identifier scope.** A SAML `<NameID>` is unique within the context of the SAML issuer (`issuer`) and the Service Provider (as scoped by `sp_name_qualifier` when present), not globally unique within the issuer. NameIDs may be public (a single value for an End-User across all Service Providers) or pairwise (different values per Service Provider). When the IdP Authorization Server issues pairwise NameIDs, the `nameid` value placed in the SAML NameID Subject Identifier MUST be the value the IdP would issue to the SAML Service Provider corresponding to the target Resource Authorization Server. The IdP Authorization Server MUST maintain the mapping between the OAuth `client_id` of the Resource Authorization Server and the SAML Service Provider entity ID used for SSO with the corresponding application, so pairwise NameIDs resolve under the correct Service Provider scope. The IdP Authorization Server MUST NOT assume the `nameid` value identifies the same End-User across different Service Providers without the qualifying scope members.

* **Non-NameID subject resolution.** Some SAML deployments resolve users by a SAML attribute outside the `<Subject>` element (for example, an attribute in the `<AttributeStatement>` such as the `http://schemas.microsoft.com/identity/claims/objectidentifier` attribute used by Microsoft Entra ID). In those deployments, the SAML NameID Subject Identifier is not the correct vehicle. The IdP Authorization Server SHOULD convey the relevant attribute value as an additional claim in the ID-JAG so the Resource Authorization Server can perform subject resolution. The choice of attribute and identifier type is deployment-specific: a SAML Service Provider and Resource Authorization Server may use either pairwise (different values per Service Provider) or public (a single value across Service Providers) identifiers, depending on local needs. Immutable identifiers are preferred. Mutable identifiers (such as `emailAddress`) MAY be used for subject resolution, subject to the considerations described in the Stability requirement above. When the attribute is pairwise per Service Provider, the IdP Authorization Server MUST use the value scoped to the SAML Service Provider corresponding to the target Resource Authorization Server.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love the suggestion of including arbitrary new claims in the ID-JAG that mirror the custom SAML attributes. If anything, there should be a single ID-JAG claim that all the custom claims live under to mirror the namespace of SAML attributes, otherwise there may be conflicts with other ID-JAG claims.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is overlap here with #100

The IdP AS may already need to map SAML Attributes to OIDC standard JWT and ID Token claims when a client exchanges a SAML Assertion for an ID Token and/or Refresh Token (which can be refreshed for an ID Token).

Additionally an IdP AS IdP could issue any number of SAML Attribute Statements that may be used for subject resolution (e.g customerId, accountId, partnerId, externalId, etc). SAML Attribute Statements have namespaces and can also be complex types that don't have 1:1 mappings to JSON values.

In my SAML to OIDC migration profile I had to define how to map SAML Attribute Statements to standard ID Token/UserInfo claims as well as private claims

https://mcguinness.github.io/connect-saml-profiles/draft-connect-saml-migration-profile.html#section-12.2

I think we may need to pull in some of this language here.

I don't think it makes sense to have the ID-JAG reflect full SAML Attribute Statements like I did for introspection

https://mcguinness.github.io/connect-saml-profiles/draft-connect-saml-migration-profile.html#name-delegate-saml-validation-wi

Its the IdP's job to transform/map the claims to an ID-JAG when needed and the claims will already be specific to the IdP. Outside of a few federations like InCommon there isn't standardized attributes for SAML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Note to preserve SAML NameId immutability

2 participants