Skip to content

fix(tui): mask a vaulted answer as the user types it - #1248

Open
Gilbert09 wants to merge 1 commit into
mainfrom
posthog/mask-sensitive-ask-answers
Open

fix(tui): mask a vaulted answer as the user types it#1248
Gilbert09 wants to merge 1 commit into
mainfrom
posthog/mask-sensitive-ask-answers

Conversation

@Gilbert09

Copy link
Copy Markdown
Member

Problem

wizard_ask lets a question declare itself sensitive. When it does, the tool
stores the user's answer in the session secret vault and returns an opaque
{ secretRef } to the agent, so the raw string never enters the model's
conversation.

The overlay that collects it did not honour that. Every kind: 'text' question
rendered through the plain TextInput, so a vaulted answer was echoed on screen
character by character while it was typed — the one place a credential is read
by someone other than its owner: a shared screen, a pairing session, a recorded
terminal.

It is the only unguarded boundary left around these values. The vault keeps them
out of the conversation, the orchestrator's skip events carry a closed set of
reasons rather than free text, and handoff prose is deliberately kept out of
telemetry for the same reason. AskQuestion.sensitive even documented the
overlay behaviour as "the TUI may also mask input accordingly" — it never did.

Why

Found while reading the telemetry for the wizard's data-source setup task — the
flow whose credential prompt is the step users most often back out of. Masking
does not change that funnel on its own; it closes a straightforward exposure on
the prompt that collects the values.

Changes

  • Route a masked question to @inkjs/ui's PasswordInput instead of
    TextInput. Same props, same submit contract; only the rendering differs.
  • shouldMaskAnswer is exported and unit-tested rather than inlined in the
    switch, and checks kind as well as the flag so it stays total over a
    question (the tool already rejects sensitive on a picker, and a picker has
    nothing to type).
  • Correct the AskQuestion.sensitive doc comment, which described masking as
    optional.

Nothing else changes: an ordinary text question renders exactly as before.

Test plan

  • shouldMaskAnswer unit tests added to WizardAskScreen.test.ts (masked
    text, unmasked text, pickers).
  • vitest run src/ui — 306 tests pass.
  • tsc --noEmit clean for the touched files; prettier and eslint clean.

Created with PostHog Desktop

`wizard_ask` lets a question declare itself `sensitive`. The tool then stores
the answer in the session secret vault and hands the agent an opaque
`secretRef`, so the raw string never enters the model's conversation.

The overlay that collects it rendered it with the plain `TextInput`, so the
value was echoed on screen character by character while it was typed. Every
other boundary around these answers is guarded — the vault keeps them out of
the conversation, the skip events carry no free text, handoff prose is kept
out of telemetry — and the prompt itself was the one place the value was shown
in the clear.

Route a masked question to `PasswordInput` instead. `shouldMaskAnswer` is
exported and unit-tested so the rule is visible rather than inlined in the
switch, and it checks `kind` as well as the flag so it stays total over a
question.

Generated-By: PostHog Desktop
Task-Id: 0af1c1f6-2aab-4807-8e24-86b2a9eb18fd
@Gilbert09
Gilbert09 requested a review from a team as a code owner September 12, 2026 11:56
Copilot AI lite review requested due to automatic review settings September 12, 2026 11:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/google-adk
  • /wizard-ci ai-observability/groq
Show more apps
  • /wizard-ci ai-observability/manual-capture
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/opentelemetry
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

@Gilbert09 Gilbert09 added the stamphog Auto-merge stamp for automated PRs label Sep 12, 2026 — with PostHog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Auto-merge stamp for automated PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants