Files
better-auth/packages/sso/CHANGELOG.md
T

19 KiB

@better-auth/sso

1.7.0-beta.2

Patch Changes

1.7.0-beta.1

Minor Changes

  • #9117 b70f025 Thanks @gustavovalverde! - ### Breaking: SAML configuration changes

    callbackUrl removed from samlConfig. The ACS URL is now always derived from your baseURL and providerId. Remove callbackUrl from your SAML provider configuration. The post-login redirect destination is set per sign-in via callbackURL in signIn.sso():

    await authClient.signIn.sso({
      providerId: "my-provider",
      callbackURL: "/dashboard",
    });
    

    /sso/saml2/callback/:providerId endpoint removed. Update your IdP's ACS URL to /sso/saml2/sp/acs/:providerId. This endpoint handles both GET and POST requests.

    spMetadata is now optional. You no longer need to pass spMetadata: {} when registering a provider. SP metadata is auto-generated from your configuration.

    Removed unused fields from SAMLConfig: decryptionPvk, additionalParams, idpMetadata.entityURL, idpMetadata.redirectURL. These were stored but never read. Remove them from your configuration if present.

    Bug fixes

    • Fix SLO SessionIndex matching: LogoutRequests with a SessionIndex were silently failing to delete the correct session.
    • Audience validation now defaults to the SP entity ID when audience is not configured, per SAML Core section 2.5.1.
    • Restore AllowCreate in AuthnRequests, required by IdPs that use JIT provisioning.
    • SP metadata endpoint now reflects actual SP capabilities (encryption, signing, SLO).

Patch Changes

  • #9121 9603043 Thanks @gustavovalverde! - ### Security: upgrade samlify to 2.12.0

    Upgrades the SAML XML processing library from 2.10.2 to 2.12.0:

    • XPath injection protection: all XPath expressions now use value escaping instead of string interpolation
    • XXE prevention: the XML parser defaults to strict mode that rejects entity references
    • Dependency reduction: removes node-forge, pako, uuid, and camelcase in favor of Node built-ins

    PEM keys and certificates with leading whitespace are now normalized automatically before being passed to samlify. This prevents DECODER routines::unsupported errors when keys are copied from indented config files or environment variables.

    Requires Node 20+.

  • Updated dependencies [5142e9c, 484ce6a, f875897, c7d2253, 9a6d475, 513dabb, 6f2948e]:

    • better-auth@1.7.0-beta.1
    • @better-auth/core@1.7.0-beta.1

1.7.0-beta.0

Minor Changes

  • #8836 93d3871 Thanks @gustavovalverde! - Add private_key_jwt (RFC 7523) client authentication across the stack. Servers verify JWT client assertions signed with asymmetric keys; clients sign them for authorization code, refresh, and client credentials flows.

  • #9055 b790144 Thanks @gustavovalverde! - fix(sso)!: harden SAML response validation (InResponseTo, Audience, SessionIndex)

    Breaking Changes

    • allowIdpInitiated now defaults to false — IdP-initiated SSO (unsolicited SAML responses) is disabled by default. Set saml.allowIdpInitiated: true to restore the previous behavior. This aligns with the SAML2Int interoperability profile which recommends against IdP-initiated SSO due to its susceptibility to injection attacks.

    Bug Fixes

    • InResponseTo validation was completely non-functional — The code read extract.inResponseTo (always undefined) instead of samlify's actual path extract.response.inResponseTo. SP-initiated InResponseTo validation now works as intended in both ACS handlers.
    • Audience Restriction was never validated — SAML assertions issued for a different service provider were accepted without checking the <AudienceRestriction> element. Audience is now validated against the configured samlConfig.audience value per SAML 2.0 Core §2.5.1.
    • SessionIndex stored as object instead of string — samlify returns sessionIndex from login responses as { authnInstant, sessionNotOnOrAfter, sessionIndex }, but the code stored the whole object. SLO session-index comparisons always failed silently. The correct inner sessionIndex string is now extracted.

    Improvements

    • Extracted shared validateInResponseTo() and validateAudience() into packages/sso/src/saml/response-validation.ts, eliminating ~160 lines of duplicated validation logic between the two ACS handlers.
    • Fixed SAMLAssertionExtract type to match samlify's actual extractor output shape.

1.6.7

Patch Changes

1.6.6

Patch Changes

1.6.5

Patch Changes

  • Updated dependencies [938dd80, 0538627]:
    • better-auth@1.6.5
    • @better-auth/core@1.6.5

1.6.4

Patch Changes

1.6.3

Patch Changes

  • #9097 52c4751 Thanks @gustavovalverde! - fix(sso): unify SAML response processing and fix provider/config bugs

    Bug fixes:

    • Fix SP metadata endpoint using internal row ID instead of providerId in ACS URL
    • Fix acsEndpoint skipping DB provider lookup when defaultSSO is configured
    • Fix acsEndpoint missing encryption fields (isAssertionEncrypted, encPrivateKey), which caused silent decryption failures
    • Fix defaultSSO config parsing in callback path (safeJsonParse on already-parsed objects)
    • Fix createSP missing callbackUrl fallback to auto-generated ACS URL
    • Complete createSP/createIdP helpers with all encryption and signing fields

    Behavioral changes:

    • ACS error redirect query parameters now use uppercase error codes (e.g. error=SAML_MULTIPLE_ASSERTIONS instead of error=multiple_assertions). If your application parses these error codes from the redirect URL, update the expected values.
    • SAML provider registration now rejects configs with no usable IdP entry point (no valid entryPoint URL, no idpMetadata.metadata, and no idpMetadata.singleSignOnService). Previously these would register successfully but fail at sign-in.
    • entryPoint validation tightened from startsWith("http") to new URL() parsing, rejecting malformed URLs like http:evil or http//missing-colon.

    Refactoring (no API changes):

    • Extract shared processSAMLResponse pipeline to eliminate ~500 lines of duplicated logic between callbackSSOSAML and acsEndpoint
    • Move validateSAMLTimestamp to saml/timestamp.ts (re-exported from original location for compatibility)
  • Updated dependencies [6ce30cf, f6428d0, c5066fe, 5f84335, 93d3871, 544f1c6]:

    • better-auth@1.7.0-beta.0
    • @better-auth/core@1.7.0-beta.0
  • Updated dependencies [5142e9c, 484ce6a, f875897, 6ce30cf, f6428d0, 9a6d475, 513dabb, c5066fe, 5f84335]:

    • better-auth@1.6.3
    • @better-auth/core@1.6.3

1.6.2

Patch Changes

  • #8968 5e5d3f6 Thanks @cyphercodes! - fix(sso): strip whitespace from SAMLResponse before base64 decoding

    Some SAML IDPs send SAMLResponse with line-wrapped base64 (per RFC 2045), which caused decoding failures. Whitespace is now stripped at the request boundary before any processing.

  • Updated dependencies [9deb793, 2cbcb9b, b20fa42, 608d8c3, 8409843, e78a7b1]:

    • better-auth@1.6.2
    • @better-auth/core@1.6.2

1.6.1

Patch Changes

1.6.0

Minor Changes

Patch Changes

1.6.0-beta.0

Minor Changes

Patch Changes