Skip to content

[Feature]: Support custom certificate passwords in winapp cert commands #242

Description

Is your feature request related to a problem? Please describe.

The extension has no way to set a certificate password. winapp.certGenerate passes no --password, so every certificate it produces uses the winapp CLI's documented development default (password). winapp.certInstall likewise passes no --password, so it can only install certificates that use that default. The only password handling anywhere in the extension is winapp.certInfo, which prompts for one in order to read an existing certificate.

Consequences:

  • A user who generates a certificate outside the extension with a non-default password cannot install it via winapp.certInstall — the command fails and the extension surfaces no way to supply the password.
  • A user who wants a generated certificate to have anything other than the well-known default password has to drop to a terminal and run the CLI by hand.

This was split out of the winapp cert generate command-surface work so that command could land without also settling the password design, which spans several commands and has a security prerequisite (below).

Describe the solution you'd like

Support a custom password consistently across the cert commands, and settle the design once rather than per command:

  • cert generate --password — opt-in, not a prompt on the default path. The CLI default (password) is appropriate for a self-signed local test certificate, so a mandatory prompt in a dev-loop command would be friction for no real threat reduction.
  • cert install --password — needed to install certificates the extension did not generate.
  • The equivalent question for winapp.sign and winapp.pack --cert, which are being looked at separately but would inherit the same transport concerns.

Constraints the implementation should respect:

  • No password in settings.json. Settings are synced, are frequently committed as .vscode/settings.json, and are rendered in plaintext in the Settings UI. If a password is persisted at all it belongs in context.secrets (SecretStorage).
  • Pass passwords via spawn with an args array and shell: false, following the precedent already set by winapp.certInfo, not by interpolating into a command string for Terminal.sendText.
  • Redact in output. runWinappCapture echoes > winapp ${args.join(' ')} to the output channel, and separately the CLI's own --json output includes a "password" field — so even a correct args-array transport re-leaks the value if raw CLI output is streamed to the channel. Both points need masking.

Additional context

Security prerequisite — the elevated path. runWinappCommandElevated / buildElevatedTerminalCommand compose a PowerShell string and sendText it into a non-elevated terminal, which then re-launches via Start-Process -Verb RunAs. A password routed through that construct is exposed in at least four places: the visible terminal buffer, PSReadLine's on-disk ConsoleHost_history.txt, the launcher process command line, and the elevated powershell.exe command line (readable by any process running as that user via Get-CimInstance Win32_Process).

There is no safe way to escape a secret through that path, so custom password support for anything that installs to the machine store should depend on the planned restructure of "Generate and install": generate un-elevated with --export-cer, then elevate only cert install <the .cer>, which carries no private key and needs no password at all. Where a .pfx install with a non-default password is genuinely unavoidable, the extension should decline to inline the secret and explain the alternative rather than silently leaking it.

Related unsurfaced cert generate options. The extension's command surface was built against winappcli ~0.3.1 while scripts/download-cli.ps1 downloads latest (now 0.6.x), so several options are unreachable from the UI. --publisher, --manifest, --output, --valid-days, --export-cer, and --if-exists are being addressed in the in-flight cert generate work; --password is tracked here. The underlying version drift — a 0.6.x CLI shipping behind a 0.3.x UI — is worth addressing separately, e.g. by pinning the downloaded CLI version or asserting a minimum version at activation using the CLI's --cli-schema self-description.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions