Repository navigation
feat(agent): back up the agent CA keys in the database, under a passphrase - #192
Merged
Merged
Conversation
…hrase A reinstall that lost pki/ stopped setup with E_AGENT_ROOT_MISSING, and the only ways out were a file backup or --new-agent-root (every agent re-enrolls). Now a database backup plus one passphrase restores the CA. - AgentCaEscrow: the four CA files (root and agent CA, key and cert), encrypted with AES-256-GCM under a scrypt key (N 2^17, r 8, p 1). The fingerprints are the AAD. No route returns the record (403). - Passphrase: 6 words from the EFF large wordlist (vendored), or a supplied one of 20+ characters. Shown once, never stored or logged. Answers mode never generates one. - setupPki saves the backup, replaces a stale one, and restores from it when pki/ has no root. A restore needs the recorded root and the recorded agent CA (new Setting FOG_AGENT_CA_FINGERPRINT), so an old backup cannot cut off agents enrolled since. - npm run agent-ca -- backup | restore | status, for an existing install. - Audit rows of type agent.ca (authSource setup) for save, restore and each wrong passphrase. - Fix: setup now drops the old config/local.js from the require cache after it reads it, so later steps load the file it writes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Nov 10, 2026
…cond boundary The test counted exactly one stamped server.pem. The first ensure in the test can already stamp the fixture's pair, and two stamps in the same second share a name, so the count was 1 or 2 depending on the clock. It failed the merge queue for #192 on Node 26. It now checks that the certificate changed and that an old pair was kept aside. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem
The fog-agent CA keys lived only in
pki/. A reinstall that lost the folder stopped setup with E_AGENT_ROOT_MISSING. The only ways out were a file backup or--new-agent-root, which forces every enrolled agent to re-enroll.Change
AgentCaEscrow,api/lib/agent-ca-escrow.js):root.key,root.pem,agent-ca.key,agent-ca.pem, encrypted with AES-256-GCM. The key comes from scrypt (N 2^17, r 8, p 1, maxmem 256 MiB). The two fingerprints are the AAD.openchecks version, KDF bounds, iv and tag length before scrypt runs. No route returns the record (GET /api/v1/agentcaescrowis 403).tools/setup/pki.js): saves the backup, replaces a stale one, and restores from it whenpki/has no root. A restore requires the backup's root and agent CA to match the recorded ones (new SettingFOG_AGENT_CA_FINGERPRINT), so an old backup cannot cut off agents enrolled since. E_AGENT_ROOT_MISMATCH never restores.npm run agent-ca -- backup | restore | statusfor an existing install. Restore refuses every bad state before it asks for the passphrase.agent.ca, authSourcesetup, for save, restore, and each wrong passphrase (ADR 0003 updated).config/local.jsran its later steps on the old file. It now reads the old file once and drops it.api/controllers/agent/,api/hooks/agent-tls/, or the agent routes.Test
npm test: 484 passing. Newtest/lib/agent-ca-escrow.test.jsandtest/setup/pki-escrow.test.js: round-trip, wrong passphrase, every tamper case, KDF bounds, refusals without a prompt, one denied row per wrong try, no passphrase in audit text.npm run test:install: the smoke test now uses its own PKI folder, empties it, re-runs the installer, checks the root is restored with the same fingerprint, and checks the installer output holds no passphrase.npm run setup(they need a terminal), as for the other installer prompts.🤖 Generated with Claude Code