AUTH4D-29 cross-stack verification and release evidence
AUTH4D-29 adds no endpoints. It verifies the assembled API, hosted login, console BFF and SDKs through their real HTTP boundaries, and checks that this combined specification documents every route the API Worker registers.
Running
pnpm test:integration # all suites, then writes the release report
AUTH4D29_SKIP_BROWSER=1 pnpm test:integration # in-isolate suites only (no Chromium or .NET)
scripts/verify/release.mjs runs three suites and writes .generated/auth4d-29/release-report.md
and .json (both ignored). It exits non-zero if any suite fails or a credential appears in the
captured logs.
- Cross-stack and security scenarios (
tests/integration/auth4d-29/,tests/security/), configured bytests/integration/auth4d-29/vitest.config.ts. The unmodified API Worker and console BFF run in one workerd isolate under the Workers Vitest integration. Requests are routed by origin (harness/worker.ts), and the BFF’sAPIservice binding points back to that entry. The run uses real D1 migrations, Durable Objects and the email queue consumer, with the local mailbox, a loopback Discord stand-in (scripts/verify/mock-discord.mjs) and secrets generated for that run. Thex-auth4d29-faultrequest header (harness/faults.ts) makes D1, Durable Object or queue bindings fail for that request only. - Per-ticket integration suites (
tests/integration/vitest.config.ts, the same aspnpm test). - Browser, SDK and C# scenarios (
tests/integration/browser/).scripts/verify/stack.mjsbuilds the login and console assets, applies migrations and starts both Workers withwrangler devon 127.0.0.1:8797 (API) and :8798 (console). A loopback control server on :8796 reports readiness and returns the run’s email codes, which it decrypts from the outbox. All state is kept in the ignored.wrangler/auth4d-29/<run>/directory. Playwright drives Chromium, andtests/integration/csharp-harnessruns the Unity package’s portable runtime over real HTTP.
Coverage
- Developer onboarding: console email sign-in through the BFF; project, browser app, native app and sign-in method configuration.
- Browser login: hosted email code, Discord through the mock, consent reuse, denial, cancellation; browser SDK login and server SDK verification.
- Guest accounts: email and Discord upgrades that keep the user ID; identity-in-use conflicts; native guests with rotating refresh tokens; the hosted upgrade window’s postMessage handshake.
- Native device login: hosted approval, denial and the no-session case; the C# client’s guest, refresh, revocation and device flows.
- Negative cases: cross-tenant identities, tokens, codes, flow cookies, proofs and management access; management/customer token substitution in both directions; login, linking, device-approval and BFF CSRF; redirect, implicit, plain-PKCE and scope abuse; replay of single-use codes, proofs and email codes; concurrent code redemption; refresh races and rotated-token replay (the family is revoked); cross-origin response headers.
- Failure injection: Discord token/profile errors, slow responses and malformed responses; D1 read/write outages (no partial projects, codes are not consumed); challenge and session Durable Object outages; control-plane authority outage; email queue rejection.
- Evidence: every credential a test observes (tokens, codes, cookies, proof IDs, Worker secrets) is
checked against captured Worker logs. The
wrangler devlogs are scanned for the run’s secrets and for token-shaped strings. The combined API specification is regenerated and checked for fragment headings, completeness, credentials, and coverage of every registered route.
Defects corrected in owning modules
apps/api/src/runtime/app.ts: CORS headers set before feature dispatch were dropped from feature responses, so browsers could not read guest, token or UserInfo responses from registered game origins. The headers are now applied to the final response (tests/security/auth4d-29.cors.test.ts).docs/api-spec/auth4d-17.md: documentsGET /management-auth/current,POST /management-auth/revokeandPOST /management-auth/revoke-session.
Identified limits
The report lists these limits. Local CPU is the total workerd process time divided by the number of
requests, so it is an upper bound; confirm with wrangler tail on staging. Latency is loopback
wall-clock time. Fault injection happens at binding boundaries, so it does not cover partial D1
batches or Durable Object eviction mid-request. Live Discord, real email delivery and cross-colo
Durable Object contention require staging. The CORS allowlist (CLIENT_ORIGINS) is
deployment-wide.
Source: docs/api-spec/auth4d-29.md