diff --git a/AGENTS.md b/AGENTS.md index 0f7fd32..1f32b8b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,7 +49,14 @@ just lsp mac-mini # nixd option completion for VSCode ## Environment -1Password CLI `op inject` at shell startup. Template in `home/shell/fish.nix` → `~/.config/op-env/env.tpl` (`op://` refs, safe to commit). Auth via `OP_SERVICE_ACCOUNT_TOKEN` in `~/.config/fish/local.fish` (gitignored). +1Password CLI secrets are **cached locally** — shell startup reads `~/.cache/op-env/env.fish` (no network). + +- Template: `home/shell/fish.nix` → `~/.config/op-env/env.tpl` (`op://` refs, safe to commit) +- Cache: `~/.cache/op-env/env.fish` (plaintext, `chmod 600`, outside git/nix store) +- Auth: `OP_SERVICE_ACCOUNT_TOKEN` in `~/.config/fish/local.fish` (gitignored) +- Refresh: user runs `op-env-refresh` manually (needs network). Atomic write (mktemp + mv), failure keeps old cache. +- Clear: `op-env-clear` removes cache file. +- `local.fish` is sourced **after** the cache, so it can override env vars per-machine. ## Home Manager option API diff --git a/home/shell/fish.nix b/home/shell/fish.nix index 023f0b6..3baf189 100644 --- a/home/shell/fish.nix +++ b/home/shell/fish.nix @@ -51,13 +51,21 @@ in # Startup only sources the cache; run op-env-refresh manually to fetch/update. # Auth via OP_SERVICE_ACCOUNT_TOKEN (set it in ~/.config/fish/local.fish) function op-env-refresh --description "Fetch secrets from 1Password and cache locally" - if not type -q op; or not set -q OP_SERVICE_ACCOUNT_TOKEN; or not test -f "${envTpl}" - echo "op-env: need op CLI + OP_SERVICE_ACCOUNT_TOKEN" >&2 + if not type -q op + echo "op-env: op CLI not found in PATH" >&2 + return 1 + end + if not set -q OP_SERVICE_ACCOUNT_TOKEN; or test -z "$OP_SERVICE_ACCOUNT_TOKEN" + echo "op-env: OP_SERVICE_ACCOUNT_TOKEN is not set" >&2 + return 1 + end + if not test -f "${envTpl}" + echo "op-env: template not found: ${envTpl}" >&2 return 1 end set -l cache_dir (path dirname "${envCache}") if not mkdir -p "$cache_dir"; or not chmod 700 "$cache_dir" - echo "op-env: cannot create cache dir" >&2 + echo "op-env: cannot prepare cache dir: $cache_dir" >&2 return 1 end set -l tmp (mktemp "$cache_dir/.tmp.XXXXXX") @@ -65,20 +73,39 @@ in echo "op-env: mktemp failed" >&2 return 1 end - if op inject --in-file "${envTpl}" > "$tmp" 2>/dev/null - chmod 600 "$tmp" - mv "$tmp" "${envCache}" - source "${envCache}" - echo "op-env: refreshed" - else - rm -f "$tmp" - echo "op-env: failed (old cache kept)" >&2 + if not op inject --in-file "${envTpl}" > "$tmp" + command rm -f "$tmp" + echo "op-env: inject failed; old cache kept" >&2 return 1 end + # Capture old var names before replacing cache + set -l old_vars + if test -f "${envCache}" + set old_vars (string match -rg 'set -gx (\S+)' < "${envCache}") + end + if not mv "$tmp" "${envCache}" + command rm -f "$tmp" + echo "op-env: cannot replace cache file" >&2 + return 1 + end + for var in $old_vars + set -e $var + end + if not source "${envCache}" + echo "op-env: cache written but could not be sourced" >&2 + return 1 + end + echo "op-env: refreshed" end function op-env-clear --description "Clear cached secrets" - rm -f "${envCache}" + if test -f "${envCache}" + for var in (string match -rg 'set -gx (\S+)' < "${envCache}") + set -e $var + end + command rm -f "${envCache}" + end + echo "op-env: cleared" end # Source cached secrets (instant, no network)