Skip to content

Authority and Enforcement

Caracal separates granting authority from using authority.

  • The STS grants authority by issuing a short-lived mandate after policy evaluation.
  • The Gateway or connector uses authority by verifying the mandate before forwarding a request or running a tool.
sequenceDiagram
  participant Client as Agent or app
  participant STS as STS
  participant OPA as Active policy set
  participant Guard as Gateway or connector
  participant Resource as Protected resource
  participant Audit as Audit ledger

  Client->>STS: Exchange subject token for resource scopes
  STS->>OPA: Evaluate principal, session, grant, resource, delegation
  OPA-->>STS: allow, deny, diagnostics, or step-up requirement
  STS->>Audit: Record decision
  alt allowed
    STS-->>Client: Mandate JWT
    Client->>Guard: Request with mandate
    Guard->>Guard: Verify signature, claims, expiry, scopes, revocation
    Guard->>Resource: Forward approved request
    Guard->>Audit: Record resource decision
  else denied or step-up required
    STS-->>Client: Error or interaction_required challenge
  end
LayerResponsibilitySource of truth
ZoneOwns keys, policies, resources, sessions, and audit data.Console or Admin API
GrantDeclares which application and user may request resource scopes.Console or Admin API
Policy setMakes the final allow, deny, or step-up decision.Rego policy versions
MandateCarries approved authority as a short-lived signed JWT.STS
Gateway or connectorVerifies mandate claims and revocation before use.Runtime and resource server config
Audit ledgerRecords decisions, diagnostics, and request correlation.API, Console, and storage

Caracal should be treated as deny-by-default:

  1. A resource must be registered.
  2. A principal must have an applicable grant or delegation path.
  3. The active policy set must allow the requested resource and scopes.
  4. The resource server must verify the mandate and revocation anchors.

Missing configuration, invalid signatures, expired mandates, insufficient scopes, revoked sessions, and failed delegation checks all stop the request.

Use the Gateway when you want Caracal to front an HTTP upstream and mediate requests centrally. Use a connector when the resource server should verify mandates inside its own framework, such as Express, FastMCP, net/http, or MCP transport.

Both patterns share the same authority model. The difference is only where mandate verification runs.

The SDK exposes several call paths. They are not interchangeable: each does a different job, and only some enforce authority. Pick by what you need at that boundary.

Call pathRoleVerifies the mandate?Use when
caracal.fetch / gateway_request through the GatewayEnforceYes — the Gateway verifies claims and revocation before forwardingCaracal fronts an HTTP upstream and mediates centrally
Direct Gateway call (curl to the Gateway URL)EnforceYes — same Gateway verificationNon-SDK clients or debugging the enforced path
Connector verify (context_middleware(verifier=…), Express, FastMCP, net/http, MCP transport)EnforceYes — the connector verifies inside the resource serverThe resource server should enforce in its own framework
caracal.transport / context_middleware() (no verifier)PropagateNo — carries and binds the envelope onlyA Gateway or connector already enforced upstream and you only need context to flow
App-managed provider call (your code calls the provider SDK directly)AttributeNo — Caracal records who acted, but does not gate the callYou want audit attribution without routing through the Gateway

Rule of thumb: use the Gateway or a connector verifier to enforce; use transport/propagation to carry identity after enforcement; treat app-managed provider calls as attribution only. If a path says “no” under verifies the mandate, something upstream must have already enforced it.

Read Zones to understand the tenant boundary that owns authority data.