{"record":{"id":"9b73c42b8918f652","repo":"zeroclaw-labs/zeroclaw","slug":"cannot-determine-current-username-acl-hardening-i","errorCode":null,"errorMessage":"Cannot determine current username; ACL hardening is required for key file protection","messagePattern":"Cannot determine current username; ACL hardening is required for key file protection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/secrets.rs","lineNumber":839,"sourceCode":"/// ACLs.  Fail-closed: if hardening cannot be established, publication aborts\n/// so the key is never visible with unhardened permissions.\n#[cfg(windows)]\nfn apply_windows_acl(path: &Path) -> Result<()> {\n    let username = std::process::Command::new(\"whoami\")\n        .output()\n        .ok()\n        .filter(|o| o.status.success())\n        .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())\n        .unwrap_or_else(|| std::env::var(\"USERNAME\").unwrap_or_default());\n    let Some(grant_arg) = build_windows_icacls_grant_arg(&username) else {\n        ::zeroclaw_log::record!(\n            WARN,\n            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)\n                .with_outcome(::zeroclaw_log::EventOutcome::Unknown),\n            \"USERNAME environment variable is empty; \\\n             cannot restrict key file permissions via icacls\"\n        );\n        anyhow::bail!(\n            \"Cannot determine current username; \\\n             ACL hardening is required for key file protection\"\n        );\n    };\n\n    match std::process::Command::new(\"takeown\")\n        .arg(\"/F\")\n        .arg(path)\n        .output()\n    {\n        Ok(o) if !o.status.success() => {\n            ::zeroclaw_log::record!(\n                WARN,\n                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)\n                    .with_outcome(::zeroclaw_log::EventOutcome::Unknown),\n                &format!(\n                    \"Failed to take ownership of key file via takeown (exit code {:?})\",\n                    o.status.code()","sourceCodeStart":821,"sourceCodeEnd":857,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/secrets.rs#L821-L857","documentation":"On Windows, before any key byte hits disk, apply_windows_acl must build a restrictive grant for the current user, which requires knowing the username: it runs `whoami`, falling back to the USERNAME env var. If both fail (whoami errors or outputs failure, and USERNAME is unset/empty — e.g., stripped service contexts), the grant argument cannot be built and the function fails closed: key publication aborts rather than writing a key with inherited (looser) ACLs. Reached from write_key_file_atomic_publish_with during first-run key creation.","triggerScenarios":"First-run master key creation on Windows inside a service/scheduled-task session where USERNAME is not set and whoami is unavailable or fails; hardened or minimal Windows environments where whoami is blocked; CI runners with scrubbed environment.","commonSituations":"Running ZeroClaw as a Windows service under an account profile that lacks USERPROFILE/USERNAME; sandboxed CI on Windows agents; group-policy-restricted hosts where whoami.exe is disallowed.","solutions":["Run the initial provisioning (`zeroclaw quickstart`) in a normal interactive user session where USERNAME is set, so the key file is created once; later service runs only read it","Set USERNAME explicitly in the service/scheduled-task environment to the account's actual user name","Ensure whoami.exe is reachable via PATH and not blocked by policy"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// run before provisioning on Windows:\n#[cfg(windows)]\nfn username_known() -> bool {\n    std::env::var(\"USERNAME\").map(|v| !v.trim().is_empty()).unwrap_or(false)\n        || std::process::Command::new(\"whoami\").output()\n            .map(|o| o.status.success()).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = provision_key(&path) {\n    let msg = e.to_string();\n    if msg.contains(\"Cannot determine current username\") {\n        eprintln!(\"run `zeroclaw quickstart` from an interactive session (or set USERNAME) so ACL hardening can identify the user\");\n    }\n    return Err(e);\n}","preventionTips":["Do first-run provisioning interactively; let services only read the already-created key","For unattended Windows installs, set USERNAME explicitly in the service environment"],"tags":["windows","acl","secrets","key-management","environment","permissions"],"backgroundTag":"missing-env-var","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}