{"record":{"id":"b19fc3e7e314e568","repo":"Hmbown/CodeWhale","slug":"codewhale-account-login-requires-an-os-credential","errorCode":null,"errorMessage":"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","messagePattern":"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 (.+?)=1","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/cloud.rs","lineNumber":544,"sourceCode":"        &transport,\n        &mut stdout,\n        &mut key_reader,\n        &mut opener,\n        &mut sleeper,\n    )\n}\n\nfn 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,","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/cli/src/cloud.rs#L526-L562","documentation":"cloud_session_secrets demands an OS-backed secret store (Keychain, Windows Credential Manager, Secret Service) for cloud session tokens. secure_account_session_secrets errors entirely (no OS backend and the file-store opt-in not satisfied), so login is refused before it starts: headless secret hygiene — never silently fall back to a plaintext file.","triggerScenarios":"Running `codewhale account login` on a headless Linux box without Secret Service (no D-Bus secret service / gnome-keyring), in minimal containers/WSL without a credential daemon, or SSH sessions where the keyring service is absent and CODEWHALE_ALLOW_FILE_SESSION_STORE (CLOUD_ALLOW_FILE_SESSION_STORE_ENV) is unset.","commonSituations":"Docker/CI containers, servers without desktop services, WSL distros lacking keyring packages, locked keyrings that fail to open.","solutions":["Install and start a Secret Service provider (gnome-keyring + libsecret) or ensure Keychain/Credential Manager is available, then retry.","For headless use where the risk is accepted, set the file-store opt-in env var to 1 to use the local 0600 secrets file (the code prints its exact name in the warning at line 539).","In containers, mount a keyring sidecar or run the login on a workstation and copy nothing — prefer enabling the env opt-in inside the container only.","If a keyring exists but is locked, unlock it and retry."],"exampleFix":"# before (headless container)\ncodewhale account login  # error: requires an OS credential manager\n\n# after (explicit opt-in to 0600 file store)\nexport CODEWHALE_ALLOW_FILE_SESSION_STORE=1\ncodewhale account login","handlingStrategy":"validation","validationCode":"// Pre-flight the secret backend before starting login\nfn secrets_available() -> bool {\n    secure_account_session_secrets().is_ok()\n        || std::env::var(CLOUD_ALLOW_FILE_SESSION_STORE_ENV).as_deref() == Ok(\"1\")\n}","typeGuard":null,"tryCatchPattern":"match cloud_session_secrets() {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"OS credential manager\") => {\n        if headless_and_accepted_risk() {\n            std::env::set_var(CLOUD_ALLOW_FILE_SESSION_STORE_ENV, \"1\");\n            cloud_session_secrets() // retry with explicit opt-in\n        } else { Err(e) }\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Provision gnome-keyring/libsecret (or Keychain/Credential Manager) in headless images.","Set the file-store opt-in env var only in containers where the 0600 file risk is accepted.","Check keyring availability in CI before account-dependent tests."],"tags":["secrets","keyring","headless","cloud","cli"],"backgroundTag":"os-keyring-unavailable","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}