Per-target capability authz + standing grants¶
This is the foundation the rest of the gate model rests on: can principal P do a verb at tier T on box X? It answers capability — the question of whether an actor is allowed to touch a target at all — before any finer policy is considered.
The system is deny-by-default, audited on every allow and every deny, and enforced by one authoritative tier ordering shared across the whole platform.
The tier ordering¶
Every orchestration verb resolves to exactly one class in a single, ordered enum:
- Read — inspect state (status, capture a reply).
- Steer — send a prompt / nudge a running session.
- Spawn — start a Commander or dispatch work.
- Kill — stop or reset a session.
- OperatorOk — the top tier: actions that require an explicit operator OK.
The ordering is a real total order (the enum derives comparison), which is what lets the whole platform compose dispositions by "most-restrictive-wins" arithmetic — the grant model, the per-action policy, and the per-target rule store all speak this one tier axis. A verb maps to its tier through one authoritative function; there is no second, divergent map to drift out of sync.
Two checks: the role floor, then the standing grant¶
Capability is decided in two composed steps.
1. Role floor¶
Every principal has a role, and a role caps the tier it can reach. The role-floor
check (decide_for) refuses any verb above the principal's role ceiling. This is
the always-on baseline — it holds even before per-target grants are in play.
2. Per-(principal, box) standing grant¶
Above the role floor, a standing grant authorizes a specific principal to act at
a specific tier on a specific box. The check (enforce_standing) reads the standing
grants for (principal, box) and refuses when the principal holds no grant on that
box at the verb's tier.
This is the "N boxes, N authorizations" model: a principal that may deploy to box A does not thereby gain any authority on box B. Authorization does not generalize across targets.
Folding multiple grants — most-restrictive-wins¶
When several active grants apply, they are folded together conservatively rather than permissively:
- the effective tier is the minimum of the grants' maximum tiers, and
- the
operator_okflag is AND-ed — every contributing grant must carry it for the fold to.
You cannot stack two narrow grants into a broad one. Folding can only tighten.
Deny-by-default¶
A principal with no matching grant is denied. A verb that does not resolve to a known tier is denied. An unresolved target is denied. The absence of an explicit allow is never read as permission — it is read as refusal. This is the property that makes the whole model safe to extend: a new box, a new verb, or a new principal starts with no capability and must be explicitly granted one.
Dark by default¶
The standing-grant requirement ships behind a flag
(HIVEMIND_ORCH_STANDING_GRANT_REQUIRED) that defaults OFF. With the flag off,
the role floor still applies but per-box standing grants are not yet required; with
it on, the full per-target model engages. This is the dark-launch discipline the
whole Hub follows — a security-tightening capability lands, is reviewed, and is
proven before it is switched on in any live deployment.
The confused-deputy boundary¶
A subtle but load-bearing distinction: the external caller that drives a box (the Hub, or a client of the Hub) is a distinct principal from the Commander the deploy produces. The Commander runs on the box under its own daemon principal and fans out to Managers and Workers with that authority. The external caller does not inherit Commander authority — it must hold its own per-box grants.
"The Hub drives box X" is therefore always a grant-holding external principal acting through the seam, never ambient trust that leaks from the Commander's own privileges. When a session claims a job, the claim seam binds the resolved machine identity so that every later gate can resolve which box the live Commander is on — closing the gap a deputy would otherwise exploit. This is documented further under Security mechanisms → Confused-deputy defense.
Where this sits¶
Capability (this page) is layer L1 of the unified gate. It answers "can P touch box X at all." A separate axis — the operator's per-target rule store — answers "and even when capable, do I want this to happen automatically, ask me, or never?" Keeping capability and preference on separate axes is what makes the gate's composition provably safe: capability is granted in the grant model, never in the rule store, and the rule store can only ever tighten.