Skip to content

Policy engine

Policy operates at two layers. The runtime policy in policy.toml controls caller identity → role → capability mapping — who may call the gateway and with what ceiling. On top of that, each registered agent is governed by a layered policy chain (org ceiling → zone ceiling → agent leaf), covered below.

Edit policy.toml to change runtime policy behaviour without recompiling.

The role used when no token is provided — or the token maps to no role — is set by default_role:

# Production posture: unauthenticated callers get nothing.
default_role = "deny_all"

deny_all is a built-in role; no [roles.deny_all] entry is required. Setting the default to admin is for development only and emits a startup warning.

[tokens]
"stratus-dev-token-change-me" = "admin"
"console-bff-token" = "console_operator"
# Regulated profiles
"fintech-teller-token" = "fintech_teller"
"fintech-manager-token" = "fintech_manager"
"regulator-token" = "regulator" # read-only ledger access

Callers present the token as Authorization: Bearer <token> or X-Imara-Token.

A role is a capability ceiling. Anything not listed is blocked and written to the ledger:

[roles.admin]
capabilities = [
"CAP_VFS_READ",
"CAP_VFS_WRITE",
"CAP_VFS_DELETE",
"CAP_VFS_SEARCH",
"CAP_NETWORK",
"CAP_SUBAGENTS",
"CAP_MESSAGING_OUT",
"CAP_X402_OUT",
"CAP_PAYMENTS_OUT",
"CAP_PAYMENT_APPROVE",
]

Capabilities are deliberately narrow. For example, CAP_PAYMENT_APPROVE lets a role answer a payment escalation but grants no ability to spend — which is why an operator role can hold it while still denying ACTION_PAYMENT_INITIATE.

Registered agents carry a second, layered policy resolution — structured like IAM:

  • an org ceiling caps everything in the organisation,
  • a zone ceiling caps the department,
  • each agent carries a compiled leaf derived from its own grant.

A request must clear all three. Starter templates render the ceiling documents from a handful of parameters; the results are ordinary, editable policy documents, content-addressed by hash:

Method Path Description
GET /v1/policy-templates Browse the template catalog
POST /v1/policy-templates/{id}/apply Render + attach org and zone ceilings (dry_run: true previews without saving)
GET /v1/agents/{id}/policy-chain The effective chain governing one agent, with document hashes

The chain endpoint returns the same resolution the enforcement gate performs, so “denied by policy” is always inspectable by hash. Re-applying a template with identical parameters is harmless — content addressing re-attaches the same hashes. See the integration guide for a worked example.

Policy mutations are control-plane operations gated by [admin]:

Method Path Description
GET /admin/policy Current snapshot (roles, tokens, default role)
POST/DELETE /admin/policy/roles · /admin/policy/tokens Manage roles and token mappings
POST /v1/policies/evaluate Dry-run a policy document against a hypothetical action
POST /admin/policy/observe Observation mode: record freely, then…
GET /admin/policy/build/{sessionID} …synthesise a least-privilege role from the trace

Observation mode is the fastest path to least privilege: run the agent against a permissive role while the kernel records what it actually does, then build a role containing exactly those capabilities.