Sales workload authentication migration is production-ready and clears the ADR-0039 Sales gate
Sales clears event:sales-workload-auth-migration-ready.
Production migration
Sales commit c90e168 migrates the shared
lib/platform/service-token-client.ts client from the root-secret mint route
to Platform's Vercel OIDC workload exchange. Every Sales Revenue client already
uses this shared client, so the change covers credit-account reads, order reads
and writes, reservation create and release operations, and Sales ordering
close without adding a parallel authentication path.
The production client selects capability revenue.sales-operations, uses the
exact Platform exchange audience, and validates the complete returned policy
before caching a token. It requires sub: sales, aud: revenue, tenant
tnt_sguild, non-empty canonical Organization reach, a maximum five-minute
lifetime, issuance bounds and JTI, and exactly the seven approved scopes. It
rejects missing, incomplete, or widened claims, coalesces concurrent refreshes,
caches only in process with a one-minute refresh margin, and fails closed when
OIDC or exchange fails. Production cannot fall back to a static bearer.
The clean direct deployment was dpl_FY6D5C98gWodt6J8GWvFtC6cVeL1. Vercel's
Git integration then deployed the same pushed commit as
dpl_DCDiHwP6GwcKJuq3hTapCDG2MC6H. The latter is the current production
deployment, is READY, owns https://sales.sguildswim.com, and returned HTTP
200 on the custom domain. Its post-deployment error scan was clean and the
removed proof route returned HTTP 404.
Successful workload and route proof
Sales used an isolated production deployment behind Vercel deployment
protection and a one-time proof nonce. Platform issued policy
sales-production-to-revenue-v1 at 2026-08-02T19:55:45Z with the approved
subject, audience, tenant, canonical Organization, exact seven scopes, a
300-second lifetime, and JTI a2a2460c-3c6b-4113-b178-aeee497fe627.
The issued bearer reached all nine approved HTTP operations. The two order reads returned HTTP 200. Credit coverage and each safe malformed write probe returned HTTP 400 after accepting the bearer. No operation returned 401, 403, 405, 429, or 5xx. The write probes intentionally omitted required fields, so they created no customer, order, reservation, external invoice, or ledger state.
The proof covered:
GET /api/v1/credit-accounts/coverage;GET /api/v1/orders/invoice-link;GET /api/v1/orders/credit-purchases;POST /api/v1/orders/invoice-link;POST /api/order-externals/cancel-invoice;POST /api/v1/reservations;POST /api/v1/reservations/atomic-multi-create;POST /api/v1/reservations/{id}/release; andPOST /api/v1/sales-ordering/close.
The one-time proof nonce was removed from Vercel immediately after the proof. The temporary proof route is absent from the final deployment and returns HTTP 404.
Secret retirement and verification
PLATFORM_SERVICE_JWT_MINT_SECRET is absent from the Sales Vercel Production
and Preview environments. Sales' local environment no longer contains that
key, the fallback SERVICE_JWT_MINT_SECRET, or the legacy mint-route override.
No secret value was printed or recorded during removal. The tracked Sales
client contains no root-secret header or legacy mint request path.
Focused authentication, Revenue-client, and Workbench coverage passed 72 tests. TypeScript checking passed after generating the normal Prisma client. Both isolated Vercel production builds completed with migration history clean, Prisma generation successful, Next.js compilation successful, and route type checking successful. The readiness smoke confirms no local legacy root-mint secret and the expected fail-closed non-production behavior. Its existing cadence drift and local geography warnings are unrelated to service auth.
Remaining gates
This memo clears only Sales migration readiness. Revenue still owns its independent subject, scope, tenant, Organization, required-claim, denial, and authorization-audit enforcement proof. Revenue also still owns retirement or migration of its two standalone root-mint scripts. Platform must repeat the full inventory before root-secret rotation and legacy-route retirement.
No root secret was rotated and no Platform legacy route was retired by Sales.
References
2026-08-02-platform-adr-0039-sales-policy-deployed2026-08-02-sales-adr-0039-caller-inventory-approvedcontracts/service-auth/README.mdv1.3.0- Sales commit
c90e168