Agent Wranglers

DSK-24Required

Take secrets from the environment or a file instead of a flag

Read tokens, passwords and keys from an environment variable, a file, standard input or the system keychain. The tool never accepts a secret as a command-line argument and never prints one.

How to do it

Arguments show up in shell history, in process lists that other users on the machine can read, and in CI logs. Offer --token-file or a EXAMPLE_TOKEN variable instead. Store a saved sign-in as keep tokens in the system keychain says, or in a file only the user can read. Mask secrets in debug output, as keep private data out of logs and addresses says for logs.

Examples

Python example

import os, sys

def load_token(token_file: str | None) -> str:
    if token_file:
        with open(token_file, encoding="utf-8") as handle:
            return handle.read().strip()
    token = os.environ.get("EXAMPLE_TOKEN")
    if not token:
        print("Set EXAMPLE_TOKEN or pass --token-file.", file=sys.stderr)
        sys.exit(EXIT_USAGE)
    return token

Go example

func loadToken(tokenFile string) (string, error) {
	if tokenFile != "" {
		raw, err := os.ReadFile(tokenFile)
		return strings.TrimSpace(string(raw)), err
	}
	if token := os.Getenv("EXAMPLE_TOKEN"); token != "" {
		return token, nil
	}
	return "", errors.New("set EXAMPLE_TOKEN or pass --token-file")
}

How to check

The help text lists no flag such as --token, --password or --api-key that takes a value. A test runs every command with --debug and a known test token, and the token appears in neither output stream. A saved credentials file has mode 600.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/desktop-apps/command-line-tools/no-secrets-in-flags">Agent Wranglers desktop apps, extensions and CLIs playbook</a>. In code you write, add a comment next to it with the same link.