{"record":{"id":"a4419a4a8570aa35","repo":"Hmbown/CodeWhale","slug":"codewhale-account-does-not-accept-the-global","errorCode":null,"errorMessage":"`codewhale account` does not accept the global `--api-key` flag because command-line values can leak through shell history. Use `account keys set <provider>` for a hidden prompt, `--api-key-stdin`, or `--from-local`","messagePattern":"`codewhale account` does not accept the global `--api-key` flag because command-line values can leak through shell history\\. Use `account keys set <provider>` for a hidden prompt, `--api-key-stdin`, or `--from-local`","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/cli/src/cloud.rs","lineNumber":552,"sourceCode":"fn cloud_session_secrets() -> Result<Secrets> {\n    match secure_account_session_secrets() {\n        Ok(secrets) => {\n            if secrets.backend_name().starts_with(\"file-based\") {\n                eprintln!(\n                    \"warning: OS credential manager unavailable; {CLOUD_ALLOW_FILE_SESSION_STORE_ENV}=1 explicitly enables the local 0600 Codewhale secrets file for cloud session tokens\"\n                );\n            }\n            Ok(secrets)\n        }\n        Err(_) => bail!(\n            \"Codewhale account login requires an OS credential manager for session tokens. Configure Keychain, Credential Manager, or Secret Service and try again. Headless users may explicitly opt into the local 0600 secrets file with {CLOUD_ALLOW_FILE_SESSION_STORE_ENV}=1\"\n        ),\n    }\n}\n\npub(crate) fn reject_inline_api_key(api_key: Option<&str>) -> Result<()> {\n    if api_key.is_some() {\n        bail!(\n            \"`codewhale account` does not accept the global `--api-key` flag because command-line values can leak through shell history. Use `account keys set <provider>` for a hidden prompt, `--api-key-stdin`, or `--from-local`\"\n        );\n    }\n    Ok(())\n}\n\n#[allow(clippy::too_many_arguments)]\nfn run_with<T: CloudTransport, W: Write>(\n    command: CloudCommand,\n    profile: &str,\n    api_base: &str,\n    config: &ConfigStore,\n    cloud_secrets: &Secrets,\n    provider_secrets: &Secrets,\n    transport: &T,\n    out: &mut W,\n    key_reader: &mut dyn FnMut(KeyReadMode) -> Result<String>,\n    opener: &mut dyn FnMut(String) -> bool,","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/cli/src/cloud.rs#L534-L570","documentation":"reject_inline_api_key guards every `codewhale account ...` subcommands: passing the global --api-key flag is rejected because command-line arguments can persist in shell history and process listings, leaking the credential. The message points to the safe alternatives (hidden prompt, stdin, or --from-local import).","triggerScenarios":"Running e.g. `codewhale --api-key sk-... account keys set openai` or `codewhale account --api-key ... me`; any invocation where the global api_key option is Some() while an account subcommand dispatches.","commonSituations":"Users migrating from tools that accept keys as flags, CI scripts templating keys into command lines, copy-pasted examples that put the key before the subcommand.","solutions":["Use the hidden prompt: `codewhale account keys set <provider>` and type/paste the key with echo off.","Pipe the key: `printf '%s' \"$KEY\" | codewhale account keys set <provider> --api-key-stdin`.","Import an existing local provider key with `--from-local`.","Never place secrets in argv; move them into env/files consumed via stdin."],"exampleFix":"# before\ncodewhale --api-key sk-abc123 account keys set anthropic\n\n# after\nprintf '%s' \"$CODEWHALE_KEY\" | codewhale account keys set anthropic --api-key-stdin","handlingStrategy":"validation","validationCode":"// In wrappers, strip the flag before dispatching account commands\nif command.is_account() && global_args.api_key.is_some() {\n    global_args.api_key = None;\n    eprintln!(\"api-key ignored for account commands; use --api-key-stdin\");\n}","typeGuard":null,"tryCatchPattern":"match reject_inline_api_key(args.api_key.as_deref()) {\n    Ok(()) => run(cmd),\n    Err(e) if e.to_string().contains(\"--api-key\") => {\n        eprintln!(\"{}\", e); // explain, then prompt for the key via stdin instead\n        prompt_key_stdin()\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Never put secrets in argv; use stdin or hidden prompts.","Audit CI scripts for templated keys in command lines.","Prefer env/secret-store lookups inside the tool over flags."],"tags":["security","cli","secrets","argument-validation"],"backgroundTag":"secret-in-command-line-rejected","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}