pwstore: keepassxc LIVE-VM proof + root-group entry-path fix
Proven end-to-end (scan→plan→commit→restore-from-backup) against the real keepassxc-cli 2.7.6 in the incredigo-sbx sandbox VM. The live run surfaced an adapter bug the fake CSV masked: KeePassXC's CSV "Group" column is the full path including the root group name (default root is "Passwords"), but keepassxc-cli addresses entries relative to root (/GitHub, not /Passwords/GitHub). kpEntryPath now drops the leading root segment; the unit test that encoded the buggy /Root/GitHub form is corrected and a nested-group table test added. Records the proof as data: docs/BROWSER-ROTATION.md promotes keepassxc MOCK-ONLY -> LIVE-VM (the others stay MOCK-ONLY). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ custody → **mandatory backup** → rotate/verify/commit → guide) — it is *
|
||||
|
||||
Status: **Phase B (propagation engine) — built.** `pwgen` + `pwstore` (all five adapters) +
|
||||
the sealed staged-list + the `incredigo passwords scan|plan|guide|commit` surface are
|
||||
implemented and tested (adapters MOCK-ONLY against fake binaries/CSVs — see §8). Phases
|
||||
implemented and tested (keepassxc is LIVE-VM proven; the rest MOCK-ONLY — see §8). Phases
|
||||
A-tier-1 / A-tier-2 (site automation) are specified here but **not yet built**. Nothing in this
|
||||
doc changes a password **at a website** automatically — the human still performs the site
|
||||
change + MFA; incredigo only propagates the new value into the *manager* afterward.
|
||||
@@ -219,18 +219,27 @@ entries additionally record that a flag-gated plaintext file was created **and s
|
||||
## 8. Validation status (DATA, mirrors `rotate/proofs.go` philosophy)
|
||||
|
||||
The adapters contain ONLY real CLI/CSV code — no test branches. What differs is how each
|
||||
write path has been *validated*. As of the Phase-B build every adapter is **MOCK-ONLY**:
|
||||
exercised against a fake `bw`/`op`/`keepassxc-cli` binary (state-dir scripts) or a fake
|
||||
export/import CSV, never yet against the real manager binary or a real browser re-import.
|
||||
write path has been *validated*. Most adapters are still **MOCK-ONLY** (exercised against a
|
||||
fake `bw`/`op` binary or a fake export/import CSV); **keepassxc is LIVE-VM** — proven end to
|
||||
end (`scan → plan → commit → restore-from-backup`) against the genuine `keepassxc-cli 2.7.6`
|
||||
in the `incredigo-sbx` sandbox VM (`lab-provision-keepass.sh`).
|
||||
|
||||
| Adapter | Write shape | Secret path off-argv? | Validated against |
|
||||
|-----------|------------------------|-----------------------|-------------------|
|
||||
| bitwarden | `bw edit item` (stdin) | **yes** — base64 on stdin | fake `bw` (MOCK-ONLY) |
|
||||
| keepassxc | `keepassxc-cli edit -p`| **yes** — db+new pass on stdin | fake `keepassxc-cli` (MOCK-ONLY) |
|
||||
| keepassxc | `keepassxc-cli edit -p`| **yes** — db+new pass on stdin | **real keepassxc-cli 2.7.6 (LIVE-VM)** |
|
||||
| 1password | `op item edit pw=…` | **no** — argv assignment¹ | fake `op` (MOCK-ONLY) |
|
||||
| chrome | tmpfs CSV → human re-import | n/a (no live secret to a child) | fake CSV (MOCK-ONLY) |
|
||||
| firefox | tmpfs CSV → human re-import | n/a | fake CSV (MOCK-ONLY) |
|
||||
|
||||
**keepassxc LIVE-VM finding:** the CSV `Group` column is the FULL group path *including* the
|
||||
root group name (the default DB names its root `Passwords`), but `keepassxc-cli` addresses
|
||||
entries *relative to root* — a top-level entry is `/GitHub`, not `/Passwords/GitHub`. The
|
||||
mock CSV (root group `Root`) never exposed this; the real CLI 404'd until `kpEntryPath` was
|
||||
fixed to drop the leading root segment. The recoverability leg (feeding the sealed `backup.age`
|
||||
back through `commit --stage-in`) restored both original passwords, proving the backup is a
|
||||
usable restore artifact, not just a sealed blob.
|
||||
|
||||
¹ **1Password argv caveat:** `op item edit` has no stdin-per-field path (only `op item create`
|
||||
does), and the JSON-template alternative would write plaintext to disk (hard rule 3). The
|
||||
remaining real path is `op item edit <id> password=<new>`, so the new value is visible to
|
||||
|
||||
Reference in New Issue
Block a user