> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ctrlrun.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Authority and delegation

> Authority is the second axis: a grant says which principal may propose which action, opt-in and then fail-closed, evaluated before the policy.

Authority answers the question the policy cannot: may *this principal* propose this action at
all? A grant names a subject, the actions, resources and environments it covers, and the
constraints on the arguments. It is opt-in, and then fail-closed: a policy with no `authority:`
section behaves exactly as before, and the moment one exists every principal needs a grant and
no grant means denied.

## Two axes, one action

```yaml runnable theme={null}
schema: ctrlrun.policy/v3

authority:
  grants:
    - id: head-of-support
      subject: { agent: "head-of-support", user: "dana@example.com" }
      actions: ["stripe.refund"]
      resources: ["payment:*"]
      constraints: { amount_gte: 0, amount_lte: 10000000 }   # €0 to €100,000.00
      environments: ["production"]
      delegable: true
      expires_at: "2027-01-01T00:00:00Z"

actions:
  stripe.refund:
    effect: "refund:{payment_id}"
    resource: "payment:{payment_id}"
    rules:
      - when: { amount_gte: 0, amount_lte: 100000 }
        decision: allow
      - when: { amount_gte: 0, amount_lte: 1000000 }
        decision: approve
      - decision: deny
```

A grant carries no `decision:`. How much autonomy `stripe.refund` has is the same for everybody;
what differs is whether they may ask. The two are evaluated separately, authority first, and
combine as the stricter of the pair: a €50,000 refund from the head of support is within the
grant and denied by the policy; a €500 refund from an agent with no grant is allowed by the
policy and denied by authority, before any approval request is written.

## Delegation only narrows

A principal holding a `delegable` grant can hand a slice of it on at runtime with
`ctrlrun delegate`. The delegated grant is valid only if it is provably a subset of its parent
on every dimension, at creation **and again at every evaluation**, so narrowing the parent later
narrows every child. Omitting a dimension the parent constrains is rejected, not inherited: a
child that drops `resources:` would authorize resources its parent never could. `delegable: true`
requires `expires_at`, because authority that can mint more authority and never lapses is the one
shape this model refuses. `ctrlrun revoke` cuts a chain of any depth with one write; every
evaluation walks to the root.

```text theme={null}
human €100,000 delegable  →  finance agent €25,000  →  support agent €2,000
support agent requests €50,000       ✗ outside the delegated grant
finance agent delegates €50,000      ✗ containment: constraints
```

## Identity is consumed, never invented

The principal comes from an identity provider the operator installs: `ctrlrun.context(agent=...)`
for a process that knows who it is, a `HeaderIdentityProvider` behind a proxy that authenticates,
or a `JWTIdentityProvider` that verifies a bearer token against a JWKS or a pinned key and maps
the verified claims onto a principal. CTRLRun issues no credential and defines no identity
format. An expired credential is refused before authority and before policy.

## The guarantee it supports

Authority and delegation: G7 (no principal refused), G8 (expired authority refused) and G9
(delegation cannot escalate, six dimensions) in `ctrlrun verify`.

## What it does not do

Authority does not authenticate the approver, does not propagate across an agent-to-agent hop,
does not match a grant on a token claim, and does not hot-reload the file: revocation and
expiry are live, an edit takes effect when the process next loads it. A `HeaderIdentityProvider`
is worth exactly what the thing setting the header is worth.

## Next

* [Authority YAML reference](/reference/authority-yaml).
* [Decisions](/concepts/decisions): the axis authority sits beside.
* [Authority and delegation, in plain language](/authority) · [Get started](/get-started/quickstart) · [Why](/why).


## Related topics

- [Authority and delegation](/authority.md)
- [Authority YAML reference](/reference/authority-yaml.md)
- [A manager agent delegating bounded authority to a worker](/cookbook/manager-and-worker.md)
- [A payout agent with maker/checker via delegation](/cookbook/payout-maker-checker.md)
- [Decisions](/concepts/decisions.md)
