
## Desired state for a governed agent

The controlplane holds governance policy as *desired state*: a description of
what agents should be allowed to reach and how they should be governed. It
never pushes that state into the customer's cluster. The enclave pulls a
snapshot of it, enforces it locally, and re-pulls when the state changes. This
is the downward half of the plane boundary described in
[The plane boundary](/concepts/the-plane-boundary/): platform-owned metadata
flows down, sovereign data never flows up.

The snapshot is a versioned JSON document. It carries a monotonically
increasing `version`, the `enclave_id` and `org_id` that it is scoped for,
and every
setting that governs the enclave's agents. An enclave serves exactly one org,
so the controlplane builds a per-enclave snapshot: the platform floor plus only
that org's settings. Another org's policy never lands in your enclave.

Settings are authored at four scopes, from broad to specific: platform, org,
group, and agent. A more-specific scope overrides a broader one, unless the
broader scope locks the setting. A lock pins the value for everything below it.
The authoring command refuses a lock at agent scope: agents never lock.

## How the enclave pulls it

A `dvx policy-pull` sidecar runs next to the gateway. In the in-repo deployment
(`deploy/enclave/gateway-daemonset.yaml`) it pulls from the broker, the
enclave's sole controlplane egress, which relays to the controlplane. The
sidecar authenticates with the broker-issued client certificate and writes the
snapshot to a shared volume that the gateway reads.

The pull follows one pattern:

1. A boot pull at startup. If it fails and a cached snapshot exists, the
   sidecar serves the cache. If no cache exists, startup fails, because a
   component must not run without the policy it is supposed to enforce.
2. A held-open event stream (server-sent events) from the controlplane. Only a
   nudge crosses the stream; the sidecar re-pulls the snapshot over the
   authenticated endpoint on each nudge.
3. A fallback pull every `--interval` (default 30s), so the enclave still
   refreshes when the stream is down. The stream reconnects with a backoff that
   doubles up to 30 seconds.

Two safeguards apply to every pulled snapshot. The sidecar validates it before
writing: the sidecar rejects a snapshot that is stamped for a different enclave
id, so a
misrouted response never reaches the gateway. The write is atomic (temp file
plus rename), so the gateway never reads a half-written file. And when a pull
fails, the sidecar keeps the last-known snapshot. A controlplane outage never
leaves the gateway ungoverned.

## How the gateway consumes it

The gateway hot-reloads the snapshot file, polling it every 5 seconds. A read
or parse error keeps the last good snapshot in force. The gateway refuses to
start without an initial snapshot, and until a snapshot is loaded it denies
egress with the reason `no_policy`: total mediation must not permit traffic that
it cannot govern. A `wait-for-policy` init container blocks the gateway until the
sidecar has written the first snapshot.

Convergence is then local. The gateway resolves every decision against the
snapshot in memory. The controlplane is not on the data path, and a controlplane
outage never stalls enforcement.

## What a decision means

For each egress request the gateway resolves the scope chain for the agent and
composes a decision:

- Deny rules union across every scope. A lower scope can add denies and can
  never remove one.
- Allow rules resolve by lock-aware most-specific-wins: the broadest locked
  scope pins the allow surface; otherwise the most-specific scope that set an
  allow wins.
- Deny beats allow, and a destination matching no allow rule is denied by
  default (`default_deny`). The reason code `default_deny` in the audit record
  means no rule matched.

An absent key is fail-closed, never permissive. An agent with no destination
settings at any scope falls to `default_deny`. No scope sets a scalar key. The
enforcing component then applies its own safe default. A snapshot that the
gateway cannot load is not treated as "allow everything": it is
either the last good snapshot or `no_policy`.

Packs, the reusable rule bundles installed at org, group, or agent scope, add
allows and denies by union on top of this resolution. A pack installed below a
locked scope cannot broaden the pinned allow surface.

## What convergence means in practice

Publishing bumps the snapshot version, so a reader can always tell which copy
it holds. When an operator authors or edits policy, the controlplane re-publishes
and the sidecar re-pulls, typically within moments of the change because of the
SSE nudge. The gateway picks up the new file on its next 5-second poll. No
gateway, sidecar, pod, or agent restarts, and in-flight connections continue
under the rules that governed them when they were opened. If you want to read
the mechanics end to end, see
[Author and pull policy](/guides/author-and-pull-policy/).
