From af41ba485ebd635586ea2ae2840f4c7d5f63a036 Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Tue, 8 Sep 2026 18:39:37 -0400 Subject: [PATCH 1/2] chore: bump to auth API v0.12.0 and dashboard v0.6.0 v0.11.0 puts passkey enrollment behind an access session, a breaking wire contract change: the API refuses the pre-auth token enrollment used to accept, so an ephemeral token can no longer enroll a credential against an account and then sign in as its owner. It also declares and validates the window on GET /admin/users, and adds organization deletion with a paged, searchable admin organization list. v0.12.0 ships dashboard v0.6.0 in the API image, so the dashboard pin moves with it and the standalone console serves the same release the image serves at /console. The conformance adapters move to @seamless-auth/express ^0.14.0 and @seamless-auth/fastify ^0.5.0, the other half of the enrollment change: they forward the access session the API now requires. They also proxy the organization delete, and forward the query string on GET /admin/users and GET /internal/auth-events/login-stats, which both dropped it. SEAMLESS_TEMPLATES_REF stays at v0.12.0. Its API starters pin the adapters from before the enrollment change and a caret on a 0.x version cannot reach 0.14.0 or 0.5.0, so a project scaffolded against this release runs a new API behind an old adapter and passkey enrollment answers 401 until templates publishes with the new pins and the ref follows. Email OTP and magic link sign-in are unaffected. The harness pins its own adapters, so it exercises the matched pair and will not show this. --- .changeset/ecosystem-bump-api-v0-12-0.md | 33 ++++++++++++++++++++++++ src/core/images.ts | 4 +-- verify/adapter-app/package.json | 2 +- verify/adapter-fastify-app/package.json | 2 +- 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 .changeset/ecosystem-bump-api-v0-12-0.md diff --git a/.changeset/ecosystem-bump-api-v0-12-0.md b/.changeset/ecosystem-bump-api-v0-12-0.md new file mode 100644 index 0000000..c1e9d5a --- /dev/null +++ b/.changeset/ecosystem-bump-api-v0-12-0.md @@ -0,0 +1,33 @@ +--- +'seamless-cli': minor +--- + +Move the scaffold onto auth API `v0.12.0` and admin dashboard `v0.6.0`. + +`v0.11.0` puts passkey enrollment behind an access session. It is a breaking change to the wire +contract: the API refuses the pre-auth token enrollment used to accept, so an ephemeral token can no +longer enroll a credential against an account and then sign in as its owner. Enrollment also stops +issuing a session of its own, answering `200` with the credential instead. The same release declares +and validates the window on `GET /admin/users`, and adds organization deletion along with a paged, +searchable admin organization list. `v0.12.0` ships dashboard `v0.6.0` inside the API image, which is +what that dashboard release needs: it pages and searches organizations on the server, gains a remove +action, takes a date range on Overview and Security, and grows an Authenticator Policy section. + +The admin dashboard pin moves with it, so the standalone console (`--admin=image` and +`--admin=source`) serves the same release the API image serves at `/console`. + +The conformance harness's adapters move to `@seamless-auth/express` `^0.14.0` and +`@seamless-auth/fastify` `^0.5.0`, which is the other half of the enrollment change: they forward the +access session the API now requires. They also proxy `DELETE /admin/organizations/:organizationId`, +and forward the query string on `GET /admin/users` and `GET /internal/auth-events/login-stats`, which +both dropped it, so the dashboard's user search and its login statistics range now reach the API as +sent. + +**A scaffolded project needs the next seamless-templates release to enroll a passkey.** +`SEAMLESS_TEMPLATES_REF` stays at `v0.12.0`, whose API starters pin `@seamless-auth/express` +`^0.13.0` and `@seamless-auth/fastify` `^0.4.0`. Those are the adapters from before the enrollment +change, and a caret on a `0.x` version cannot reach `0.14.0` or `0.5.0`, so a project scaffolded +against this release runs a new API behind an old adapter and passkey enrollment answers `401` until +templates publishes with the new pins and `SEAMLESS_TEMPLATES_REF` follows. Email OTP and magic link +sign-in are unaffected. The conformance harness pins its own adapters, so it exercises the matched +pair and will not show this. diff --git a/src/core/images.ts b/src/core/images.ts index c163572..77cb738 100644 --- a/src/core/images.ts +++ b/src/core/images.ts @@ -3,11 +3,11 @@ // scaffolded with, and never has its data directory pulled out from under it. export const POSTGRES_IMAGE = "postgres:18"; -export const SEAMLESS_AUTH_API_VERSION = "v0.10.0"; +export const SEAMLESS_AUTH_API_VERSION = "v0.12.0"; export const SEAMLESS_AUTH_API_IMAGE = `ghcr.io/fells-code/seamless-auth-api:${SEAMLESS_AUTH_API_VERSION}`; -export const SEAMLESS_AUTH_ADMIN_DASHBOARD_VERSION = "v0.5.0"; +export const SEAMLESS_AUTH_ADMIN_DASHBOARD_VERSION = "v0.6.0"; export const SEAMLESS_AUTH_ADMIN_DASHBOARD_IMAGE = `ghcr.io/fells-code/seamless-auth-admin-dashboard:${SEAMLESS_AUTH_ADMIN_DASHBOARD_VERSION}`; diff --git a/verify/adapter-app/package.json b/verify/adapter-app/package.json index 735a907..2a543cf 100644 --- a/verify/adapter-app/package.json +++ b/verify/adapter-app/package.json @@ -5,7 +5,7 @@ "type": "module", "description": "Minimal adopter backend for the conformance harness — real @seamless-auth/express with a capture transport.", "dependencies": { - "@seamless-auth/express": "^0.13.0", + "@seamless-auth/express": "^0.14.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", "express": "^5.1.0" diff --git a/verify/adapter-fastify-app/package.json b/verify/adapter-fastify-app/package.json index 2203863..10aae80 100644 --- a/verify/adapter-fastify-app/package.json +++ b/verify/adapter-fastify-app/package.json @@ -6,7 +6,7 @@ "description": "Minimal adopter backend for the conformance harness — real @seamless-auth/fastify with a capture transport.", "dependencies": { "@fastify/cors": "^11.0.1", - "@seamless-auth/fastify": "^0.4.0", + "@seamless-auth/fastify": "^0.5.0", "fastify": "^5.2.0" } } From 43417a1f80ef15cfd883c4e2ef754b303b944e19 Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Tue, 8 Sep 2026 18:52:54 -0400 Subject: [PATCH 2/2] chore: scaffold from seamless-templates v0.13.0 Templates v0.13.0 published after the previous commit and carries the matched half of the enrollment change: @seamless-auth/react 0.12.0, @seamless-auth/express 0.14.0 and @seamless-auth/fastify 0.5.0 in the starters. Its own notes say to point a scaffolded project at seamless-auth-api 0.12.0, which is what this branch pins. That closes the gap the previous commit documented. A scaffold no longer runs a new API behind an adapter from before the contract change, so passkey enrollment works out of the box and the changeset drops the caveat. The manifest contract and the registry are byte-identical to v0.12.0, so nothing in init moves with the ref. --- .changeset/ecosystem-bump-api-v0-12-0.md | 42 +++++++++++------------- src/core/images.ts | 2 +- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/.changeset/ecosystem-bump-api-v0-12-0.md b/.changeset/ecosystem-bump-api-v0-12-0.md index c1e9d5a..9ebee18 100644 --- a/.changeset/ecosystem-bump-api-v0-12-0.md +++ b/.changeset/ecosystem-bump-api-v0-12-0.md @@ -2,32 +2,30 @@ 'seamless-cli': minor --- -Move the scaffold onto auth API `v0.12.0` and admin dashboard `v0.6.0`. +Move the scaffold onto auth API `v0.12.0`, admin dashboard `v0.6.0`, and seamless-templates `v0.13.0`. `v0.11.0` puts passkey enrollment behind an access session. It is a breaking change to the wire -contract: the API refuses the pre-auth token enrollment used to accept, so an ephemeral token can no -longer enroll a credential against an account and then sign in as its owner. Enrollment also stops -issuing a session of its own, answering `200` with the credential instead. The same release declares -and validates the window on `GET /admin/users`, and adds organization deletion along with a paged, -searchable admin organization list. `v0.12.0` ships dashboard `v0.6.0` inside the API image, which is -what that dashboard release needs: it pages and searches organizations on the server, gains a remove -action, takes a date range on Overview and Security, and grows an Authenticator Policy section. +contract: `/webAuthn/register/start` and `/webAuthn/register/finish` used to accept the ephemeral +token the API mints from an email address alone, so anyone who knew an address could enroll a +credential against that account and sign in as its owner. Both routes read the access session now, +and enrollment no longer issues a session of its own, answering `200` with the credential instead. +The same release declares and validates the window on `GET /admin/users`, and adds organization +deletion along with a paged, searchable admin organization list. `v0.12.0` ships dashboard `v0.6.0` +inside the API image, which is what that dashboard release needs: it pages and searches organizations +on the server, gains a remove action, takes a date range on Overview and Security, and grows an +Authenticator Policy section. The admin dashboard pin moves with it, so the standalone console (`--admin=image` and `--admin=source`) serves the same release the API image serves at `/console`. -The conformance harness's adapters move to `@seamless-auth/express` `^0.14.0` and -`@seamless-auth/fastify` `^0.5.0`, which is the other half of the enrollment change: they forward the -access session the API now requires. They also proxy `DELETE /admin/organizations/:organizationId`, -and forward the query string on `GET /admin/users` and `GET /internal/auth-events/login-stats`, which -both dropped it, so the dashboard's user search and its login statistics range now reach the API as -sent. +The enrollment change has no safe release order, so every side of it moves here at once. Templates +`v0.13.0` carries `@seamless-auth/react` `0.12.0`, `@seamless-auth/express` `0.14.0` and +`@seamless-auth/fastify` `0.5.0` in the starters, and the conformance harness's adapters take the +same `^0.14.0` and `^0.5.0`. The adapters forward the access session the API now requires; an older +one sends what this API refuses, so a scaffold pinned to either half alone would answer `401` at +enrollment. No shipped flow loses a step, because registration proves an address with an email OTP +and verifying it issues the session before the passkey screen appears. -**A scaffolded project needs the next seamless-templates release to enroll a passkey.** -`SEAMLESS_TEMPLATES_REF` stays at `v0.12.0`, whose API starters pin `@seamless-auth/express` -`^0.13.0` and `@seamless-auth/fastify` `^0.4.0`. Those are the adapters from before the enrollment -change, and a caret on a `0.x` version cannot reach `0.14.0` or `0.5.0`, so a project scaffolded -against this release runs a new API behind an old adapter and passkey enrollment answers `401` until -templates publishes with the new pins and `SEAMLESS_TEMPLATES_REF` follows. Email OTP and magic link -sign-in are unaffected. The conformance harness pins its own adapters, so it exercises the matched -pair and will not show this. +The adapters also proxy `DELETE /admin/organizations/:organizationId`, and forward the query string +on `GET /admin/users` and `GET /internal/auth-events/login-stats`, which both dropped it, so the +dashboard's user search and its login statistics range now reach the API as sent. diff --git a/src/core/images.ts b/src/core/images.ts index 77cb738..43e0e5e 100644 --- a/src/core/images.ts +++ b/src/core/images.ts @@ -25,4 +25,4 @@ export const SEAMLESS_AUTH_ADMIN_DASHBOARD_REF = SEAMLESS_AUTH_ADMIN_DASHBOARD_V // SEAMLESS_TEMPLATES_REF, or point at a local checkout with SEAMLESS_TEMPLATES_DIR. export const SEAMLESS_TEMPLATES_REPO = "fells-code/seamless-templates"; -export const SEAMLESS_TEMPLATES_REF = "v0.12.0"; +export const SEAMLESS_TEMPLATES_REF = "v0.13.0";