Skip to content

Remits

A remit is the signed capability set a run carries. The control plane issues it before the run starts, the gateway verifies it on every tool call, and nothing in a prompt can widen it. It is the most important decision in Kernos: every prompt-injection defence that relies on the model behaving well eventually fails, and a capability check does not care what the model was persuaded to attempt.

What a remit names

Field Meaning
tools The tool identifiers the run may call, as exact ids or connector.* patterns
scopes The data it may touch: sql:table:invoices, http:host:api.example, fs:path:/exports, with a trailing * for prefixes
grants Data classes the run may see un-redacted, such as pii
spend A ceiling in tokens and currency, enforced by the kernel's budget
autonomy observe, propose, supervised or autonomous
exp An expiry. Remits are short-lived by design
policy_set The policies that gate this run's actions
requested_by The person the run acts for, with role and manager, for approvals

The token is krt1.<payload>.<signature>.<key id>, Ed25519-signed by the control plane. The gateway fetches the public key once and verifies every call locally, so a compromised worker cannot mint a remit and a persuaded model cannot claim one.

Scope comes from the arguments

A remit lists scopes; a call does not declare which scope it is using. The connector derives the scope from the call's arguments (the tables a statement touches, the host in a URL, the directory of a path) and the gateway checks the derived scope against the remit. A model that asks to read customers when the remit says invoices is refused, whatever it says about itself.

Autonomy is enforced twice

The gateway enforces the mechanical part: an observe or propose remit cannot call any tool that writes. Policy enforces the judgement part: the reference policies require approval for writes under supervised, and the default rule requires approval for any write to a system of record unless the remit is autonomous.

Delegation narrows, never widens

A run may spawn sub-runs, and a sub-run gets a child remit derived from the parent. Every field must be a subset: each child tool pattern must be matched by a parent pattern, scopes and grants must be subsets, spend and expiry less or equal, autonomy no higher, and the policy set may only grow. A request that widens any field is refused with the field named. There is no other path to a child remit, so fan-out cannot escalate privilege.

Refusals are events

A call outside the remit is refused at the boundary with a stable reason (tool_not_in_remit, scope_not_granted, autonomy_too_low, remit_expired, signature_invalid, remit_run_mismatch) and the gateway records a tool.refused event on the run. Refusals are counted in metrics and are alertable like any other signal: a run that keeps trying to leave its remit is worth a look, and the log says exactly what it tried.

See the remit token reference for the exact payload, verification order and narrowing rules.