Skip to content

Version Packages - #165

Merged
Bccorb merged 1 commit into
mainfrom
changeset-release/main
Sep 13, 2026
Merged

Bccorb merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@seamless-auth/core@0.16.0

Minor Changes

  • 36d530b: Accept the auth API's access token as a bearer credential in requireAuth and getSeamlessUser.

    Both guards read req.cookies and nothing else, so a native client, which has no cookie jar
    and holds the auth API's own tokens, was rejected on every request to an adopter's routes.
    requireAuth now takes an optional authServerUrl + audience pair; with both configured it
    also accepts Authorization: Bearer <access token>, verified against the auth API's JWKS
    (issuer, audience, expiry) and required to carry typ: "access", so a sign-in flow's
    ephemeral token is refused even though the same key signs it. The cookie wins when both are
    present, and leaving the pair out keeps the guard cookie-only, which is what every earlier
    version did. Half of the pair is a setup error.

    getSeamlessUser resolves a bearer session too. The router options already carry
    authServerUrl and audience, so no new option is needed there: a request with no access
    cookie but a valid bearer token is verified the same way and forwarded to GET /users/me as
    the caller's identity, while a request with neither, or a token that fails verification,
    returns null without an upstream call.

    On the bearer path req.user.email and req.user.phone are unset, because the access token
    does not carry them; getSeamlessUser hydrates the profile.

    Core exports verifyAccessToken, extractBearerToken, authenticateBearer, and
    authenticateRequest. getSeamlessUser in core takes an optional bearer: { authorization, audience }. The JWKS memo that verifySignedAuthResponse used moves to a shared module so both
    verifiers share one instance per auth server. Fastify gains direct tests for its guards, which
    until now were covered only through the plugin parity suite.

    Tracks feat(guards): accept bearer tokens in requireAuth and getSeamlessUser #147.

  • 0222376: Serve a bearer transport on the auth routes for native clients, and add POST /refresh.

    Every proxied route assumed cookies: identity came from the cookie payload, session responses
    were stripped of their tokens and minted into cookies, and silent refresh ran on the refresh
    cookie. A native app has no cookie jar, so it could not sign in through the adapter at all, and
    going around it to the auth API directly would bypass message delivery, client IP forwarding,
    and the service token, and need the auth API exposed.

    A request that carries x-seamless-auth-transport: bearer now gets a bearer contract on the
    same routes. The client presents the token a route needs in Authorization: Bearer (the
    ephemeral token /login or /registration/register returned on pre-auth routes, the access
    token on access routes) and the adapter forwards it to the auth API as-is. Session-issuing
    responses come back whole, token and refreshToken included, with no Set-Cookie; the auth
    API's signature on the access token is still verified before the body goes out. ensureCookies
    is skipped. A route that needs an identity and gets no bearer token answers 401 with the same
    error it gives a missing cookie. The header rather than the presence of Authorization selects
    the transport, because the first request of a flow carries no token in either. Requests without
    the header are served exactly as before.

    POST /refresh is new in both adapters. In bearer transport it takes Authorization: Bearer <refreshToken> and returns the rotated pair, passing the auth API's failure body through so a
    client can tell refresh_token_reused from a transient error. Concurrent rotations of the same
    token are collapsed into one upstream call, since the auth API treats a replayed refresh token as
    theft. In cookie transport it rotates the refresh cookie into fresh session cookies, for a client
    that wants an explicit refresh.

    Core: AuthTransport, resolveAuthTransport, AUTH_TRANSPORT_HEADER, sessionResult (what
    every session-issuing handler now returns through), a transport option on loginHandler,
    registerHandler, finishLoginHandler, the OTP verify handlers,
    pollMagicLinkConfirmationHandler, switchOrganizationHandler and finishOAuthLoginHandler,
    transport and authorization on checkProxyIdentity, transport on applyResult,
    refreshBearerSession, and refreshHandler. The parity suite drives a full bearer sign-in
    through both adapters.

    Closes feat(transport): bearer transport mode for the auth proxy #163.

@seamless-auth/express@0.16.0

Minor Changes

  • 36d530b: Accept the auth API's access token as a bearer credential in requireAuth and getSeamlessUser.

    Both guards read req.cookies and nothing else, so a native client, which has no cookie jar
    and holds the auth API's own tokens, was rejected on every request to an adopter's routes.
    requireAuth now takes an optional authServerUrl + audience pair; with both configured it
    also accepts Authorization: Bearer <access token>, verified against the auth API's JWKS
    (issuer, audience, expiry) and required to carry typ: "access", so a sign-in flow's
    ephemeral token is refused even though the same key signs it. The cookie wins when both are
    present, and leaving the pair out keeps the guard cookie-only, which is what every earlier
    version did. Half of the pair is a setup error.

    getSeamlessUser resolves a bearer session too. The router options already carry
    authServerUrl and audience, so no new option is needed there: a request with no access
    cookie but a valid bearer token is verified the same way and forwarded to GET /users/me as
    the caller's identity, while a request with neither, or a token that fails verification,
    returns null without an upstream call.

    On the bearer path req.user.email and req.user.phone are unset, because the access token
    does not carry them; getSeamlessUser hydrates the profile.

    Core exports verifyAccessToken, extractBearerToken, authenticateBearer, and
    authenticateRequest. getSeamlessUser in core takes an optional bearer: { authorization, audience }. The JWKS memo that verifySignedAuthResponse used moves to a shared module so both
    verifiers share one instance per auth server. Fastify gains direct tests for its guards, which
    until now were covered only through the plugin parity suite.

    Tracks feat(guards): accept bearer tokens in requireAuth and getSeamlessUser #147.

  • 0222376: Serve a bearer transport on the auth routes for native clients, and add POST /refresh.

    Every proxied route assumed cookies: identity came from the cookie payload, session responses
    were stripped of their tokens and minted into cookies, and silent refresh ran on the refresh
    cookie. A native app has no cookie jar, so it could not sign in through the adapter at all, and
    going around it to the auth API directly would bypass message delivery, client IP forwarding,
    and the service token, and need the auth API exposed.

    A request that carries x-seamless-auth-transport: bearer now gets a bearer contract on the
    same routes. The client presents the token a route needs in Authorization: Bearer (the
    ephemeral token /login or /registration/register returned on pre-auth routes, the access
    token on access routes) and the adapter forwards it to the auth API as-is. Session-issuing
    responses come back whole, token and refreshToken included, with no Set-Cookie; the auth
    API's signature on the access token is still verified before the body goes out. ensureCookies
    is skipped. A route that needs an identity and gets no bearer token answers 401 with the same
    error it gives a missing cookie. The header rather than the presence of Authorization selects
    the transport, because the first request of a flow carries no token in either. Requests without
    the header are served exactly as before.

    POST /refresh is new in both adapters. In bearer transport it takes Authorization: Bearer <refreshToken> and returns the rotated pair, passing the auth API's failure body through so a
    client can tell refresh_token_reused from a transient error. Concurrent rotations of the same
    token are collapsed into one upstream call, since the auth API treats a replayed refresh token as
    theft. In cookie transport it rotates the refresh cookie into fresh session cookies, for a client
    that wants an explicit refresh.

    Core: AuthTransport, resolveAuthTransport, AUTH_TRANSPORT_HEADER, sessionResult (what
    every session-issuing handler now returns through), a transport option on loginHandler,
    registerHandler, finishLoginHandler, the OTP verify handlers,
    pollMagicLinkConfirmationHandler, switchOrganizationHandler and finishOAuthLoginHandler,
    transport and authorization on checkProxyIdentity, transport on applyResult,
    refreshBearerSession, and refreshHandler. The parity suite drives a full bearer sign-in
    through both adapters.

    Closes feat(transport): bearer transport mode for the auth proxy #163.

Patch Changes

  • Updated dependencies [36d530b]
  • Updated dependencies [0222376]
    • @seamless-auth/core@0.16.0

@seamless-auth/fastify@0.7.0

Minor Changes

  • 36d530b: Accept the auth API's access token as a bearer credential in requireAuth and getSeamlessUser.

    Both guards read req.cookies and nothing else, so a native client, which has no cookie jar
    and holds the auth API's own tokens, was rejected on every request to an adopter's routes.
    requireAuth now takes an optional authServerUrl + audience pair; with both configured it
    also accepts Authorization: Bearer <access token>, verified against the auth API's JWKS
    (issuer, audience, expiry) and required to carry typ: "access", so a sign-in flow's
    ephemeral token is refused even though the same key signs it. The cookie wins when both are
    present, and leaving the pair out keeps the guard cookie-only, which is what every earlier
    version did. Half of the pair is a setup error.

    getSeamlessUser resolves a bearer session too. The router options already carry
    authServerUrl and audience, so no new option is needed there: a request with no access
    cookie but a valid bearer token is verified the same way and forwarded to GET /users/me as
    the caller's identity, while a request with neither, or a token that fails verification,
    returns null without an upstream call.

    On the bearer path req.user.email and req.user.phone are unset, because the access token
    does not carry them; getSeamlessUser hydrates the profile.

    Core exports verifyAccessToken, extractBearerToken, authenticateBearer, and
    authenticateRequest. getSeamlessUser in core takes an optional bearer: { authorization, audience }. The JWKS memo that verifySignedAuthResponse used moves to a shared module so both
    verifiers share one instance per auth server. Fastify gains direct tests for its guards, which
    until now were covered only through the plugin parity suite.

    Tracks feat(guards): accept bearer tokens in requireAuth and getSeamlessUser #147.

  • 0222376: Serve a bearer transport on the auth routes for native clients, and add POST /refresh.

    Every proxied route assumed cookies: identity came from the cookie payload, session responses
    were stripped of their tokens and minted into cookies, and silent refresh ran on the refresh
    cookie. A native app has no cookie jar, so it could not sign in through the adapter at all, and
    going around it to the auth API directly would bypass message delivery, client IP forwarding,
    and the service token, and need the auth API exposed.

    A request that carries x-seamless-auth-transport: bearer now gets a bearer contract on the
    same routes. The client presents the token a route needs in Authorization: Bearer (the
    ephemeral token /login or /registration/register returned on pre-auth routes, the access
    token on access routes) and the adapter forwards it to the auth API as-is. Session-issuing
    responses come back whole, token and refreshToken included, with no Set-Cookie; the auth
    API's signature on the access token is still verified before the body goes out. ensureCookies
    is skipped. A route that needs an identity and gets no bearer token answers 401 with the same
    error it gives a missing cookie. The header rather than the presence of Authorization selects
    the transport, because the first request of a flow carries no token in either. Requests without
    the header are served exactly as before.

    POST /refresh is new in both adapters. In bearer transport it takes Authorization: Bearer <refreshToken> and returns the rotated pair, passing the auth API's failure body through so a
    client can tell refresh_token_reused from a transient error. Concurrent rotations of the same
    token are collapsed into one upstream call, since the auth API treats a replayed refresh token as
    theft. In cookie transport it rotates the refresh cookie into fresh session cookies, for a client
    that wants an explicit refresh.

    Core: AuthTransport, resolveAuthTransport, AUTH_TRANSPORT_HEADER, sessionResult (what
    every session-issuing handler now returns through), a transport option on loginHandler,
    registerHandler, finishLoginHandler, the OTP verify handlers,
    pollMagicLinkConfirmationHandler, switchOrganizationHandler and finishOAuthLoginHandler,
    transport and authorization on checkProxyIdentity, transport on applyResult,
    refreshBearerSession, and refreshHandler. The parity suite drives a full bearer sign-in
    through both adapters.

    Closes feat(transport): bearer transport mode for the auth proxy #163.

Patch Changes

  • Updated dependencies [36d530b]
  • Updated dependencies [0222376]
    • @seamless-auth/core@0.16.0

@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 5ae37aa to a2ce45f Compare September 13, 2026 15:42
@Bccorb
Bccorb merged commit 4bc1f1f into main Sep 13, 2026
@Bccorb
Bccorb deleted the changeset-release/main branch September 13, 2026 16:41
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.

feat(transport): bearer transport mode for the auth proxy

1 participant