Authentication -- Verify API
Verify's audit endpoints and Sentinel Watch use two independent Bearer token systems. This page documents both, and where the boundary between them actually is.
One rule that applies everywhere
Every authenticated route reads the token from a standard Authorization header. There is no query-parameter fallback anywhere in the API, and tokens must never be committed to source control or client-side code.
- Authorization: Bearer <token>
- Missing token, invalid token, and insufficient scope are three distinct failures -- see /docs/errors for the exact status codes and response bodies each system returns.
- Scopes are least-privilege: request only the scope a given integration needs.
Audits: verify:audit / verify:readiness
POST /v1/audits/mcp and POST /v1/audits/readiness are gated by JWT bearer tokens issued by Sentinel Signal's token service, checked against the scope literally required by the route.
- verify:audit -- required by POST /v1/audits/mcp
- verify:readiness -- required by POST /v1/audits/readiness
- Missing bearer token -> 401.
- Token present but missing the required scope -> 403, naming the scope it needed.
Sentinel Watch: watch:read / watch:write
The entire /v1/watch/* surface (including the /v1/watch/policies sub-resource) is gated by a separate, opaque API-key system scoped to an organization -- not the same JWTs used by the audit endpoints above.
- watch:read -- read access; a write-scoped key can also read.
- watch:write -- required to create, update, delete, or manually run a watch or policy.
- Keys are issued per organization by Sentinel Signal; there is no self-service key-creation endpoint.
- Missing bearer token, an invalid/revoked key, and an expired key are three distinct 401 outcomes with distinct error codes.
- A key missing the required scope -> 403, naming the scopes it needed.
These are not one system with two scope sets
This is a real, deliberate architectural boundary, not a documentation simplification: audit-endpoint JWTs and Watch API keys are two structurally different credential types, verified by two different pieces of code, backed by two different lookup tables. A token that works for /v1/audits/readiness cannot be extended to also work against /v1/watch by adding a scope to it -- it is simply not the credential type Watch checks. If you need both, request both.