This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 3, 2026. Spotted a mistake? Tell us.
NameID is the SAML assertion's subject identifier: the value that tells the service provider who just logged in. The format matters as much as the value, because it decides whether the SP can link this login to an existing account, and whether that link survives a name change, an email change or a new session.
Most SAML problems that look like "the user logs in but sees the wrong account" or "every login creates a new account" come down to a NameID mismatch, not to signing or certificates.
Where NameID appears
In a SAML 2.0 response, the identifier sits inside the assertion's <Subject>:
<NameID>holds the value the SP will use as the account key.- The
Formatattribute says how to interpret that value. NameQualifierandSPNameQualifiercan scope the identifier to an IdP and an SP.<SubjectConfirmation>carries the method (usually bearer) and the conditions under which the assertion is valid.
The same NameID value also appears in SAML single logout requests, paired with the SessionIndex. If the value changes between login and logout, the IdP cannot find the session to terminate.
The formats that matter
SAML defines many NameID formats; four appear in almost every integration:
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress— the value is an email address. Easy for people to read and easy for SPs to match against an existing user table. It breaks when the address changes or when one person has several addresses.urn:oasis:names:tc:SAML:2.0:nameid-format:persistent— an opaque, stable identifier. The IdP should generate it per IdP/SP pair and keep it stable for the life of the account. It should not contain the username or email, so it does not leak or change when those do.urn:oasis:names:tc:SAML:2.0:nameid-format:transient— a one-session identifier. It is different at every login and must not be used to correlate a user across sessions.urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified— the IdP decides; the SP must not assume any particular meaning. It is the most common default, and the most common source of surprises.
Windows domain qualified name, X.509 subject name and Kerberos principal formats exist for legacy enterprise integrations. They are rare in new deployments.
Format and value are different decisions
A frequent mistake is to treat "email" as a format choice only. The format says what kind of string it is; the value is the actual identifier. Two options produce very different behavior:
- Format
emailAddress, valuealice@example.com: readable, but the account link breaks if Alice's address changes or if the address is reassigned to someone else. - Format
persistent, valuef3a9c1e7...: opaque, stable, safe for account linking, but a human cannot map it back to a person without the IdP's help.
For anything that stores data per user, persistent is the safer default. Use email only when the SP itself is the identity source or when the integration is explicitly one-time and low risk.
What the service provider asks for
An SP can send a <NameIDPolicy> in the authentication request:
Formatstates the desired format.AllowCreate="true"says the IdP may create an identifier on the fly if none exists.
The IdP is allowed to ignore the request or to return an error if it cannot satisfy the policy. That is why the same IdP can work with one SP and fail with another. When an SP reports "InvalidNameIDPolicy" or a generic "SAML response invalid", compare the requested format with the format actually in the assertion before touching certificates.
Choosing a format by use case
- SaaS applications with local user tables: persistent, with a stable fallback attribute such as email or employee ID for matching. Keep the persistent value immutable even if the person's name changes.
- Internal tools where email is the account key: emailAddress is acceptable, but plan for address changes and for shared mailboxes.
- Kiosk or shared-workstation logins: transient, so sessions cannot be correlated and no durable account is created.
- Legacy SPs that only read an unspecified NameID: send the value they expect (usually the login name) and document that assumption. Do not silently change it later.
The stable identifier should go in NameID. Human-readable data belongs in attributes: mail, displayName, givenName, sn, group or role attributes. Mixing the two is what forces painful migrations later.
Email-specific pitfalls
Using email as the NameID looks harmless until one of these happens:
- Address change. A married name, a domain migration or a rebrand changes the value, and the SP sees a new user.
- Reassignment. A departed employee's address is reused, and the new person inherits the old account if the SP matches on email alone.
- Aliases. The IdP sends
alice@corp.exampleon one day anda.smith@corp.exampleon another; the SP creates two accounts. - Case and whitespace. Some SPs normalize email, some do not. A trailing space in an attribute mapping is enough to break the match.
- UPN versus email. In Microsoft Entra environments the UPN, the mail attribute and the NameID are three different values. Check the actual assertion instead of assuming they match.
Troubleshooting table
| Symptom | Likely cause | Check |
|---|---|---|
| SP shows the wrong user | NameID value comes from a mutable or non-unique attribute | Compare the assertion's NameID with the SP's account key |
| A new account on every login | transient format, or a value that changes per session | Format and the attribute behind the value |
InvalidNameIDPolicy |
SP requested a format the IdP does not issue | Requested format vs actual assertion format |
| Login works, logout fails | NameID value changed since login, or SessionIndex is missing | SLO request's NameID and SessionIndex |
| Some users fail, others work | duplicates or missing source attribute (email, employee ID) | User records in the IdP |
NameID in Casdoor
Casdoor acts as a SAML 2.0 identity provider. Its NameID behavior is deliberately simple:
- By default the NameID value is the Casdoor username, with format
unspecified. - Turning on Use Email as SAML NameID on the application switches the value to the user's email and the format to
emailAddress. - SAML NameID template builds the value from user fields. Supported placeholders include
$user.name,$user.email,$user.emailLocalPart,$user.emailDomain,$user.id,$user.phoneand$user.owner. A template such as$user.idgives you a value that does not change when the username or email does. - Casdoor's IdP metadata advertises emailAddress, persistent and transient NameID formats, so SPs that read the metadata know what to request.
Because Casdoor's own value is derived from the user record, pick a template that will not change for the life of the account. If you map to email, expect a new account in the SP whenever the email changes. Casdoor is open source, and Casdoor Cloud starts at $6.67/month billed yearly for a dedicated instance.
FAQ
Is persistent always better than email? For account linking, yes. Persistent values do not change when the person's name or email changes, and they do not expose the address to every SP. Email is fine only when the SP's user table is keyed on email and you accept the maintenance that comes with it.
Can I change the NameID format later without breaking users? Only if the SP supports matching on another attribute. Changing the NameID value usually looks like a new user to the SP. Plan the change with the SP owner, or keep the old value as a fallback attribute during the transition.
What should go in NameID versus attributes? NameID: a stable, unique, non-reassignable identifier. Attributes: everything a human reads or an application displays, such as email, display name, department and groups.
Does the NameID need to be encrypted? Encryption is a separate decision from the NameID format. If the assertion is encrypted, the SP decrypts it before reading the NameID. The format and value rules do not change.
Why does single logout fail after renaming a user? Because the logout request carries the NameID that was used at login. If the value changed, the IdP cannot match the session. Use an immutable NameID, or keep the old value as an alias.
Sources
- OASIS SAML 2.0 Core
- OASIS SAML 2.0 Profiles
- Microsoft Entra SAML token claims
- Okta NameID format
- Casdoor SAML documentation
Product names are trademarks of their respective owners.