v0.21 Release Notes
v0.21 makes Seamless Auth an OpenID Provider. Any app that speaks OpenID Connect can sign users in
with Seamless passkeys through a new service, seamless-auth-oidc-provider, with no Seamless SDK.
It shipped as auth API 0.21.0 and OpenID Provider 0.1.0, with matching releases of the shared types,
server adapters, admin dashboard and CLI. The versions that go together are in the
Compatibility Matrix. Full details are in each package’s
changelog and GitHub release.
OpenID Provider
Section titled “OpenID Provider”- A separate edge service.
seamless-auth-oidc-provideris the public login edge in front of the private API. It holds no database and no private keys: the API stores every provider record and signs every token after checking its claims. It runs as an image (ghcr.io/fells-code/seamless-auth-oidc-provider) or embeds in an Express app. See OpenID Provider. - Locked to OAuth 2.1 and RFC 9700. The code flow with
S256PKCE, exact redirect matching (RFC 8252 loopback ports for native apps), refresh rotation with reuse detection,isson authorization responses, andprivate_key_jwtfor confidential clients. Shared secrets and a per-client PKCE opt-out exist only for confidential apps that support nothing else, and only when an admin turns them on. - Grants. Authorization code, refresh token, client credentials, and the device authorization grant (RFC 8628) for first-party CLIs and devices. Every device approval asks for a passkey again.
- Tokens for your APIs. Register a resource and its scopes, and an application asking with
resource=gets an RFC 9068 JWT access token whoseaudis that API. Per-application token lifetimes apply. - Hosted pages. Login, consent, step-up, device verification and sign-out pages, branded from
the
hosted_uisystem config, served under a strict nonce CSP. - Step-up.
acr_values,max_ageandprompt=loginare honoured, andacrandamrreflect how the user signed in, including a later step-up. - Sign-out. RP-initiated logout at
/session/end, and OpenID Back-Channel Logout tokens to every app that registered abackchannelLogoutUriwhen the session behind a sign-in ends. - Introspection and revocation (RFC 7662, RFC 7009).
- Admin. Applications and resources under
/admin/applicationsand/admin/resources(admin write and step-up, audited), the dashboard’s Applications, Resources, OpenID Provider and Hosted Page Branding screens, andseamless clients,seamless resourcesandseamless config hosted-uiin the CLI.
Verify-Only Resource Servers
Section titled “Verify-Only Resource Servers”APIs that receive the provider’s access tokens check them without a cookie secret, service token or
auth routes. createResourceServer({ issuer, audience }) in @seamless-auth/express and
@seamless-auth/fastify, and the matching verify-only mode in the Go, Python and Rust adapters, find
the keys through discovery and check iss, aud, the at+jwt header and the claims, with audience,
scope, role and step-up guards.
Inbound OAuth From An Issuer
Section titled “Inbound OAuth From An Issuer”An inbound OAuth provider can be configured from its issuer alone. Endpoints you leave out are read
from the issuer’s discovery document when the provider is used, cached for an hour, and held to the
same rules as typed ones. The dashboard’s provider form has a “Discover from issuer” option, and the
CLI takes seamless config oauth-providers add --issuer <url>.
OAuth state replay records now live in the database, so a replayed state is refused by every
instance and callbacks no longer need sticky routing.
Account Notices From Applications
Section titled “Account Notices From Applications”POST /applications/account-notices lets a registered application tell one of its users something
on their verified email or phone without holding either. It takes a client credentials token with
scope notices:send, reaches only users who signed in to that application, and is rate limited per
application and per user. An admin turns it on per application.
Also In v0.21
Section titled “Also In v0.21”- Server adapters. A proxied request that silently refreshed the session is served on the same
request, instead of failing once with
access session required. A recovery session is rotated right after it enrolls a passkey or authenticator app. - Go, Python and Rust adapters (0.4.0). Check
allowedOriginsalongsideSec-Fetch-Siteand verify the access token inside the cookie, matching the JavaScript adapters. - CLI (0.27.0).
seamless migrate assesswrites a readiness report from the source alone, andseamless migrate auth0andmigrate cognitoread the vendors’ exports directly.seamless initscaffolds templates v0.21.1, whose production images run as non-root on port 8080.
Upgrading
Section titled “Upgrading”Upgrade the auth API first, then the server adapters, the dashboard and the CLI. Clients need no change.
- Upgrade the auth API to 0.21.0. It runs three additive migrations on start unless
RUN_MIGRATIONS=false: the provider tables, two session columns that record how the user signed in, and the per-application PKCE and nonce settings. If you setRUN_MIGRATIONS=false, run them first, because the server refuses to start while any migration is pending. The console at/consoleis dashboard 0.12.0. - Upgrade the server adapters:
@seamless-auth/express0.23.0,@seamless-auth/fastify0.14.0,@seamless-auth/nextjs0.7.0, or the Go, Python or Rust adapter 0.4.0. The dashboard’s OpenID Provider screens go through the adapter, so it must be one of these versions, or an adapter that reads the live route manifest from API 0.21.0. - Upgrade the dashboard to 0.12.0 if you deploy it separately, and the CLI to 0.27.0.
- Do not set
OIDC_PROVIDER_ENABLEDuntil the edge is ready. With it on, the API refuses to start unless the issuer,SEAMLESS_OIDC_SERVICE_TOKENand theOIDC_JWKS_*key set are all valid.
Turning On The OpenID Provider
Section titled “Turning On The OpenID Provider”Follow Deploy The Edge. In order:
- Pick the issuer hostname. It must use
https, differ from the API’sISSUER, and be yourrpidor a subdomain of it, for examplehttps://login.example.com. - Create the edge’s secrets. A new
SEAMLESS_OIDC_SERVICE_TOKEN, set on both the API and the edge, that differs fromSEAMLESS_SERVICE_TOKEN. Never give the edge the adapters’ token. A provider key set for the API (OIDC_JWKS_KEYSandOIDC_JWKS_ACTIVE_KID) that shares no key withSEAMLESS_JWKS_*. ASEAMLESS_COOKIE_SECRETandOIDC_COOKIE_KEYSfor the edge. - Deploy the API with those secrets, and add the issuer origin to its
originsconfig. - Turn the provider on from an admin session with a fresh step-up: the dashboard’s System
Configuration, or
seamless config set oidc_issuer <url>and thenseamless config set oidc_provider_enabled true. On a new instance,OIDC_ISSUERandOIDC_PROVIDER_ENABLEDseed both on first boot instead. - Run the edge (0.1.0, which needs auth API 0.21.0) behind TLS. Every cookie it sets is a
__Host-cookie, so it needs HTTPS in development too. Terminate TLS at a proxy, setTRUST_PROXY=true, and keep the originalHostheader, or requests get421 misdirected_request. The edge refuses to start while the provider is off or when the API speaks a different/oidc/*contract version, so always deploy the API and the edge from the same release. - Check
/.well-known/openid-configurationand/jwkson the issuer, then register an application and sign in once.
Not In v0.21
Section titled “Not In v0.21”- Provider access tokens do not yet carry
roles,acr,amrorauth_time, so the verify-only role and step-up guards refuse them. Audience and scope checks work. - An expired device code gets
invalid_grantrather thanexpired_token(#542), and ending one application’s grant sends no back-channel logout (#543). seamless initdoes not scaffold the OpenID Provider service yet.- FIDO and OpenID certification are deferred to v1.0.