Skip to content

Verify Package

The verify packages authenticate Caracal mandates without tying the check to Express, FastMCP, or Go net/http. Framework adapters build on this engine.

Use one long-lived verifier per trust boundary so JWKS and revocation state are reused. Do not use it to mint mandates or create Sessions.

EcosystemPackage
TypeScriptnpm install @caracalai/verify
Pythonpip install caracalai-verify
Gogo get github.com/garudex-labs/caracal/packages/verify/go
APIPurpose
extractBearer / extract_bearer / ExtractBearerParse a bearer token from an Authorization header.
createMandateVerifier / NewVerifierBuild a reusable verifier with secure defaults, JWKS caching, revocation checks, and per-route overrides.
create_mandate_verifierPython reusable verifier with the same defaults, warmup, and per-route override model.
authenticate / AuthenticateVerify one token against identity claims and revocation anchors.
authenticateRequest / unauthorizedResponseAuthenticate a fetch-standard Request and render an AuthError as a JSON Response in WinterTC runtimes.
checkActiveAuthority / check_active_authority / CheckActiveAuthorityCheck expiry and revoked anchors for verified claims.
import { createMandateVerifier } from '@caracalai/verify'
import { InMemoryRevocationStore } from '@caracalai/revocation'
const verifier = createMandateVerifier({
issuer: 'https://sts.pipernet.example',
audience: 'resource://pipernet',
zoneId: '0195f2a9-1b22-7c3d-9e4f-5a6b7c8d9e0f',
revocations: new InMemoryRevocationStore(),
})
const result = await verifier.authorization(req.headers.authorization, {
requiredScopes: ['mcp:tool:call'],
requiredTargets: ['resource://pipernet'],
requireSession: true,
})
if (!result.ok) {
throw new Error(`${result.error.code}: ${result.error.hint}`)
}

Add route-level scopes or targets through verifier.authorization(..., overrides) or verifier.require(overrides).

Use one verifier per resource server. The verifier defaults to resource mandates, checks the STS issuer and audience, enforces zone, scope, target, Session, Delegation, and hop constraints, checks expiry, and queries the Authority record ID, Root authority record ID, Session ID, and Delegation ID parsed claims as revocation anchors. See the parsed claim mapping for language-level and raw JWT names.

Runtimes built on WinterTC Request/Response globals - Node 18+, Deno, Bun, and edge workers - can authenticate without a framework adapter:

import { authenticateRequest, unauthorizedResponse } from '@caracalai/verify'
export default {
async fetch(request: Request): Promise<Response> {
const result = await authenticateRequest(request, deps)
if (!result.ok) {
return unauthorizedResponse(result.error)
}
return handle(request, result.principal)
},
}

unauthorizedResponse maps error codes to 401 or 403 and renders the same JSON error body as the framework adapters. The same pair drops into any fetch-based framework. In Hono:

app.use('/api/*', async (c, next) => {
const result = await authenticateRequest(c.req.raw, deps)
if (!result.ok) return unauthorizedResponse(result.error)
c.set('principal', result.principal)
await next()
})

And in a Next.js route handler:

export async function GET(request: Request): Promise<Response> {
const result = await authenticateRequest(request, deps)
if (!result.ok) return unauthorizedResponse(result.error)
return Response.json(await loadReports(result.principal))
}

Python and Go services cover this role with the ASGI adapter and the net/http adapter, which wrap their ecosystems’ native request types.

authenticate and reusable verifiers normalize failures into typed error codes: missing_token, invalid_token, invalid_zone, insufficient_scope, session_revoked, delegation_stale, session_required, delegation_required, chain_mismatch, and hop_count_exceeded. TypeScript, Python, and Go reusable verifiers include a safe debugging hint for operator logs and API error bodies. STS and Gateway report the zone and scope conditions with their own spellings, zone_invalid and scope_insufficient; see Error Codes for the per-surface mapping.

Authentication performs no retry of the protected operation. A JWKS or revocation-store failure fails verification rather than widening authority. Warm the verifier at process startup where the language API exposes warmup; close any caller-owned HTTP or Redis clients during service shutdown.