Skip to content

Zone

A zone is the top-level organizational boundary in Caracal. Everything — applications, resources, policies, grants, sessions, and audit events — belongs to exactly one zone. Zones are independent: a mandate issued in one zone cannot be verified in another, and a policy in one zone has no effect on another.

ItemScoped to zone
ApplicationsYes — each application belongs to one zone
Resources and providersYes
Policies and policy setsYes — one active policy set per zone at a time
GrantsYes
Agent sessionsYes
Audit eventsYes
Signing key pairYes — each zone has its own EC P-256 key pair

A zone is stored with these attributes:

FieldDescription
idUUID; carried in every mandate as zone_id
org_idOrganization identifier (default: "default")
nameHuman-readable label
slugURL-safe identifier (matches /^[a-z0-9-]+$/)
dek_ciphertextThe zone’s data encryption key, encrypted under the KEK
dcr_enabledWhether Dynamic Client Registration is permitted
pkce_requiredWhether PKCE is required for authorization code flows
login_flowAuthentication flow type for this zone

Each zone has its own signing key pair used to sign and verify mandates. This isolation means a compromised key in one zone does not affect others, and keys can be rotated per zone independently.

The key hierarchy has two levels:

ZONE_KEK (environment variable, 32 bytes)
└─ encrypts → zone Data Encryption Key (DEK, stored as dek_ciphertext in DB)
└─ encrypts → zone signing key (EC P-256 private key, stored in secrets table)

ZONE_KEK is a 32-byte hex-encoded key set in the ZONE_KEK environment variable on the STS. It is the root of the key hierarchy. The STS validates on startup that ZONE_KEK is present, is 32 bytes, and is not all zeros.

Zone DEK (dek_ciphertext) is stored in the zones table. The DEK is decrypted by the STS using ChaCha20-Poly1305 with the ZONE_KEK. The decrypted DEK is then used to decrypt the zone’s signing key from the secrets table.

Zone signing key is the EC P-256 private key used to sign mandates. It is stored encrypted under the zone DEK, never in plaintext at rest.

The ZONE_KEK_PROVIDER environment variable controls where the KEK is sourced. The current supported value is "local" (reads from the ZONE_KEK env var). Future values may support external KMS providers.

The STS exposes the zone’s public key(s) for verification:

GET /zones/{zoneId}/.well-known/jwks.json

This endpoint returns up to two recent public keys to support key rotation without breaking in-flight tokens that were signed with the previous key. JWKS responses are cached by the Gateway and SDK connectors, refreshed every 5 minutes.

A zone has exactly one active policy set binding at a time. All token exchanges in the zone are evaluated against the active bundle. A zone with no active binding evaluates with the deny-all fallback.

Policy set activations are propagated to the STS immediately through the caracal.policy.invalidate Redis stream, which triggers a bundle reload for the zone.

Two zones running on the same stack are as independent as two separate deployments. They share PostgreSQL and Redis infrastructure but maintain separate:

  • Signing keys (mandates can only be verified by the issuing zone’s JWKS)
  • Policy sets (an activation in zone A does not affect zone B)
  • Session namespaces (agent sessions are keyed by zone_id)
  • Audit ledgers (audit events carry zone_id and are queryable per zone)

A mandate issued by zone A carries zone_id = "zone-A" in its claims. The Gateway verifies the token against the JWKS of the zone specified in the token — a token for zone A cannot be verified against zone B’s JWKS.

Use separate zones when you need:

  • Different policy sets for different environments (staging vs production)
  • Different signing keys for different teams or services
  • Audit segregation by organizational unit
  • Independent key rotation schedules

A single zone is sufficient for most deployments where all services share the same policies and trust boundary.

  • Resource and Grant — resources and grants within a zone
  • Policy — activating a policy set in a zone
  • Mandate — how zone signing keys produce mandates