Files
sherlock/docs/storage.md
T
amacocian 154412b0a7
CI / build (push) Successful in 7s
Drop profiles
2026-05-25 10:14:39 +02:00

2.7 KiB

Storage

How sherlock persists secrets and runtime state.

Decisions

Topic Decision
Token storage OS keyring via github.com/zalando/go-keyring. No on-disk credential files, no age blobs, no plaintext.
Pre-flight Both sherlock and sherlock-broker call keyring.Probe() at startup. A missing/locked keyring fails fast with a platform-appropriate hint and exit code 3.
Service name sherlock for real tokens; sherlock-preflight for the probe sentinel.
Account key The Authentik sub claim once logged in, default before.
Runtime files $XDG_RUNTIME_DIR/sherlock.sock, sherlock.pid, sherlock.log, sherlock/<agent>.mcp.json. All 0600 (files) / 0700 (dirs).
Config files $XDG_CONFIG_HOME/sherlock/services.d/*.toml (operator-registered services, Phase 2+). Agent integrations are compiled in — see agents.md.

TokenSet

What we store under the sherlock keyring service:

type TokenSet struct {
    IDToken      string
    AccessToken  string
    RefreshToken string
    IDExpiresAt  time.Time
    RefreshExpAt time.Time
    Issuer       string
    Subject      string
    Email        string
    Name         string
}

Serialized as a single JSON blob — the keyring exposes one secret per (service, account) pair and we don't want to round-trip multiple secrets.

Pre-flight semantics

keyring.Probe():

  1. Writes a fixed sentinel value under service sherlock-preflight, account probe.
  2. Reads it back, verifies the round-trip.
  3. Deletes it.

If any step fails the call returns keyring.ErrUnavailable wrapping the underlying cause. keyring.IsUnavailable(err) is the test; keyring.RemediationHint() returns a per-OS one-liner.

CLI behaviour: any failure prints the wrapped error and the hint, then exits with code 3.

Platform notes

OS Backend Common setup snag
Linux Secret Service (D-Bus) gnome-keyring-daemon, KWallet, or keepassxc with Secret Service enabled must be running for the session. Headless boxes need gnome-keyring-daemon --components=secrets started inside the session bus.
macOS Keychain Works out of the box. First write may prompt for unlock.
Windows Credential Manager Works out of the box.

Why not files

We considered an age-encrypted token blob and dropped it: the keyring gives us OS-managed locking, session affinity, and consistent multi-user behaviour for free, and avoids inventing a new key management story. The trade-off — Linux headless setups need a deliberate session keyring — is the right one for a homelab operator tool where the operator already has a desktop session.