Repository navigation
[Bug]: step prints KMS URI secrets (pin-value, etc.) in cleartext when step-kms-plugin fails #1668
Description
Steps to Reproduce
Run any command that shells out to step-kms-plugin with a credential supplied inline in the KMS
URI, and have the plugin call fail. For example:
step certificate create --profile root-ca \
--kms "yubikey:serial=<SERIAL>;pin-value=<YOUR-PIN>" \
--key "yubikey:slot-id=9c" --not-after 87600h "My Root CA" root_ca.crt
When the plugin subprocess exits non-zero for any reason (wrong PIN, a touch-policy timeout, etc.),
step prints the full command line it ran — including the pin-value= you supplied.
This is not specific to YubiKey or to certificate create: it affects any KMS URI that carries an
inline credential, on any step command that runs the plugin, because the error wrapper embeds the
entire plugin argv. It is also visible by inspection in
internal/cryptoutil/cryptoutil.go — exitError formats cmd.String() into the returned error.
Your Environment
- OS - Windows 11 (the affected code path is OS-agnostic; macOS/Linux are equally affected)
stepCLI Version - 0.30.6 (with step-kms-plugin 0.17.0)
Expected Behavior
Secrets supplied through the documented pin-value= (and management-key=, client-secret=)
mechanism should not appear in cleartext in error output. The echoed command is genuinely useful for
debugging, so the fix is to redact the credential values, not to drop the echo.
Actual Behavior
The credential is printed verbatim on stderr. For example:
error creating certificate request: command "…\step-kms-plugin.exe sign --format base64 --kms yubikey:serial=<SERIAL>;pin-value=<YOUR-PIN-IN-CLEARTEXT> yubikey:slot-id=9c" failed with:
Error: command failed: smart card error 6982: security status not satisfied
pin-value= is the documented way to supply the PIN non-interactively, so using the feature as
designed puts the secret on stderr on any failure — where it lands in console scrollback, session
transcripts, and CI logs, and (because this error text is exactly what people paste into bug
reports) potentially public issue trackers.
Additional Context
- Root cause:
exitErrorininternal/cryptoutil/cryptoutil.goformatscmd.String()(the full
plugin argv — the--kmsURI plus the positional key URI) into
fmt.Errorf("command %q failed with: …"), and passes the plugin's stderr through verbatim. - Affected attributes across the KMS URI schemes the crypto library parses:
pin-value
(yubikey/pkcs11/capi),management-key(yubikey),client-secret(azurekms).pin-source,
management-key-source, andcredentials-fileare file paths (not secrets). - The
6982in the example is an unrelated touch-policy timeout; the leak occurs on any plugin
failure, not just that one.
Contributing
Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).
Activity
[-][Bug]: step prints KMS URI secrets (pin-value, etc.) in cleartext when step-kms-plugin fails ```[/-][+][Bug]: step prints KMS URI secrets (pin-value, etc.) in cleartext when step-kms-plugin fails[/+]Redact KMS URI secrets from plugin error output