new·Earn with mozg — 20% of every monthSend somebody here and take a fifth of every plan payment they make, for as long as they keep paying — not a bounty on the first invoice. Your handle is the link, the window is thirty days, and the commission lands on your balance the second they pay. Free to join: if you have signed in, you already have the link. mozg.sh/earnall news →
mozg.beta
Sign in

Better Auth · Plugins · all subjects

sso/saml

21 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

SAML provider registration

Register a SAML provider using the `registerSSOProvider` endpoint with SAML configuration. The provider acts as a Service Provider (SP) integrating with an Identity Provider (IdP). Required fields: providerId, issuer (identifies your service provider), domain (comma-separated email domains), and samlConfig containing entryPoint, audience, signatureAlgorithm, digestAlgorithm, identifierFormat, idpMetadata, and spMetadata. Better Auth identifies a SAML account by provider ID and the signed NameID.

SAML account identification

Better Auth identifies a SAML account by the provider ID and the signed `NameID`. The `issuer` field identifies your service provider, while the IdP entity ID comes from `idpMetadata.metadata` or explicit `idpMetadata.entityID`. Attribute mappings can populate profile fields but cannot replace the signed NameID account subject.

Get SAML Service Provider metadata

Retrieve Service Provider metadata XML using `auth.api.spMetadata()` with query parameters: providerId (the SSO provider ID) and format ('xml' or 'json'). The response contains the SP metadata that needs to be configured in your Identity Provider.

SAML default provider configuration

Define a default SAML provider in the SSO plugin configuration using the `defaultSSO` option. The defaultSSO provider is used when no matching provider is found in the database. It allows testing SAML authentication without setting up providers in the database. The default provider supports all the same configuration options as regular SAML providers.

SAML Service Provider metadata configuration

When registering a SAML provider, provide Service Provider (SP) metadata configuration in spMetadata: metadata (XML metadata for SP), binding (typically 'post' or 'redirect'), privateKey (for signing AuthnRequests), privateKeyPass (password for private key), isAssertionEncrypted (boolean), encPrivateKey (private key for decryption if encryption enabled), encPrivateKeyPass (password for encryption private key).

SAML signed AuthnRequests configuration

Some enterprise IdPs (Okta, Azure AD, ADFS) require signed AuthnRequests. Enable this by setting `authnRequestsSigned: true` in samlConfig and providing the private key in spMetadata. The SP metadata endpoint automatically includes `AuthnRequestsSigned='true'` when enabled.

SAML Identity Provider metadata configuration

Provide Identity Provider (IdP) configuration in idpMetadata: metadata (XML metadata from IdP), privateKey (optional, for IdP communication), privateKeyPass (password for IdP private key if encrypted), isAssertionEncrypted (boolean), encPrivateKey (private key for IdP assertion decryption), encPrivateKeyPass (password for IdP decryption key).

SAML signing certificate rotation

When an IdP rotates its signing certificate, list both old and new PEM certificates under `idpMetadata.cert` as an array. Better Auth accepts SAML responses signed by either certificate, allowing users to continue signing in during rotation. Both `samlConfig.cert` and `samlConfig.idpMetadata.cert` accept either a single PEM string or an array; when both are set, `idpMetadata.cert` takes precedence.

SAML certificate source configuration

If the IdP publishes a metadata XML document, pass it as `idpMetadata.metadata` and leave `cert` unset; certificates come from the document and rotation happens when the IdP republishes it. If neither `cert` nor `idpMetadata.metadata` are supplied, registration fails with `CERT_SOURCE_MISSING`.

SAML attribute mapping configuration

Configure how SAML attributes map to user fields in the mapping option: email (default: 'email' or 'nameID'), name (default: 'displayName'), firstName (default: 'givenName'), lastName (default: 'surname'), extraFields (object for additional custom fields like department, role, phone).

SAML InResponseTo validation configuration

Enable InResponseTo validation for SP-initiated SAML flows using `saml.enableInResponseToValidation: true` (default). This prevents unsolicited responses, replay attacks, and cross-provider injection. Configuration options: enableInResponseToValidation (boolean, default true), allowIdpInitiated (boolean, default true, set false to reject IdP-initiated flows for stricter security), requestTTL (number in milliseconds, default 300000 for 5 minutes, time-to-live for AuthnRequest records).

SAML InResponseTo validation errors

When InResponseTo validation fails, users are redirected with error query parameters: `error=invalid_saml_response&error_description=Unknown+or+expired+request+ID` (request ID not found or expired), `error=invalid_saml_response&error_description=Provider+mismatch` (response meant for different provider), `error=unsolicited_response&error_description=IdP-initiated+SSO+not+allowed` (IdP-initiated SSO disabled).

SAML assertion replay protection

SAML assertion replay protection is always enabled. Each SAML Assertion ID is tracked and rejected if reused. When a SAML response is received, the Assertion ID is extracted from the XML, checked against prior uses, stored in the database until its NotOnOrAfter expiration, and rejected if it's a duplicate. Replay protection uses the database verification table and works correctly in multi-instance deployments without additional configuration.

SAML replay attack error

When a SAML assertion replay attack is detected, users are redirected with error: `error=replay_detected&error_description=SAML+assertion+has+already+been+used`.

SAML timestamp validation configuration

Configure SAML assertion timestamp validation using: clockSkew (number in milliseconds, default 300000 for 5 minutes, tolerance for time differences between IdP and SP), requireTimestamps (boolean, default false, when true reject assertions without NotBefore/NotOnOrAfter, when false accept but log warning). For enterprise/production with SAML2Int compliance, set clockSkew to 60000 (1 minute) and requireTimestamps to true.

SAML timestamp validation behavior

For each SAML assertion: NotBefore validation rejects if current time is before `NotBefore - clockSkew`; NotOnOrAfter validation rejects if current time is after `NotOnOrAfter + clockSkew`. SAML 2.0 Core spec allows omitting timestamps, but SAML2Int (widely adopted profile) requires them. Better Auth defaults to accepting assertions without timestamps but logs a warning; enable strict mode with requireTimestamps: true.

SAML timestamp validation error messages

SAML timestamp validation produces these error messages: 'SAML assertion is not yet valid' (current time before NotBefore minus clock skew), 'SAML assertion has expired' (current time after NotOnOrAfter plus clock skew), 'SAML assertion missing required timestamp conditions' (no timestamps and requireTimestamps enabled).

SAML algorithm validation configuration

Configure SAML cryptographic algorithm validation using `algorithms.onDeprecated` option with values: 'warn' (default, log warning and allow), 'reject' (throw error and block), 'allow' (silent, no validation). Deprecated algorithms trigger warnings/rejection: RSA-SHA1, SHA1, RSA 1.5, 3DES.

SAML supported cryptographic algorithms

Signature algorithms: RSA-SHA256, RSA-SHA384, RSA-SHA512, ECDSA-SHA256, ECDSA-SHA384, ECDSA-SHA512. Digest algorithms: SHA256, SHA384, SHA512. Deprecated (trigger warning/rejection): RSA-SHA1, SHA1, RSA 1.5, 3DES.

SAML size limits configuration

SAML payload size limits: maxResponseSize (default 256KB, maximum SAML response size in bytes), maxMetadataSize (default 100KB, maximum IdP or SP metadata size). Customize with: `saml: { maxResponseSize: 512 * 1024, maxMetadataSize: 100 * 1024 }`.

deriveSAMLIdentityProviderEntityID utility function

Use `deriveSAMLIdentityProviderEntityID` from '@better-auth/sso' to derive the SAML IdP entity ID from a SAML configuration. This utility uses the same metadata parser used by SAML authentication and allows applications to pin the IdP authority when storing a SAML connection.

Give your agent this brain