Repository navigation
feat(verify): an adapter conformance suite any server adapter can run - #251
Merged
Merged
Conversation
Server adapters hold the auth API's tokens in cookies, so each one is part of the security surface, but only the Node adapters had anything to prove themselves against, and the adapter specs covered the happy paths alone. verify/CONFORMANCE.md now states the reference app contract, and the adapter specs cover cookie attributes and clearing, refresh rotation, concurrent refresh and refresh-token reuse, bearer transport, the adapter's guard on an app route, error passthrough, no tokens in cookie-transport bodies, and forwarding of the client address and user agent, read back from the auth API's own events. `seamless verify --adapter-url=<url>` runs them against a reference app on any other adapter. The reference apps trust one proxy hop, so each virtual user gets its own client address and rate-limit bucket, serve a guarded /api/me, accept AUTH_SERVER_ISSUER, and pin the current adapter releases. Closes #246.
This was referenced Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #246. Part of fells-code/seamless-auth-api#371.
Why
Server adapters hold the auth API's tokens in cookies, so each one is part of the security surface. Only the Node adapters had parity tests, inside
seamless-auth-server. The adapter specs here covered the happy paths and nothing about cookies, refresh, bearer transport or what reaches the API. A Go, Rust or Python adapter had nothing to prove itself against.What changes
The contract.
verify/CONFORMANCE.mdstates what a reference app on any adapter must serve:GET /for health/authGET /api/mebehind the adapter's own guardGET /__captured/:recipient, fed by the adapter's external-delivery hookIt also gives the configuration, including
AUTH_SERVER_ISSUERfor an app that reaches the API through a published port, and every behaviour the specs check.Six new specs in
verify/harness/adapter/. They run against the Express and Fastify reference apps on everyseamless verify.cookieAttributesHttpOnly; Secure; SameSite=None; Path=/andMax-Ageequal to the API's lifetimes; clearing on logout; notokenorrefreshTokenin any cookie-transport bodyrefreshRotationPOST /auth/refreshreturns no tokensbearerTransport/auth/users/meand/api/me; refresh rotation and reuse; logout ends the sessionprotectedEndpoint/api/merefuses no session and an altered cookie, and sees the signed-in usererrorPassthrough400keeps its body; no session answers401with an error code; an unknown route answers404clientForwardingseamless verify --adapter-url=<url>starts only Postgres and the auth API, then runs the same specs as a newconformancePlaywright project against a reference app the caller started. It skips packing the Node adapters and the browser layer, and exits 1 when the app fails.Reference apps
X-Forwarded-ForandUser-Agent. That is what makes forwarding checkable, and it gives each user its own rate-limit bucket on the API, which removes the shared per-IP OTP cap that used to constrain these specs.trustProxy./api/meand acceptAUTH_SERVER_ISSUER.@seamless-auth/express^0.19.1and@seamless-auth/fastify^0.10.1. The old^0.16.0and^0.7.0pins meant the daily released smoke test was testing adapters several minors old.Found by the suite
requireAuthrefused every cookie session on routes outside the plugin. Fixed in fix(fastify): read the session cookie on routes outside the plugin seamless-auth-server#209.trustProxyour README recommends, so Fastify adopters forward the proxy's address as the client IP. Docs fix pending.Before merging
seamless-auth-servermain. The Fastify/api/mecookie case fails until fix(fastify): read the session cookie on routes outside the plugin seamless-auth-server#209 merges.Checks
npm test: 57 files, 1175 passed. That includes 4 newverifytests for--adapter-url: services started, project and environment, no packing with--local, exit 1 on failure, and URL validation.npm run buildpasses.mainand the adapters built from fix(fastify): read the session cookie on routes outside the plugin seamless-auth-server#209:adapterandadapter-fastifyprojects: 48 of 48, three runs in a row.conformanceproject against the Express reference app running on the host throughAUTH_SERVER_ISSUER, the setup an external adapter uses: 24 of 24.Not covered yet: a non-JSON error body from the API, such as a plaintext
429. It needs a fault-injecting proxy between the adapter and the API, andCONFORMANCE.mdsays so.