Repository navigation
feat(vault): encrypt OAuth secrets with a safe rollout contract - #425
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: blocked before merge. What this changesThis PR adds optional password-based encryption for persisted OAuth secrets, migration on write, diagnostics, and child-process password isolation. Example: Run
Review scores
ProductKind: Feature · Worth it: Needs a maintainer decision · Fix scope: Complete Merge readiness⛔ Blocked before merge - 1 item remains Keep this PR open: it provides useful encryption absent from main, with no concrete code defect found, but the new security configuration and coordinated-upgrade contract still need an area-owner decision. Priority: P2 Decision needed
Before merge
FindingsNone. Agent review detailsHow this fits togetherOAuth persistence connects CLI and runtime authentication to the shared vault and configured token-cache directories; it accepts provider credentials and returns usable credentials while encrypting their stored secret fields. flowchart TD
A[CLI and generated clients] --> B[OAuth runtime]
B --> C[Persistence stores]
D[Password and encryption policy] --> E[JWE codec]
C --> E
E --> F[Vault and token cache files]
B --> G[OAuth and MCP servers]
Technical reviewBest possible solution: Approve the bounded opt-in encryption design and documented coordinated rollout, or choose storage isolation before landing. Do we have a high-confidence way to reproduce the issue? This is a feature request rather than a broken encryption contract; current main visibly persists plaintext JSON, and the reporter's scanner run confirms the practical concern. Is this the best way to solve the issue? A shared codec covering both credential stores is coherent and avoids whole-file corruption handling, but the permanent configuration and mixed-version contract require owner approval. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against e3fa5352d05f. Provenance checked
TestingProof path: shipped entry point. SecurityNone. EvidenceWhat I checked:
Likely related people:
LabelsLabel changes: No label changes. Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReview history (12 earlier review cycles; latest 8 shown)
Reviewed October 16, 2026, 1:48 AM ET / 05:48 UTC (Revision 13). |
|
Thanks for the review. All findings are addressed in 99ff6ef ("clawsweeper review": [P2] Propagate vault encryption refusals through cache fallback — fixed.
[P2] Migrate existing secrets in every token-cache file — fixed.
[P1 merge risk] Legacy files deleted without encryption — fixed with your recommended option.
[P1] Prevent older writers from restoring plaintext — addressed as an explicit upgrade contract, not storage isolation.
Also fixed after an independent re-check of the above
Validation: Real behavior proof The built branch CLI and the released Transcript (8 steps)Step 1 shows two refreshes for one call: 2026-10-06-mcporter-vault-jwe-encryption-pr-proof.txt @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
MCPORTER_VAULT_PASSWORD (#408)
|
Revision 2 and 3 items are addressed: directory writers in 8e616af ("clawsweeper review 2"), the generator in c45fb62 ("generate-cli").
Validation: @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
Revision 4's finding is addressed in c6ed6eb:
The remaining items are not code: the maintainer decision on the coordinated-upgrade contract (goal 3 of the PR body states it; the review recommends accepting it) and the rebase onto @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
@steipete this is ready for your look. ClawSweeper has no contributor-facing finding left after eight rounds, the branch is merged with The one item still open is a decision rather than code: the coordinated-upgrade contract in design goal 3. Encryption is in place in the existing If the contract is acceptable, a short confirmation here is all the review asks for. If you would rather have the residue window closed as well, I can add sealing on the next read with the password set as a follow-up. Anything else you want changed, say so and I will adjust. |
|
Synchronized with The open item is unchanged: the coordinated-upgrade contract in design goal 3 needs a maintainer decision. @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
Rank-up move applied in ddec532: the helper-only @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
On priority: the review rates this P2 as "a useful optional feature without evidence of an urgent exploit or broken existing workflow". The description now has a "Why this matters now" section with the evidence. In short: @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
On the compatibility label: nothing changes at merge or on upgrade. Without @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
Thanks @alexminza, this covers what I was after. Both departures make sense to me. Per-value sealing is the right call, since older readers treat a non-JSON vault as corrupt and wipe it, and a 401 with re-auth is a much better failure. JOSE over raw AES-GCM is fine too, since the cipher is the same and I built the branch and scanned real vault and tokenCacheDir output with Kingfisher 2.13.0 ( Needed before merge
Worth doing in the same PR
With |
|
@stenh0use thanks for the build-and-scan pass, that is exactly the check this needed.
Tests: @steipete with @stenh0use's sign-off above, the only item ClawSweeper still lists is your one-line OK on the compatibility contract (TL;DR of the description). |
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
Update the Rolldown dependency from 1.2.13 to 1.2.14, including its native bindings and Oxc types in the lockfile. The release has cleared the 48-hour cooldown. This keeps generated CLI bundling current while preserving Node 24 support, the patched MCP client, and security overrides. Validation: frozen-lockfile installation with strict engines; `pnpm check`; `pnpm test` (2,206 passed, 27 skipped); and `pnpm test:package`, including installed-package OAuth correlation checks, all passed on Linux. Independent review found no actionable P0–P2 issues. An Unreleased changelog entry is included; the package version is unchanged.
Add optional per-value OAuth encryption while preserving plaintext defaults. Persist versioned encryption markers across empty-store clears, document the coordinated-upgrade contract and isolated downgrade procedure, and exercise migration, unsafe legacy writes, and safe rollback against mcporter 0.15.0. Closes openclaw#408 Co-authored-by: Alexander Minza <alexander.minza@gmail.com>
MCPORTER_VAULT_PASSWORD (#408)
steipete
left a comment
There was a problem hiding this comment.
Accepting the opt-in encryption design with the documented coordinated-upgrade requirement and isolated downgrade procedure. The versioned markers preserve the policy across empty stores and every directory deletion path; they deliberately do not claim enforcement by already-released binaries. The completed candidate has passed focused regression and installed-package downgrade proof, and independent P0–P2 review.
Closes #408.
OAuth tokens and client secrets currently remain readable in copied vaults and token caches. This adds optional per-value JWE encryption with
MCPORTER_VAULT_PASSWORD, covers both persistence backends, migrates plaintext on write, and keeps existing plaintext defaults. The required policy, diagnostics, generated-CLI policy propagation, and child-process password filtering are included.Maintainer decision: accept the bounded opt-in feature with a coordinated-upgrade requirement and an isolated downgrade procedure. Every CLI, daemon, and bundled generated CLI sharing the state must be upgraded and restarted before opt-in. Already-released binaries ignore encryption and can silently restore plaintext on re-authentication. A new top-level vault version would be worse because released readers repair unknown versions by replacing the vault. The prominent warning and rollback instructions in
docs/config.mdstate this limitation explicitly.Supporting versions now persist a versioned encryption marker in the vault and
tokenCacheDir, retain it after the last credential is cleared, and refuse missing passwords or unknown marker versions without rewriting the store. Rollback uses separate HOME/XDG directories and separate explicit token caches; it does not decrypt the original store in place. The package test exercises this against the published 0.15.0 package, including the unsafe shared-store downgrade and re-sealing recovery.Validation on an isolated Linux worker:
pnpm check; 181 focused tests across persistence, refresh locking/recovery, vault commands/validation, diagnostics, and generated CLIs;pnpm test:package, including installed-candidate versus published 0.15.0 migration and downgrade checks. The four initial marker regressions were reproduced failing on the original contributor head and passing on the completed implementation. Independent Codex autoreview is clean for P0–P2 findings. The first broad test run identified two test-fixture assumptions, both corrected and retested; exact-head CI passed across Ubuntu/Node 24, Ubuntu/Node 26, macOS, and Windows. Post-merge CI and the no-publish source and native release rehearsal also passed at merge commit90bb83f934cb68f5faf463461388135a20597293.Thanks @alexminza for the implementation and @stenh0use for the original scanner-based validation and field-coverage feedback. No release or version bump.