Every request the platform forwards to your zone carries a freshly minted JWT in the x-zone-token header. Your zone must verify it on every route before doing anything else.
middleware.ts
ts
import { createZoneMiddleware } from '@cxpa/sdk/zone'
export const middleware = createZoneMiddleware({
secret: process.env.ZONE_JWT_SECRET!,
audience: process.env.AUDIENCE_ID!,
})
// With `basePath` configured in next.config.ts, Next.js applies the matcher
// to the path *after* the basePath has been stripped — `/:path*` covers the
// entire zone surface (including the bare basePath root).
export const config = {
matcher: ['/:path*'],
}
AUDIENCE_ID must match the audience the platform mints tokens with for this agent — a platform admin configures it on the agent's settings page and shares the value with you alongside ZONE_JWT_SECRET.
What the middleware does
- Reads the JWT from
x-zone-token. - Verifies the HS256 signature against
ZONE_JWT_SECRET. - Checks the
audclaim againstAUDIENCE_ID. - Checks
exp/nbfwith a 5-second clock-skew tolerance. - On success: forwards the request and attaches
x-zone-claims(stringified JSON) so downstream code can read the verified payload. - On failure: returns
401 invalid zone token.
Rotating the secret
The platform supports two valid secrets during rotation: write the new value to a new runtime_secrets row, ask all zones to redeploy with the new secret in their environment, then retire the old row. There is no in-band rotation signal — coordinate the cutover with the platform admin.
Continue
Read the session inside your pages and server actions.