Skip to content

Daemon should use OS keychain when available (Mac mini, MacBook, Raspberry Pi) #12

@hanwencheng

Description

@hanwencheng

Problem

Two related issues with daemon session storage:

1. No keychain support on capable machines

The daemon (agentkeys-daemon) always stores its child session as a plain file at ~/.agentkeys/session (mode 0600). The CLI (agentkeys-cli) uses the OS keychain by default with file fallback.

The spec assumes "daemon = Docker/cloud sandbox = no keychain," but daemons also run on:

  • Mac mini (macOS Keychain available)
  • Another MacBook (macOS Keychain available)
  • Raspberry Pi (Linux secret-service / gnome-keyring available)

In these cases, plain file storage is unnecessarily weak.

2. Multiple daemons on one machine collide

All daemons write to the same path: ~/.agentkeys/session. Running two agent daemons on the same Mac mini means the second daemon overwrites the first's session token. This breaks the multi-agent isolation use case the spec explicitly requires:

"explicit (needed if multiple agents are attached to the same machine)" -- 1-step-analysis.md:221

"Multi-agent isolation E2E: two agents, each with different credentials, scope enforcement verified" -- development-stages.md:623

The multi-agent demo (Demo 1) requires N agents on one host, each with independent sessions and scoped credentials.

Current behavior

Binary Session storage Keychain Multi-instance
agentkeys-cli Keychain-first, file fallback Yes (keyring crate, 2s timeout) N/A (single master)
agentkeys-daemon Plain file only No Broken (all write to same path)

Proposed fix

Wallet-based session isolation

Use the wallet address to namespace sessions. Each daemon gets its own storage slot:

Role Keychain entry File fallback
Master (CLI) service=agentkeys, account=master ~/.agentkeys/master/session.json
Daemon (per agent) service=agentkeys, account=daemon-<wallet> ~/.agentkeys/daemon-<wallet>/session.json

This supports:

  • One master + one daemon on a laptop (current use case)
  • One master + N daemons on a Mac mini (multi-agent use case)
  • N daemons, no master on a cloud VM (headless multi-agent)

Step 1: Move session_store to agentkeys-core

Move session_store.rs from agentkeys-cli to agentkeys-core so both CLI and daemon share the same keychain-first, file-fallback logic.

The shared module should accept a session_id: &str parameter to distinguish entries:

pub fn save_session(session: &Session, session_id: &str) -> Result<()>
pub fn load_session(session_id: &str) -> Result<Session>

Keychain entry: service=agentkeys, account=<session_id>
File fallback: ~/.agentkeys/<session_id>/session.json

Step 2: Update CLI to use named session

session_store::save_session(&session, "master")?;
session_store::load_session("master")?;

Step 3: Update daemon to use wallet-based session

The daemon learns its wallet after pairing/recovery. Before that, it uses a temp session ID, then renames after wallet is known:

// After pair/recover completes and wallet is known:
session_store::save_session(&session, &format!("daemon-{}", wallet.0))?;

For --recover <identity>, the daemon can pre-resolve the wallet via identity lookup and use it from the start.

Step 4: Env var override

The AGENTKEYS_SESSION_STORE=file env var continues to force file-only mode for CI/Docker/headless environments.

Affected deployment environments

Environment Keychain available Multi-daemon Expected behavior
macOS (MacBook, Mac mini) Yes (macOS Keychain) Yes Keychain with wallet-based accounts
Linux desktop (Raspberry Pi with GUI) Yes (gnome-keyring / KDE Wallet) Yes secret-service via keyring crate
Linux server (headless) No Yes File fallback with wallet-based paths
Docker container No One per container File fallback
Cloud LLM sandbox No One per sandbox File fallback
CI (GitHub Actions) No N/A File fallback via AGENTKEYS_SESSION_STORE=file

Documentation updates

  • docs/spec/architecture.md -- update daemon session storage to reflect keychain-first + wallet-based isolation
  • wiki/key-security.md -- update storage table, document session naming scheme
  • docs/manual-test-stage4.md -- add test cases: (1) daemon keychain on macOS, (2) master + daemon coexistence, (3) two daemons on same machine
  • docs/spec/plans/development-stages.md -- note as Stage 4 hardening item

Context

  • CLI session store: crates/agentkeys-cli/src/session_store.rs (keychain-first pattern to reuse)
  • Daemon session store: crates/agentkeys-daemon/src/session.rs (file-only, needs upgrade)
  • Security spec: wiki/key-security.md
  • Multi-agent isolation: docs/spec/1-step-analysis.md:221, docs/spec/plans/development-stages.md:623

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions