Programming · free software · the open webSubscribe via RSS

Why Should a CLI Avoid Printing Secrets?

From the earlier reference collection. Read the current software blog.

Keep credentials out of command arguments and logs, and redact configuration values before producing diagnostics.

Output travels farther than expected

Terminal output is often copied into issue reports, attached to support messages, or retained by automation. A command that prints a complete configuration object may expose API tokens, passwords, private endpoints, or session cookies long after the original task is finished. Even a local debug log can be readable by more people or processes than the operator expects.

The same concern applies to process arguments. A token placed directly after --token may be visible in shell history or process inspection tools. Prefer a protected configuration mechanism such as a permission-restricted file, an environment variable supplied by a secret manager, or an interactive prompt when appropriate.

Redact at the source of diagnostics

Avoid logging whole request headers or dumping every configuration field on failure. Instead, print the non-sensitive details needed to diagnose the issue: the source identifier, operation, status code, and a correlation ID. If a configuration dump is essential, use an allowlist of safe fields rather than trying to recognize every possible secret name after the fact.

For example, a useful message might say refresh for source coastal-feed failed with HTTP 403 without showing the authorization header or full credential-bearing URL. The operator can then inspect the protected configuration through the appropriate channel.

Treat indirect exposure as exposure

Secrets can appear inside exception messages, URLs, query parameters, shell tracing, or copied environment dumps. Review these paths when designing a command’s error handling. If a library includes a request URL in its exception, strip sensitive query parameters before writing that exception to a general log.

Redaction should preserve enough structure to be useful. Replacing every character with [REDACTED] can hide whether a value was absent or malformed. A message can identify the configuration key and say that a value was supplied without showing the value itself.

Make safe behavior the default

Document how credentials enter the command and where they may be stored. Keep verbose diagnostics opt-in, and ensure they still pass through redaction. A safe default protects routine runs, while a carefully designed debug mode can provide additional context without turning logs into a credential archive.

When a secret is accidentally exposed, removing it from the visible terminal is not enough; revoke or rotate it through the system that issued it. Prevention is simpler: keep secrets out of arguments, output, and logs from the start.

Suggest a correction · All posts