Auth and scope
Auth and scope
Section titled “Auth and scope”Callspec keeps credentials out of the RPC contract. The client sends Authorization: Bearer …; that token is never part of the route’s input pred or generated client types. You verify tokens however you already do — JWT, session lookup, API keys — in one authenticate(token, req) hook on the spec. Whatever your hook returns becomes handler ctx; routes that allow anonymous callers normally see ctx: undefined.
Per route, choose whether a valid token is required: auth: 'bearer' (default) or auth: 'none'. Callspec runs the gate before the handler — missing or invalid credentials → 401 UNAUTHORIZED, and your handler never runs. If any route uses 'bearer', spec throws at load time when authenticate callback is missing.
auth: 'none'— no credentials required;ctxis normallyundefinedunless set byauthenticateauth: 'bearer'(default) — missing or invalid token → 401 before the handler runs
OpenAPI Bearer security is auto-derived from route auth.
Scope controls whether a route is published in specs (and by extension, docs and generated clients). Scope allows you to have “undocumented” routes. These routes are mounted and available either way, and have nothing to do with auth.
scope: 'public'(default) — on the public contract (callspec.json, OpenAPI, docs UI, SDK codegen, MCPtools/list)scope: 'private'— documented when this mount usesvisibility: 'all'. Does not change the auth gate.
visibility on mountSpec / emitCallspec / emitOpenApi (default 'public'):
'public'— public-scope routes only (prod)'all'— public and private routes on the same/docsand JSON (dev/stage)
mountSpec(router, api, { visibility: process.env.NODE_ENV === 'production' ? 'public' : 'all',});Callspec does not read NODE_ENV itself. There is no npx callspec --scope flag — the CLI reads whatever callspec.json the server already served. Point it at a mount that used visibility: 'all' if you want private methods in the client.
← mountSpec · Next: Surfaces & exports