Last updated: September 25, 2026

Security and Trust Model

The design goal is that compromising the control plane is not the same as compromising a host. Below: who holds which key, what each can and cannot do, what a host checks, and which attacks are tested — including the ones that are not yet.

Can a compromised control plane take over hosts?

In Decentralized.Host a host pins the cluster root key and checks every assignment against 18 ordered checks before running it, so a control plane holding a valid member key still cannot make a host run work its policy refuses. Fuzzing and an external security review have not been done yet.

Source: docs/trust-model.md

Keys

KeyHeld byCanCannot
Cluster rootoperator, offlinesign rosters, delegate to members, create invites, sign root rotations, grant federation, attest artifactsrun anything on a host whose policy refuses it
Member keyeach control-plane membersign bundles and assignments within its root delegationenlarge the roster, change host policy, roll a host back, issue work for a revoked host
Host keyeach hostsign enrollment, observations, wg-binding, storage evidence, its own ledgerspeak for another host; its signed seq cannot be replayed
Session capabilityoperator browser or CLIact as api.read / api.write / api.admin until it expiresexceed the caveats of any block in its chain

What a host checks before it runs anything

  1. The bundle chains to the pinned root — the root from its join token, or from a rotation that root signed.
  2. The bundle signer is in the root-signed roster, and its state index is not older than one already accepted.
  3. The assignment is signed by a roster member, names this host, and has a generation at least as high as any already admitted.
  4. The capability chain authorizes this assignment, host, generation, artifact digest and resources, down from the root.
  5. Its own policy.yaml: tiers, runtimes, digest pinning, publisher attestation, federated work, caps.
  6. The artifact bytes hash to the assigned digest.

If any check fails, nothing new starts; if the same generation is already running it is held, not stopped. Every decision goes into the host's own hash-chained ledger. In total the host evaluates 18 ordered checks (spec §9.3), shown per replica by dh describe app.

Failure and attack cases

CaseOutcomeTested by
Control plane down or partitionedoffline-hold: admitted work continues, new work refused, observations queuedchaos cp-total-outage, network-partition; M1
Compromised member (valid member key)can only sign within its delegation; every host still applies its own policy; rollbacks and impostor keys refusedpkg/node/sovereignty_test.go
Replayed, forged or tampered observationrejected with a specific reason; state unchangedchaos replay-forgery; M1
Stolen host key`dh node revoke-key` revokes that keyM3
Revoked hostcut from mesh and routing, replicas rescheduled, new admission blockedchaos revoked-host; M3
Host clock skewCLOCK_SKEW detected from bundle timestamps; admitted work heldchaos clock-skew
Host ledger tamperingLEDGER_CORRUPT; no appends to the broken chain; operator seal recovers with the break recordedchaos journal-corruption
Audit ledger truncation or rewritedetected offline by hash chain and signed checkpointspkg/audit; M1
Storage corruptionBLAKE3 verification on read; quarantine; repair from peers with evidenceM2; chaos storage-replica-loss, disk-full
Network observerTLS on member APIs from first start, pinned bootstrap, mutual-TLS Raft, WireGuard between hoststls_test.go; M7

Security tests

Signature tampering
M1; chaos replay-forgery; conformance verify/tampered-payload
VERIFIED
Wrong key
M1; conformance key-substitution, key-not-allowed
VERIFIED
Replay
M1; chaos replay-forgery
VERIFIED
Generation rollback
sovereignty_test.go; chaos stale-generation
VERIFIED
Revocation
M1, M3; chaos revoked-host
VERIFIED
Forged shell or command
exec is policy-gated (allowExec); commands are argv, never a shell
VERIFIED
Audit tampering
pkg/audit; 14 conformance vectors; dh audit verify
VERIFIED
Compromised control plane (valid member key)
sovereignty_test.go
VERIFIED
Canonicalization attacks
42 canon vectors: duplicate keys, lone surrogates, invalid UTF-8, floats, BOM
VERIFIED
Transport interception
tls_test.go: plain HTTP refused, certificates verify against the root, bootstrap pinned
VERIFIED
Fuzzing
planned (P0-8)
NOT RUN
External security review
planned (P0-8)
NOT RUN

Deliberate limits

  • › The root key is the single anchor. Rotation is supported, but a stolen root can sign a rotation — keep it offline.
  • › A member with a valid delegation can sign harmful-but-permitted work (for example, scaling an app to zero). Host policy bounds what runs; it cannot judge intent. Use `dh freeze` if you suspect compromise.
  • › The process runtime does not enforce CPU or memory limits; admission details say so. Use the docker runtime for enforcement.
  • › Session capabilities are bearer tokens. They stay in sessionStorage and the URL fragment, never server logs, and expire.
  • › Root key custody (offline signer or HSM) is not implemented.

Full model: docs/trust-model.md. To report a suspected vulnerability, contact the maintainer privately through github.com/CodesbyFebin rather than opening a public issue.