fix(configure): mask gateway password input in CLI wizard prompt#90571
Conversation
The `openclaw configure --section gateway` wizard echoed the typed Gateway password in cleartext on the terminal. Switch the prompt from clack's `text` to `password` (via a new styled `password` helper in `configure.shared.ts`) so input renders as bullets. Persisted config shape, validation, and downstream auth behavior unchanged. Mirrors the masking discipline established by openclaw#76693 for onboarding credential prompts. Sibling Gateway-token and models-auth paste-token prompts will be addressed in separate PRs.
|
Codex review: needs maintainer review before merge. Reviewed June 7, 2026, 6:16 AM ET / 10:16 UTC. Summary PR surface: Source +7, Tests +5. Total +12 across 4 files. Reproducibility: yes. Source inspection of current Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Merge this narrow masking fix after the usual maintainer and CI gates, and keep sibling credential-prompt fixes in their separate PRs. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection of current Is this the best way to solve the issue? Yes. Adding a shared configure AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 85840eb10e7f. Label changesLabel justifications:
Evidence reviewedPR surface: Source +7, Tests +5. Total +12 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Summary
What problem does this PR solve?
The
openclaw configure --section gatewaywizard echoes the typed Gateway password in cleartext on the terminal. This is reproducible on the latest published CLI with no special setup — anyone using documented onboarding steps over a shared screen, screen recording, pair-programming session, or office display can leak their gateway password.Why does this matter now?
This is the same class of UX/security defect already fixed for onboarding-wizard token/credential inputs in #76693 — the gateway configure surface was missed by that PR. Closing the gap keeps interactive credential entry consistent across all OpenClaw configure flows.
What is the intended outcome?
The
Gateway passwordprompt renders bullets (••••) instead of the typed characters. Persisted config shape, validation, and downstream auth behavior are unchanged.What is intentionally out of scope?
Gateway token (blank to generate)prompt — addressed in sibling PR fix(configure): mask gateway token input in CLI wizard prompt #91059.openclaw models auth paste-token --provider <p>prompt (masked: false) — separate PR fix(models): mask paste-token input in CLI auth prompt #90893.What does success look like?
Running the published-CLI repro after this patch shows bullets where the screenshot below shows the cleartext password. No regression in the
authMode === "password"config persistence path (existing unit testdoes not set password to literal 'undefined' when prompt returns undefinedstill passes).What should reviewers focus on?
passwordhelper inconfigure.shared.tsmatches the styling of the existingtext/confirm/selectwrappers.password→passwordInput) inconfigure.gateway.tsdoes not shadow the new imported helper.configure.gateway.test.ts's existingtextQueuefixtures still feed the password branch via the newpasswordmock.Linked context
Which issue does this close?
None — this PR was authored from an audit of unmasked credential prompts, not in response to an open issue.
Which issues, PRs, or discussions are related?
Was this requested by a maintainer or owner?
No — found while auditing remaining unmasked credential prompts after #76693 merged.
Real behavior proof (required for external PRs)
Behavior or issue addressed:
openclaw configure --section gatewayechoes the Gateway password in cleartext.Real environment tested: Windows 10 Home Single Language (build 19045.7291), PowerShell, OpenClaw
2026.6.1 (2e08f0f)for before-evidence (installed via the documented global installernpm install -g openclaw@latest); OpenClaw2026.6.2 (861bf54)from this branch viapnpm openclaw configure --section gatewayfor after-evidence.Exact steps or command run after this patch:
git checkout fix/mask-gateway-tokenpnpm install && pnpm buildpnpm openclaw configure --section gatewayGateway password, typeUSING_DUMMY_PASSWORDEvidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output):
Observed result after fix: characters render as bullets; persisted
gateway.auth.passwordvalue is the typed string (validated end-to-end byopenclaw configureprintingUpdated config: ~/.openclaw/openclaw.json).What was not tested: macOS, Linux. The change touches cross-platform
@clack/promptscode with noprocess.platformbranching, so the fix applies on all three platforms. Verification on each is tracked as a separate atomic task — macOS: [verify] gateway password mask renders bullets on macOS (PR #90571) #90634; Linux: [verify] gateway password mask renders bullets on Linux (PR #90571) #90635.Proof limitations or environment constraints: My machine is Windows-only. The fix path is platform-agnostic, but I cannot personally screenshot macOS/Linux output.
Before evidence (optional but encouraged):
Tests and validation
Which commands did you run?
pnpm installrun first (fresh checkout).pnpm check— typecheck green; one pre-existing lint failure inextensions/slack/(this PR's commits touch zero slack/plugin-sdk surface, perCONTRIBUTING.md:128-129).pnpm test— pre-existing Windows-only failures (POSIX-path, SQLite EBUSY, PTY tests) — none in this PR's files;configure.gateway.test.tsshard passes. Targeted regression:npx vitest run src/commands/configure.gateway.test.ts—Test Files 1 passed (1) / Tests 11 passed (11). After commitfa3f5e8aa4:pnpm tsgo:coreandpnpm test:changed— green (one pre-existing POSIX-path failure insrc/crestodian/operations.test.ts, unrelated). Manual repro per the steps above.What regression coverage was added or updated?
Updated mock setup in
src/commands/configure.gateway.test.tsto register the newpasswordhelper. Existing assertions covering the password branch ('does not set password to literal "undefined"', Tailscale-funnel-requires-password) continue to pass unchanged, demonstrating that the masked prompt feeds the same persistence path. AddedclackPassword: vi.fn()andpassword: mocks.clackPasswordto the@clack/promptsmock insrc/commands/configure.wizard.test.tsso the shared module import chain resolves correctly (commitfa3f5e8aa4).What failed before this fix, if known?
No automated test failure — this is a UX/security defect not previously asserted. The proof is the live terminal capture.
If no test was added, why not?
A test was not added because automated tests cannot meaningfully assert "the TTY echoes bullets, not characters" — that requires a real terminal. The structural fix is the new
passwordimport; verifying it is correctly wired is exactly what the manual repro screenshots prove.Risk checklist
Did user-visible behavior change? (
Yes/No)Yes — the
Gateway passwordprompt now renders bullets instead of typed characters. No other visible UI changes.Did config, environment, or migration behavior change? (
Yes/No)No —
gateway.auth.passwordinopenclaw.jsonis persisted unchanged. Backup file path unchanged. No migration.Did security, auth, secrets, network, or tool execution behavior change? (
Yes/No)Yes — masking the on-screen rendering of secret input. This is the intended security fix; no other auth/network behavior altered.
What is the highest-risk area?
Local-variable shadowing: I renamed
const password(the local variable holding the answer) topasswordInputso it doesn't shadow the new importedpasswordhelper. If a reviewer prefers an alternative name (e.g.,passwordAnswer), it's a one-token change.How is that risk mitigated?
The new helper is named identically across the wizard surface (
text,confirm,select, nowpassword) so future credential prompts inconfigure.gateway.tsand siblings have an obvious masked counterpart and won't accidentally regress totext(...). The variable rename is mechanical and locally scoped.Current review state
What is the next action?
Maintainer review.
What is still waiting on author, maintainer, CI, or external proof?
Which bot or reviewer comments were addressed?
ClawSweeper Codex review (2026-06-07, commit
3b067a65ab): P1 finding addressed in commitfa3f5e8aa4— addedclackPassword: vi.fn()to thevi.hoisted()mocks andpassword: mocks.clackPasswordto thevi.mock("@clack/prompts", ...)block insrc/commands/configure.wizard.test.ts. All targeted tests pass after the fix.AI-assisted PR:
codex review --base origin/mainlocally and address the findings before asking for review