Bug Description
When choosing the "Environment variable" option in Step 2 (Security) of the setup wizard, the secrets_crypto context is not initialized in memory. This causes subsequent API key saves in Step 3 (LLM Provider) to fail silently, leaving the user with no stored API key and a non-working LLM configuration.
Steps to Reproduce
- Run
ironclaw for the first time (or delete ~/.ironclaw/.env and ONBOARD_COMPLETED setting)
- In Step 1 (Database), choose any option
- In Step 2 (Security), choose option 2: "Environment variable (generate a key for .env file)"
- In Step 3 (LLM Provider), configure an OpenAI-compatible provider and enter your API key
- Complete the wizard
- Try to use IronClaw - observe 401 Unauthorized errors
- Check the database
secrets table - it's empty
Root Cause
In src/setup/wizard.rs around line 758-769, the "Environment variable" option (index 1) generates a key and prints it but never sets self.secrets_crypto:
1 => {
// Env var mode
print_info("Generate a key and add it to your environment:");
let key_hex = crate::secrets::keychain::generate_master_key_hex();
println!();
println!(" export SECRETS_MASTER_KEY={}", key_hex);
println!();
print_info("Add this to your shell profile or .env file.");
self.settings.secrets_master_key_source = KeySource::Env;
print_success("Configured for environment variable");
// ✗ Missing: self.secrets_crypto = Some(...) <-- BUG!
}
Compare to option 0 (keychain) which DOES set self.secrets_crypto:
0 => {
// Keychain mode
let crypto = crate::secrets::keychain::init_from_keychain()
.map_err(|e| anyhow::anyhow!("Failed to initialize keychain: {}", e))?;
self.secrets_crypto = Some(crypto); // ✓ Correctly set
...
}
When self.secrets_crypto is None, the init_secrets_context() call later in the wizard fails, and the API key is never saved to the database.
Additional Issue: Misleading Message
The wizard message says:
Add this to your shell profile or .env file.
However, IronClaw uses dotenvy which only loads from .env files (~/.ironclaw/.env and ./.env), NOT from the shell environment inherited from .bashrc or other shell profiles. So adding to .bashrc and sourcing does NOT work - the key must be in a .env file.
Workaround
Manually add both keys to ~/.ironclaw/.env:
SECRETS_MASTER_KEY=<generated-hex-key>
LLM_API_KEY=<your-api-key>
Proposed Fix
-
Initialize crypto for env var option: Generate the key, initialize self.secrets_crypto with it, AND save the key to ~/.ironclaw/.env automatically (or at least offer to do so).
-
Update the message to clarify that only .env files work:
Add this to ~/.ironclaw/.env file (IronClaw loads from .env files, not shell profiles).
-
Consider auto-writing: The wizard could automatically append SECRETS_MASTER_KEY=... to ~/.ironclaw/.env when this option is chosen, making the process seamless.
Environment
- IronClaw version: 0.16.1
- OS: Linux (WSL2)
- Database: libSQL
Related Code
src/setup/wizard.rs - step_security() function
src/config/mod.rs - inject_llm_keys_from_secrets()
src/secrets/store.rs - secrets storage implementation
Bug Description
When choosing the "Environment variable" option in Step 2 (Security) of the setup wizard, the
secrets_cryptocontext is not initialized in memory. This causes subsequent API key saves in Step 3 (LLM Provider) to fail silently, leaving the user with no stored API key and a non-working LLM configuration.Steps to Reproduce
ironclawfor the first time (or delete~/.ironclaw/.envandONBOARD_COMPLETEDsetting)secretstable - it's emptyRoot Cause
In
src/setup/wizard.rsaround line 758-769, the "Environment variable" option (index 1) generates a key and prints it but never setsself.secrets_crypto:Compare to option 0 (keychain) which DOES set
self.secrets_crypto:When
self.secrets_cryptoisNone, theinit_secrets_context()call later in the wizard fails, and the API key is never saved to the database.Additional Issue: Misleading Message
The wizard message says:
However, IronClaw uses
dotenvywhich only loads from.envfiles (~/.ironclaw/.envand./.env), NOT from the shell environment inherited from.bashrcor other shell profiles. So adding to.bashrcand sourcing does NOT work - the key must be in a.envfile.Workaround
Manually add both keys to
~/.ironclaw/.env:Proposed Fix
Initialize crypto for env var option: Generate the key, initialize
self.secrets_cryptowith it, AND save the key to~/.ironclaw/.envautomatically (or at least offer to do so).Update the message to clarify that only
.envfiles work:Consider auto-writing: The wizard could automatically append
SECRETS_MASTER_KEY=...to~/.ironclaw/.envwhen this option is chosen, making the process seamless.Environment
Related Code
src/setup/wizard.rs-step_security()functionsrc/config/mod.rs-inject_llm_keys_from_secrets()src/secrets/store.rs- secrets storage implementation