> ## 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.

# A manager agent delegating bounded authority to a worker

> A manager agent holds a delegable grant, hands a worker a narrower slice for one job, the worker cannot exceed or widen it.

A manager agent plans a job and hands parts of it to worker agents. Each worker should hold
exactly the authority its part needs, for the time the job takes, and nothing the manager
does not itself hold. When the job ends, one revocation should remove every worker's authority
at once.

## The policy

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

authority:
  max_delegation_depth: 3
  grants:
    - id: ops-manager
      subject: { agent: "ops-manager" }
      actions: ["k8s.rollout_restart", "k8s.scale"]
      resources: ["cluster:*"]
      constraints: { replicas_gte: 0, replicas_lte: 50 }
      environments: ["production"]
      delegable: true
      expires_at: "2027-01-01T00:00:00Z"

actions:
  k8s.rollout_restart:
    effect: "restart:{cluster}:{deployment}"
    resource: "cluster:{cluster}"
    decision: allow
  k8s.scale:
    effect: "scale:{cluster}:{deployment}:{replicas}"
    resource: "cluster:{cluster}"
    decision: allow
```

## The code

```python runnable file=main.py theme={null}
from pathlib import Path

from ctrlrun import (
    Action,
    Authority,
    AuthorityDenied,
    AuthorityEscalation,
    Control,
    Policy,
    Principal,
    SQLiteStateStore,
)
from ctrlrun.authority import grant_from_yaml

HERE = Path(__file__).resolve().parent
STATE = HERE / ".ctrlrun"
STATE.mkdir(exist_ok=True)
for name in ("state.db", "state.db-wal", "state.db-shm"):
    (STATE / name).unlink(missing_ok=True)

MANAGER = Principal(agent="ops-manager")
WORKER = Principal(agent="scale-worker")
document = (HERE / "ctrlrun.yaml").read_text(encoding="utf-8")
store = SQLiteStateStore(STATE / "state.db")
control = Control(
    Policy.from_yaml(document, source="ctrlrun.yaml"),
    store,
    authority=Authority.from_yaml(document, source="ctrlrun.yaml"),
    environment="production",
)
scaled: list[tuple[str, int]] = []


def scale(who: Principal, cluster: str, deployment: str, replicas: int) -> None:
    control.execute(
        Action(
            name="k8s.scale",
            arguments={"cluster": cluster, "deployment": deployment, "replicas": replicas},
            principal=who,
            resource=f"cluster:{cluster}",
        ),
        lambda: scaled.append((deployment, replicas)),
        f"scale:{cluster}:{deployment}:{replicas}",
    )


# The worker gets scaling only, on one cluster, up to 10 replicas, for a day.
job = control.delegate(
    "ops-manager",
    grant_from_yaml("""
subject: { agent: "scale-worker" }
actions: ["k8s.scale"]
resources: ["cluster:prod-eu"]
constraints: { replicas_gte: 0, replicas_lte: 10 }
environments: ["production"]
expires_at: "2026-12-01T00:00:00Z"
"""),
    by=MANAGER,
)
print("worker's grant:", job.delegation_id)

scale(WORKER, "prod-eu", "checkout", 6)
print("worker scales checkout to 6 on prod-eu: done")

try:
    scale(WORKER, "prod-eu", "checkout", 40)
except AuthorityDenied as refused:
    print("worker scales to 40: refused,", refused.reason)
else:
    raise SystemExit("the worker exceeded its slice")

try:
    scale(WORKER, "prod-us", "checkout", 6)
except AuthorityDenied as refused:
    print("worker scales on prod-us: refused,", refused.reason)
else:
    raise SystemExit("the worker acted outside its cluster")

try:
    control.delegate(
        "ops-manager",
        grant_from_yaml("""
subject: { agent: "scale-worker" }
actions: ["k8s.scale"]
resources: ["cluster:prod-eu"]
environments: ["production"]
expires_at: "2026-12-01T00:00:00Z"
"""),
        by=MANAGER,
    )
except AuthorityEscalation as refused:
    print("a slice that omits constraints: refused,", refused.reason, refused.dimension)
else:
    raise SystemExit("an omitted dimension was inherited as unlimited")

# The job is over.
control.revoke(job.delegation_id, by="ops-manager")
try:
    scale(WORKER, "prod-eu", "checkout", 4)
except AuthorityDenied as refused:
    print("worker after revocation: refused,", refused.reason)
else:
    raise SystemExit("a revoked worker still acted")

print("scaling calls:", scaled)
store.close()
```

## What the agent sees

```text theme={null}
worker's grant: dlg_…
worker scales checkout to 6 on prod-eu: done
worker scales to 40: refused, authority_constraint
worker scales on prod-us: refused, no_authority
a slice that omits constraints: refused, containment constraints
worker after revocation: refused, authority_revoked
scaling calls: [('checkout', 6)]
```

Omitting `constraints:` in the second delegation was refused, not inherited: a slice that
names no replica limit would have authorized what the manager's own grant caps.

## The receipt

```bash runnable theme={null}
ctrlrun receipts --last 2
```

Every refusal is an `AUTHORITY_DENIED` event naming the grant it failed against; the delegation
and the revocation are `DELEGATION_CREATED` and `DELEGATION_REVOKED`, with who did each.

## When an AMBIGUOUS appears

A scale call that timed out may have applied. Read the deployment's replica count, then
`ctrlrun resolve scale:prod-eu:checkout:6 --committed` or `--failed`. A worker whose grant has
since been revoked cannot retry either way; the resolution is the manager's or a human's.

## Next

* [A payout agent with maker/checker](/cookbook/payout-maker-checker).
* [Authority and delegation](/concepts/authority-and-delegation) · [Get started](/get-started/quickstart) · [Why](/why).


## Related topics

- [Cookbook](/cookbook/index.md)
- [A payout agent with maker/checker via delegation](/cookbook/payout-maker-checker.md)
- [Threat model](/THREAT_MODEL.md)
- [A customer-notification agent](/cookbook/customer-notification-agent.md)
- [Authority](/reference/api/Authority.md)
