From aec2625eaad65595bf4b24a1ab5279a941aaad11 Mon Sep 17 00:00:00 2001 From: imbytecat Date: Wed, 15 Apr 2026 03:10:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(shell):=201Password=20=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=94=B9=E4=B8=BA=E6=9C=AC=E5=9C=B0=E7=BC=93?= =?UTF-8?q?=E5=AD=98=EF=BC=8C=E6=94=AF=E6=8C=81=E7=A6=BB=E7=BD=91=E4=BD=BF?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - op inject 结果缓存到 ~/.cache/op-env/env.fish,shell 启动不再联网 - 新增 op-env-refresh(手动刷新)和 op-env-clear(清除缓存) - mktemp + mv 原子写入,刷新失败保留旧缓存 - 更新 README 文档匹配新行为 --- README.md | 11 ++++++++-- home/shell/fish.nix | 52 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3c71650..327e8e6 100644 --- a/README.md +++ b/README.md @@ -104,14 +104,21 @@ Fish + Starship + Atuin + Zoxide + FZF + Direnv,Catppuccin Mocha 主题。 ## Environment -1Password CLI `op inject` 在 Fish 启动时注入环境变量。 +1Password CLI `op inject` 获取环境变量,本地缓存后离线可用。 模板文件 `~/.config/op-env/env.tpl` 由 `home/shell/fish.nix` 生成,仅包含 `op://` 引用,可安全提交。 +Shell 启动时只读取本地缓存(`~/.cache/op-env/env.fish`),不联网。首次使用或密钥变更后需手动刷新: + +```bash +op-env-refresh # 从 1Password 获取并缓存(需联网) +op-env-clear # 清除本地缓存 +``` + 认证需要在 `~/.config/fish/local.fish`(gitignored)中设置: ```bash set -gx OP_SERVICE_ACCOUNT_TOKEN "your-service-account-token" ``` -未设置 token 时 `op-env` 静默跳过,不影响使用。 +未设置 token 时 `op-env-refresh` 会提示错误,不影响已有缓存的正常使用。 diff --git a/home/shell/fish.nix b/home/shell/fish.nix index ab3960e..023f0b6 100644 --- a/home/shell/fish.nix +++ b/home/shell/fish.nix @@ -2,6 +2,7 @@ let envTpl = "${config.xdg.configHome}/op-env/env.tpl"; + envCache = "${config.xdg.cacheHome}/op-env/env.fish"; in { # ── 1Password env template ────────────────────────── @@ -46,20 +47,49 @@ in alias pbpaste "powershell.exe -noprofile -c Get-Clipboard" end - # User-local overrides + # 1Password → env vars (cached locally, no network on shell start) + # 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 + 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 + return 1 + end + set -l tmp (mktemp "$cache_dir/.tmp.XXXXXX") + or begin + 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 + return 1 + end + end + + function op-env-clear --description "Clear cached secrets" + rm -f "${envCache}" + end + + # Source cached secrets (instant, no network) + if test -f "${envCache}" + source "${envCache}" + end + + # User-local config (OP_SERVICE_ACCOUNT_TOKEN, per-machine overrides) if test -f ~/.config/fish/local.fish source ~/.config/fish/local.fish end - - # 1Password → env vars (single op call, silent on failure) - # Auth via OP_SERVICE_ACCOUNT_TOKEN (set it in ~/.config/fish/local.fish) - function op-env --description "Load secrets from 1Password" - if not type -q op; or not set -q OP_SERVICE_ACCOUNT_TOKEN; or not test -f ${envTpl} - return 1 - end - op inject --in-file ${envTpl} 2>/dev/null | source - end - op-env ''; }; }