Protect an Express App
Use @caracalai/express when an Express app should verify Caracal mandates before route handlers run.
Prerequisites
Section titled “Prerequisites”- A Caracal-mandate resource whose audience matches this service.
- The zone STS issuer, zone ID, and a shared production revocation store.
- A route-by-route scope and target map.
Install
Section titled “Install”npm install express @caracalai/express @caracalai/verify @caracalai/revocationUse a Redis-backed revocation store in production. The in-memory store is only suitable for local development and tests.
Add middleware
Section titled “Add middleware”import express from 'express'import { caracalAuth, type CaracalRequest } from '@caracalai/express'import { createMandateVerifier } from '@caracalai/verify'import { InMemoryRevocationStore } from '@caracalai/revocation'
const app = express()
const verifier = createMandateVerifier({ issuer: process.env.CARACAL_ISSUER!, audience: 'resource://pipernet', zoneId: process.env.CARACAL_ZONE_ID!, revocations: new InMemoryRevocationStore(),})
await verifier.warmup()
app.use( '/reports', caracalAuth( { verifier }, { requiredScopes: ['pipernet:read'], requiredTargets: ['resource://pipernet'], }, ),)
app.get('/reports', (req: CaracalRequest, res) => { res.json({ principal: req.caracalClaims?.sub, reports: ['market-risk', 'quarterly'], })})The middleware attaches verified claims to req.caracal and req.caracalClaims, plus the propagation context at req.caracalContext.
Enforce the right boundary
Section titled “Enforce the right boundary”| Option | Use it for |
|---|---|
requiredScopes | Tool or route-level scope checks. |
requiredTargets | Resource-target checks. |
requireSession | Require a governed Session. |
requireDelegation | Require delegated authority. |
maxHopCount | Limit delegation depth. |
Validate
Section titled “Validate”- Exchange for a mandate that targets the resource.
- Call the protected route with
Authorization: Bearer <mandate>. - Remove a required scope and confirm the route returns
403. - Revoke the session and confirm the route rejects the old mandate.
Expected result: missing or invalid credentials return 401, valid but insufficient authority returns 403, and protected handlers run only after req.caracalClaims and req.caracalContext are populated.
For middleware option signatures, use Express Adapter reference.
Next Step
Section titled “Next Step”Add route-specific requirements, then test the boundary with Test Caracal Integrations.

