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.

  1. Cross-stack and security scenarios (tests/integration/auth4d-29/, tests/security/), configured by tests/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’s API service 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. The x-auth4d29-fault request header (harness/faults.ts) makes D1, Durable Object or queue bindings fail for that request only.
  2. Per-ticket integration suites (tests/integration/vitest.config.ts, the same as pnpm test).
  3. Browser, SDK and C# scenarios (tests/integration/browser/). scripts/verify/stack.mjs builds the login and console assets, applies migrations and starts both Workers with wrangler dev on 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, and tests/integration/csharp-harness runs 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 dev logs 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: documents GET /management-auth/current, POST /management-auth/revoke and POST /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