You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Credentials currently live at rest in plaintext — SPEEDIANCE_PASSWORD in a .env or the password key in config.json. This is mitigated well (both are gitignored; config set writes config.json at 0600; the token cache is 0600 and lives outside the working dir), but there's no option to keep the password in OS-encrypted storage. For an interactive/desktop user on a shared or backed-up machine, an encrypted-at-rest path would be a meaningful improvement.
Goal
Add an optional, opt-in OS keychain source for credentials, slotted into the existing resolution chain in internal/config/config.go (Load): defaults < config.json < .env < env vars < flags. Keychain would sit alongside config.json as an alternative credential store, not replace any layer.
Hard constraint — do not break headless/agent use
This is the key design requirement. The tool's primary consumer is OpenClaw / headless agents that can't unlock a keychain interactively. So:
Keychain must be strictly additive and opt-in. Env vars and .env remain first-class and must keep working with zero keychain involvement.
No code path may block on or require a keychain (no interactive unlock prompt in a data command — same reasoning as the login-prompt discussion: an agent would hang). If the keychain is locked/unavailable, fall through to the existing sources silently.
Precedence stays explicit and documented; keychain should not silently shadow an env var.
Suggested direction (not prescriptive)
A cross-platform lib like zalando/go-keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service) keeps it dependency-light and matches the "single static binary" goal — though the Linux Secret Service dependency on a running keyring daemon needs handling (graceful fall-through when absent, which also keeps CI/headless green).
Surface via an explicit action, e.g. speediance-cli config set --keychain password or a login --save-keychain, rather than implicit writes.
config show should report that a keychain credential is present (never its value), consistent with the existing password masking.
Cross-repo coordination
CLAUDE.md notes the config/auth/credential layer is shared byte-identical with the sibling google-health-cli via .claude/CLI_CONVENTIONS.md, and changes "go through the shared agent process so both copies stay in sync — do not edit one repo's copy unilaterally." A keychain source touches exactly that shared layer, so this likely needs to land as a coordinated change across both repos (or be designed so the shared invariants in CLI_CONVENTIONS.md still hold).
Notes
Per .claude/CLAWHUB_STANDARDS.md, ships with guard tests in the same PR — in particular a test asserting that with no keychain available the env/.env/config.json paths still resolve and nothing blocks (the headless-safety invariant).
Problem
Credentials currently live at rest in plaintext —
SPEEDIANCE_PASSWORDin a.envor thepasswordkey inconfig.json. This is mitigated well (both are gitignored;config setwritesconfig.jsonat0600; the token cache is0600and lives outside the working dir), but there's no option to keep the password in OS-encrypted storage. For an interactive/desktop user on a shared or backed-up machine, an encrypted-at-rest path would be a meaningful improvement.Goal
Add an optional, opt-in OS keychain source for credentials, slotted into the existing resolution chain in
internal/config/config.go(Load): defaults <config.json<.env< env vars < flags. Keychain would sit alongsideconfig.jsonas an alternative credential store, not replace any layer.Hard constraint — do not break headless/agent use
This is the key design requirement. The tool's primary consumer is OpenClaw / headless agents that can't unlock a keychain interactively. So:
.envremain first-class and must keep working with zero keychain involvement.login-prompt discussion: an agent would hang). If the keychain is locked/unavailable, fall through to the existing sources silently.Suggested direction (not prescriptive)
zalando/go-keyring(macOS Keychain, Windows Credential Manager, Linux Secret Service) keeps it dependency-light and matches the "single static binary" goal — though the Linux Secret Service dependency on a running keyring daemon needs handling (graceful fall-through when absent, which also keeps CI/headless green).speediance-cli config set --keychain passwordor alogin --save-keychain, rather than implicit writes.config showshould report that a keychain credential is present (never its value), consistent with the existing password masking.Cross-repo coordination
CLAUDE.mdnotes the config/auth/credential layer is shared byte-identical with the siblinggoogle-health-clivia.claude/CLI_CONVENTIONS.md, and changes "go through the shared agent process so both copies stay in sync — do not edit one repo's copy unilaterally." A keychain source touches exactly that shared layer, so this likely needs to land as a coordinated change across both repos (or be designed so the shared invariants inCLI_CONVENTIONS.mdstill hold).Notes
.claude/CLAWHUB_STANDARDS.md, ships with guard tests in the same PR — in particular a test asserting that with no keychain available the env/.env/config.jsonpaths still resolve and nothing blocks (the headless-safety invariant).0600-env/file is a reasonable default for the agent-first use case — this just adds a stronger option for interactive users.