controller v0.195.0: prove the offsite key comes back (R-200 plumbing half) -- MinAgent 0.125.0
gates / gates (push) Successful in 10s
gates / gates (push) Successful in 10s
--recover-offsite-check is a docker exec diagnostic in the shape of --print-reset-code: it reads the customer's recovery code from STDIN, asks the agent to fetch this host's sealed bundle and open it, and reports whether the recovered key matches the one on disk BY SHA256. Two hashes and a verdict; never a password, never R, never a blob. R comes from stdin and not a flag because a flag value is visible in ps, in shell history, in a container's command line and in any transcript of the session that ran it. IT COMPARES; IT DOES NOT INSTALL. The recovered password is never written to offbox/repo_password -- installing changes a live box on a path nobody has walked, and that link is next session's, with the drill around it. A test asserts the data dir is byte-unchanged after a check; its red-proof (adding the install call) fails it. Exit codes: 0 match, 2 clean MISMATCH, 1 a step failed -- "it failed" and "it worked and disagreed" must never share a status. A box with no local password reports distinctly: that is the rebuilt-box shape, where the next step is to install rather than compare. Nothing customer-reachable ships here: no card, no form, no preview.
This commit is contained in:
@@ -75,6 +75,7 @@ func main() {
|
||||
showVersion := flag.Bool("version", false, "Show version and exit")
|
||||
printResetCode := flag.Bool("print-reset-code", false, "Customer-claim escape hatch (v0.122.0, F-4): print a fresh one-time local claim/reset code to stdout, then exit. Root-gated by reachability (docker exec). Same gate consumes it.")
|
||||
printInfraImages := flag.Bool("print-infra-images", false, "Print every controller-managed infra image (one per line) and exit. Read by the golden bake (felhom-agent configs/build-golden.sh) so the appliance image pre-pulls exactly what THIS controller version will request.")
|
||||
recoverOffsiteCheck := flag.Bool("recover-offsite-check", false, "R-200 diagnostic: read the customer recovery code from STDIN, recover the offsite repository password from the hub-held sealed escrow via the agent, and report whether it matches the one on disk — BY HASH. Compares, never installs; writes nothing. Exit 0 = match, 2 = clean mismatch, 1 = a step failed.")
|
||||
flag.Parse()
|
||||
|
||||
if *showVersion {
|
||||
@@ -91,6 +92,35 @@ func main() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// R-200 (v0.195.0) — the offsite-key recovery check. A `docker exec` escape hatch in the shape of
|
||||
// --print-reset-code above, and deliberately NOT a page or a browser-reachable API: the
|
||||
// customer-facing flow is designed on top of a chain that has been walked, and this is the walk.
|
||||
// R arrives on STDIN so it never appears in argv, `ps`, shell history or a session transcript.
|
||||
if *recoverOffsiteCheck {
|
||||
cfg, err := config.LoadPermissive(*configPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "recover-offsite-check: loading config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
sett, err := settings.Load(cfg.Paths.DataDir+"/settings.json", log.New(os.Stderr, "", 0))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "recover-offsite-check: loading settings: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
ac, err := agentapi.New(cfg.LocalAPI.Endpoint, cfg.LocalAPI.Token, cfg.LocalAPI.Fingerprint)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "recover-offsite-check: agent channel: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(backup.RunRecoveryCheck(backup.RecoveryCheckDeps{
|
||||
Manager: backup.NewManager(cfg, sett, log.New(os.Stderr, "", 0)),
|
||||
Recoverer: ac,
|
||||
In: os.Stdin,
|
||||
Out: os.Stdout,
|
||||
Err: os.Stderr,
|
||||
}))
|
||||
}
|
||||
|
||||
if *printResetCode {
|
||||
cfg, err := config.LoadPermissive(*configPath)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user