Add the secondary-persona path from docs/BROWSER-ROTATION.md: ingest a password
manager / browser store, take a mandatory verified sealed backup, generate fresh
strong passwords, hand the human a ready-to-finish task at the MFA wall, and commit
the new value into the manager only after the site change is confirmed.
- internal/pwgen: crypto/rand generator (rejection sampling, per-class guarantee,
vault-native — never returns plaintext as a Go string).
- internal/pwstore: Manager/ItemUpdater/BulkImporter contracts, secrets-free
RedactIdentity, and five adapters — bitwarden (bw, stdin), keepassxc
(keepassxc-cli, stdin), 1password (op, argv assignment with documented caveat),
chrome/firefox (tmpfs CSV ingest-and-shred). All real code; validation status is
data (MOCK-ONLY against fake binaries/CSVs, recorded in the design doc).
- internal/pwstore/stage.go: age-sealed staged-list (WriteStaged/ReadStaged) +
StagedImporter — the only artifacts crossing the plan->commit gap, never plaintext.
- cmd/incredigo: passwords scan|plan|guide|commit. Backup gate seals + round-trip
verifies before any commit; guide is interactive verify-before-commit; commit is
headless over a sealed stage. Browser CSV writes are gated behind --allow-csv.
Hard rules honored: backup-before-commit, verify-before-commit, no plaintext on
disk (browser CSV is the flag-gated tmpfs+shred exception), MFA always a human
handoff. go vet + -race clean; end-to-end verified against a fake bw.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ran live cutover POCs in the sandbox VM against the real target software and
promoted both drivers from MOCK-ONLY to LIVE-VM in the proof table (data, not
driver behaviour):
- k8s: proven against real k3s v1.35 kube-apiserver + token controller
(lab-provision-k8s.sh). The real apiserver serves a self-signed cert, so the
driver gained CA-pinned TLS — blob params ca= (base64 PEM, pinned as the only
trusted root) and insecure=1 (lab-only escape hatch), routed through a new
clientFor(cr). Neither is test-awareness; a real deployment configures the same
CA. Added TestK8sTLSTrust covering CA-pinned / insecure / untrusted-rejection
and the blob round-trip.
- mongo: proven against real mongod 8.0 (lab-provision-mongo.sh).
npm stays MOCK-ONLY by decision (registry.npmjs.org not self-hostable; real
create-token requires the account password in the body) — documented as a
contract gap rather than faking a LIVE-VM. gcp/twilio/flyio remain MOCK-ONLY.
Live POCs surfaced real-target-only behaviour now recorded in the docs: the
apiserver's ~10s successful-auth cache (old token kept working ~7s after Secret
deletion) and real mongosh's stdout prompt. Full suite 104 green, -race clean.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each driver is real-service code only (no test awareness; tests inject just an
HTTPClient/Bin), following the established patterns:
- mongo: in-place changeUserPassword over the old connection; no secret on argv
(host/db on the URI, both passwords on stdin, output scrubbed).
- npm: create token -> /-/whoami -> delete-by-key; blob records the key.
- gcp: service-account KEY rotation; mints an RS256 JWT signed with the SA's
own private key (crypto/rsa, stdlib) to self-auth the IAM create/verify/delete.
- twilio: API Key create -> get -> delete, Basic auth (KeySid/secret).
- flyio: GraphQL — a managing token mints/deletes the rotated deploy token.
- k8s: create a service-account-token Secret, await the populated token,
verify against the SA, delete the old Secret (invalidates the old token).
All 6 register their honest proof level (MOCK-ONLY) in proofs.go +
ROTATION-PROOFS.md; mongo/npm/k8s are LIVE-VM candidates pending real-target VM
POCs. Emulators enforce credential validity (gcp verifies the JWT signature),
tests assert Verify(old) fails after revoke + a secret-leak canary.
Full suite: 103 green, -race clean on rotate/sink/vault.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add gitlab, cloudflare, ghactions (MOCK-ONLY) and appsecret (LIVE-VM) one-file
Rotators, each with a table-driven cutover-proof + leak-check test. gitlab/
cloudflare/ghactions are in-place SaaS-token rolls (self/rotate, value-roll,
sealed-secret overwrite) so RevokeOld is a no-op; ghactions seals via
nacl/box.SealAnonymous (no new go.mod dep). appsecret regenerates a local app
signing secret and rewrites it in place across every target file (atomic, mode-
preserving, redacted errors), discoverable via exact-match app-signing key names
in env.go.
Keep real-rotation code distinct from mock code: how each driver's cutover was
validated lives as DATA in internal/rotate/proofs.go (single source of truth) +
docs/ROTATION-PROOFS.md, surfaced as a PROOF column in `incredigo rotate` so a
MOCK-ONLY driver can never be mistaken for a LIVE-VM one. appsecret proven LIVE-VM
against real local files in the sandbox VM.
82 tests green, -race clean on rotate/sink/vault.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds VISION.md (target personas + 20-credential surface), docs/MARKET.md
(competitive positioning), and docs/FINDINGS-2026-06-16.md (controlled-env
test run: live cutover POCs for postgres/gitea/aws/mysql/redis/wireguard, the
backup-gate defect + fix, and the MariaDB unprivileged-rotation gap). Swaps the
placeholder _igo_options assets for the banner/icon set. Refreshes the project
CLAUDE.md directive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>