Sealed, Delegated, Deployable — DGV After v0.4.0
Encrypted agent-to-agent transport, tokens that can only narrow, and a deployment posture check that passed on real Postgres + RS256
Sealed, Delegated, Deployable — DGV After v0.4.0
Update: the gate is now genuinely publicly deployed — real host, DNS, TLS, and OIDC issuer — with the T0/T1 revocation proof and delegation cascade re-run externally against it. See the follow-up note. The "not yet publicly deployed" line below no longer stands.
Two capabilities have shipped since the v0.4.0 gate update, plus the deployment surface that turns the gate from "runs on our machines" into "runs where a client's auditors can reach it." As before: every claim below is a test you can run, and the non-claims are listed plainly at the end.
Sealed agent-to-agent transport (dgv-sealed-v1)
The v0.4.0 gate authorized A2A envelopes but left payload encryption to the agents. That gap is now closed — properly, not by trusting the transport.
The flow. Agents register two keys at the gate: an Ed25519 signing key and an X25519 encryption key, both admin-provisioned. A sender resolves the recipient's encryption key from the gate's public registry (GET /agents/keys/:agent_id) — never in-band, which blocks key-substitution MITM by construction. ECDH produces a shared secret; a per-message KDF (SHA3-256, mirroring libonlystate) derives the ChaCha20-Poly1305 key; the ciphertext travels a zero-knowledge relay (onlystate-relay) under a deterministic queue id.
The binding. POST /a2a/send carries payload_hash — SHA-256 of the ciphertext. The gate authorizes the delivery of one specific sealed payload. A ciphertext swapped in transit decrypts (same key) but fails the hash check, so it is never acknowledged. The relay stores and serves opaque bytes; the gate authorizes without seeing plaintext or ciphertext.
Receipts on every hop. The sender gets a gate-signed delivery receipt; the recipient verifies sender key, hash, and AEAD before acking. Authorization metadata (sender, recipient, expiry) stays visible to the gate — that is a stated limit, not a hidden one.
15 tests against a live gate plus a live relay binary: ECDH roundtrip, full delivery (~40–70 ms same host), ciphertext-swap detection, AEAD tamper, wrong-recipient, forged signature, revoked sender, legacy unsealed envelopes, zero plaintext on the wire.
Token delegation (dgv-delegate-v1)
An agent holding a live token can now mint child tokens for other agents — and authority can only ever decay along the chain. This is the honest version of self-organizing multi-agent work.
The invariants, enforced at the gate:
- Same tool and action — no cross-tool scope creep
- Parameters must be a JSON subset of the parent's — keys may be dropped, never added or changed; array elements must come from the parent's array
- Expiry no later than the parent's;
min_approvalsinherited — a child cannot launder away an approval requirement - Depth bounded (
DGV_MAX_DELEGATION_DEPTH, default 3); the parent must be live and unconsumed - The delegator must be the parent's grantee, proven by an Ed25519 signature over the delegation record using its registered key
The cascade. /execute walks the ancestor chain: revoke the orchestrator and every delegated token dies at T₁ — delegated_authority_revoked. One revocation is the orchestration kill switch.
A binding that did not exist. While building this we found tokens were not bound to a proposer — any verified executor could consume any token. Now executor_id must equal token.granted_to (legacy rows grandfathered). GET /delegations/:token_id walks the lineage root-to-leaf; every hop stores a DelegationRecord plus a DecisionRecord, so the chain is auditable evidence, not a log line.
17 tests: a 3-deep chain minted and executed, depth-4 denied, widened params / added keys / foreign array elements / over-expiry all denied, forged delegator signature denied, non-grantee delegator denied, wrong executor denied, ancestor revocation kills a depth-3 child.
The CRM evidence surface
Governance receipts were already landing in Minuta's audit stream — now they are inspectable as a feature. Settings → Governance lists every governed call: the tool, the principal, the outcome (including governance_denied and execution_denied — denials are evidence too), the run id, and the decision hash. A per-row Verify action re-asks the gate's /verify/:run_id and confirms the stored hash matches the receipt the tool carried. The query path was validated against a real Postgres instance, not just typechecked.
Deployment posture — verified, not yet public
The deployment bundle is real: nginx.conf (TLS 1.2/1.3, HSTS, SSE-aware), docker-compose.gate.yml (loopback-bound ports, required secrets enforced at compose-parse time), DEPLOYMENT.md, and deploy-check.sh — a posture validator that fails a running gate unless JWT verification, admin auth, fail-closed partition policy, storage connectivity, and unauthenticated-request rejection all hold.
We ran it against a production-posture instance — real Postgres storage, RS256 JWT with a pinned public key, admin key, fail-closed: all checks pass. Forged tokens, missing tokens, and malformed requests are denied with signed DENY receipts. A misconfigured OIDC issuer now fails startup rather than silently disabling identity verification — a bug we found and fixed while writing the runbook.
What this does not establish: a public host, DNS, real certificates, and a real OIDC issuer. The artifacts are ready; nothing is publicly deployed. deploy-check.sh is the proof gate for that step — a deployment that fails it is not production, whatever the runbook says.
What this does not establish
- No post-quantum A2A crypto and no forward secrecy. Static-static X25519 ECDH; libonlystate's WOTS+ exists but is not wired into this path.
- Deterministic queue ids are dictionary-guessable — queue existence is not a secret; payload confidentiality does not depend on it.
- No traffic-analysis resistance. The gate necessarily sees sender→recipient metadata.
- Delegation is attenuation, not scope composition. No cross-tool grants, no parametric bounds — richer policy semantics are future work.
- No consensus protocol and no third-party audit. Same as v0.4.0 — gossip is authenticated propagation; independent certification remains required.
- Not publicly deployed. Verified production posture on our machines; a public endpoint is pending host, DNS, certs, and a real OIDC issuer.
Where to look
A2A_TRANSPORT.md— the sealed-transport spec and threat modeltest_a2a_transport.py— 15 live checks against gate + relaytest_delegation.py— 17 checks on decay, depth, and cascade revocationDEPLOYMENT.md+deploy-check.sh— the runbook and the posture proofopenapi.yaml— 27 endpoints, every schema
The next milestones remain: public deployment, consensus-grade revocation, and an independent third-party audit. Evidence, not adjectives.
Published by Only Institute