feat(proof-vm-agent): boot-check TLS SANs for the dedicated droplet, cert helper (Architecte follow-up 2/4) - #249
Closed
echobt wants to merge 1 commit into
Conversation
The agent certificate must carry a SAN for every host the control plane's PROOF_VM_ORCHESTRATOR_URL may name (the dedicated droplet's VPC IP, its hostname) - staging shipped a certificate for the docker gateway only and the CP's rustls client refused everything else. New PROOF_VM_AGENT_TLS_SANS (default: a specific bind address; required with a wildcard bind) is checked against the certificate at boot with webpki (the CP's own validator); a missing SAN exits 1 naming the host, what the cert presents, and the fix. deploy/scripts/proof-vm-agent-tls.sh mints CA + leaf from the same names (--san, env, bind host, hostname -f, VPC IPv4 on eth1) and can write the env line; the wire check translates curl SAN / chain refusals into that command. Placement wording everywhere: production is a dedicated g-8vcpu-32gb droplet on the VPC (nested KVM, no DO bare metal), never the CP droplet.
5 tasks
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Architecte / Owner follow-up 2 of 4 (TLS SAN — hostname / VPC IP of the dedicated droplet). Stacked on #248 (same file,
bins/proof-vm-orchestrator/src/main.rs); base retargets tomainonce #248 merges. Placement per the Owner lock: prod is a dedicated DO dropletg-8vcpu-32gbnyc1 on the VPC with nested/dev/kvm— not DO bare metal — never the CP droplet.Problem. The CP's rustls client (
proof-vm-fc) refuses a certificate without a SAN for the host inPROOF_VM_ORCHESTRATOR_URL. Staging minted a certificate for the docker gateway (172.18.0.1, what a colocated CP container reaches). That is worthless on the dedicated prod droplet, where the CP arrives on the VPC address / a hostname — and nothing in the repo generated certificates or checked them.Agent (
bins/proof-vm-orchestrator)--tls-sans/PROOF_VM_AGENT_TLS_SANS(comma-separated DNS names / IPs): every host the CP's URL may name for this agent. Default: the bind address whenPROOF_VM_AGENT_BINDis a specific IP; required with a wildcard bind (0.0.0.0/[::]say nothing about the host clients use — no default, no docker-gateway guess).webpki::EndEntityCert::verify_is_valid_for_subject_name, already in the graph via rustls): the leaf must be valid for every listed name. A miss exits 1:tls cert … has no SAN for 10.116.0.7 (it presents […]); the control plane's rustls client refuses it — regenerate with deploy/scripts/proof-vm-agent-tls.sh --san 10.116.0.7 (CN alone is never a name). Success logslistening (https); certificate covers every listed namewithtls_sans.Helper (
deploy/scripts/proof-vm-agent-tls.sh, openssl only, runs on the KVM host) — mintsca.pem/ca.key(once; reused after,--forcere-mints) andtls.crt/tls.keyunder/etc/proof-vmwithsubjectAltName= union of--san …,PROOF_VM_AGENT_TLS_SANSand a specificPROOF_VM_AGENT_BINDhost from the env file,hostname -f(--no-hostname/--hostname NAME), and the first IPv4 on--vpc-iface(defaulteth1, DO's VPC NIC;--no-vpc).--write-envrecords exactly the minted names asPROOF_VM_AGENT_TLS_SANS;--dry-runlists. Refuses an empty list; warns when every SAN is a docker bridge address (172.17–31.x — colocated staging only). Keys 0400, certs 0644,openssl verifybefore install.Wire check —
proof-vm-wire-check.sh agenttranslates curl's SAN / chain refusals into the exact fix (proof-vm-agent-tls.sh --san <url host>, or copyca.pemto the CP).Docs / env — runbook § TLS (knob, boot check, helper, staging colo vs dedicated droplet), § Install / § 1 / § sign-off updated; env examples (
PROOF_VM_AGENT_TLS_SANS), systemd unit comment; placement wording aligned to the Owner lock inAGENTS.mditem 7,deploy/AGENTS.md,docs/PROOF.md,docs/ARCHITECTURE.md,docs/COMPLETENESS.md, module docs ("dedicated DO metal preferred" → "dedicatedg-8vcpu-32gbdroplet, nested KVM, never the CP").Fail-closed, minimal wire impact: no protocol change, no CP change; a host whose certificate does not cover its listed names stops at boot instead of serving a certificate the CP refuses.
How to verify
On the dedicated droplet:
deploy/scripts/proof-vm-agent-tls.sh --write-env(VPC IP autodetected on eth1 + hostname), restart the agent, copyca.pemto the CP,proof-vm-wire-check.sh agent && … cp.Greptile
@greptileai reviewTest plan
cargo test --workspacecargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warnings,cargo deny check, xtaskloc-cap/consensus-lint/spec-check/design-check/external-docs-check(compose-matrix assertion needs docker; not touched)openssl verifyOK), boot check refused wildcard-without-list / missing SAN / CN-only and accepted the listed names;proof-vm-wire-check.shtest suite green with the newagentmessagesRisk
Deploy only (host agent + operator script + docs). Operator action on upgrade: a wildcard
PROOF_VM_AGENT_BINDnow needsPROOF_VM_AGENT_TLS_SANS, and the certificate must cover those names — the agent exits 1 with the exact fix otherwise (that is the intended fail-closed behaviour; staging colo keeps working by listing the gateway address it already serves). No miner CVM measurement, signature domain, or emission impact.Naming
I did not rename
BASE_*environment variables, deployed host paths(
/opt/base,/run/base, …), GHCRbaseintelligence/basepackage names, orbase-*-v1cryptographic domain tags, unless this PR’s purpose is a coordinatedcutover documented in
docs/NAMING.md.