Desired state and convergence
Understand what desired state means for a governed agent: the controlplane publishes a scoped policy snapshot, the enclave pulls it and enforces it locally, and every change takes effect on the next pull without restarting anything.
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: 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:
- 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.
- 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.
- 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 codedefault_denyin 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.