diff --git a/README.md b/README.md index 6c76df0..3e07afc 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,11 @@ Already have a clone? Just run it directly: The first run prompts for the service-account token (and vault/item), and keeps them in `~/.config/dotfiles/op.env` (0600, not loaded into shells). Runs after `bin/` (needs `op` and `jq`); bootstrap loads the result so later - modules get the keys without prompting. Day to day: `envr NAME` reads a - field, `envc NAME [VALUE]` creates or updates one (prompts, hidden, without - VALUE), `envd NAME` deletes one; both of those refresh the file and this - shell. `envl [VAULT [ITEM]]` shows every field with its current value, and - `envs` refreshes after a change made elsewhere. No sudo. + modules get the keys without prompting. Day to day: `opr NAME` reads a + field, `opc NAME [VALUE]` creates or updates one (prompts, hidden, without + VALUE), `opd NAME` deletes one; both of those refresh the file and this + shell. `opl [VAULT [ITEM]]` shows every field with its current value, and + `ops` refreshes after a change made elsewhere. No sudo. opencode is configured by `mcp-config/`: it points at the covert-gpt LiteLLM gateway (`https://llm.covert-gpt.com/v1`) for models. MCP tools do diff --git a/secrets/install.sh b/secrets/install.sh index 5aea8ac..aa0f673 100755 --- a/secrets/install.sh +++ b/secrets/install.sh @@ -6,19 +6,19 @@ # field on EVERY new shell. That made each terminal wait on 1Password, broke # every shell when the network or the service account was down, and meant each # box carried its own hand-written copy of the loop. Now the vault is read once -# here (at bootstrap, or on demand with `envs`), and shells read a local file. +# here (at bootstrap, or on demand with `ops`), and shells read a local file. # # Layout: one vault per user (default: the login name), holding one item # (default: also the login name) whose field LABELS are the variable names — # GITEA_KEY, LITELLM_KEY, PROXMOX_TOKEN_SECRET, ... Every such field is -# exported. Add a secret by adding a field (`envc NAME`), not by editing +# exported. Add a secret by adding a field (`opc NAME`), not by editing # this repo. # # Files, all under ~/.config/dotfiles (0700), none in the repo: # op.env OP_SERVICE_ACCOUNT_TOKEN, OP_VAULT, OP_ITEM (0600). Kept so a # refresh needs no prompt. Deliberately NOT sourced by shells: # the token stays out of every process's environment, and only -# the env* helpers in zsh/zshrc load it, in a subshell. +# the op* helpers in zsh/zshrc load it, in a subshell. # secrets.env the exported fields (0600), replaced atomically, so a failed # fetch leaves the previous copy in place. # @@ -115,7 +115,7 @@ _tmp="$(mktemp "$CONF_DIR/secrets.env.XXXXXX")" trap 'rm -f "$_tmp"' EXIT { printf '# Generated by dotfiles secrets/install.sh from op://%s/%s — do not edit.\n' "$OP_VAULT" "$OP_ITEM" - printf '# Refresh with: envs (change the vault with: envc NAME / envd NAME)\n' + printf '# Refresh with: ops (change the vault with: opc NAME / opd NAME)\n' printf '%s' "$_json" | jq -r ' .fields[] | select(.purpose != "NOTES") diff --git a/zsh/zshrc b/zsh/zshrc index cc10594..d5422ff 100644 --- a/zsh/zshrc +++ b/zsh/zshrc @@ -76,38 +76,38 @@ grmb() { # Secrets from this user's 1Password vault, written by dotfiles/secrets/install.sh. # Reading a local 0600 file keeps shell startup off the network: nothing here -# calls op. envc/envd refresh the file themselves; after editing the vault -# anywhere else (the 1Password app, another box), run `envs`. +# calls op. opc/opd refresh the file themselves; after editing the vault +# anywhere else (the 1Password app, another box), run `ops`. _DOTFILES_CONF="$HOME/.config/dotfiles" [ -f "$_DOTFILES_CONF/secrets.env" ] && source "$_DOTFILES_CONF/secrets.env" -# envr NAME read one field straight from the vault -# envc NAME [VALUE] create or update a field (prompts, hidden, when VALUE is -# omitted, which keeps the secret out of shell history), -# then refresh and reload this shell -# envd NAME delete a field, refresh, and unset it in this shell -# envl [VAULT [ITEM]] show every field and its current value (default: your -# vault and item from op.env) -# envs re-fetch the vault into secrets.env and reload this shell +# opr NAME read one field straight from the vault +# opc NAME [VALUE] create or update a field (prompts, hidden, when VALUE is +# omitted, which keeps the secret out of shell history), +# then refresh and reload this shell +# opd NAME delete a field, refresh, and unset it in this shell +# opl [VAULT [ITEM]] show every field and its current value (default: your +# vault and item from op.env) +# ops re-fetch the vault into secrets.env and reload this shell # # The service-account token lives in op.env and is loaded only inside these # subshells, so it never lands in the environment of everything you run. _dotfiles_op() { - [ -f "$_DOTFILES_CONF/op.env" ] || { print -u2 "no $_DOTFILES_CONF/op.env; run: envs"; return 1; } + [ -f "$_DOTFILES_CONF/op.env" ] || { print -u2 "no $_DOTFILES_CONF/op.env; run: ops"; return 1; } ( set -a; source "$_DOTFILES_CONF/op.env"; set +a; "$@" ) } _dotfiles_env_name() { [[ "$1" =~ '^[A-Za-z_][A-Za-z0-9_]*$' ]] && return 0 print -u2 "$2: '$1' is not a valid variable name"; return 2 } -envr() { - _dotfiles_env_name "$1" envr || return - _dotfiles_op sh -c 'op read "op://$OP_VAULT/$OP_ITEM/$1"' envr "$1" +opr() { + _dotfiles_env_name "$1" opr || return + _dotfiles_op sh -c 'op read "op://$OP_VAULT/$OP_ITEM/$1"' opr "$1" } -envc() { +opc() { emulate -L zsh local name=$1 value - _dotfiles_env_name "$name" envc || return + _dotfiles_env_name "$name" opc || return if (( $# >= 2 )); then value=$2 else @@ -115,18 +115,18 @@ envc() { fi # [concealed] makes it a password field; an existing field of that name is updated. _dotfiles_op sh -c 'op item edit "$OP_ITEM" --vault "$OP_VAULT" "$1[concealed]=$2" >/dev/null' \ - envc "$name" "$value" && envs + opc "$name" "$value" && ops } -envd() { - _dotfiles_env_name "$1" envd || return - _dotfiles_op sh -c 'op item edit "$OP_ITEM" --vault "$OP_VAULT" "$1[delete]" >/dev/null' envd "$1" \ - && unset "$1" && envs +opd() { + _dotfiles_env_name "$1" opd || return + _dotfiles_op sh -c 'op item edit "$OP_ITEM" --vault "$OP_VAULT" "$1[delete]" >/dev/null' opd "$1" \ + && unset "$1" && ops } -envl() { +opl() { _dotfiles_op sh -c ' vault=${1:-$OP_VAULT} item=${2:-$OP_ITEM} printf "op://%s/%s\n" "$vault" "$item" >&2 - op item get "$item" --vault "$vault" --reveal --format json' envl "$@" \ + op item get "$item" --vault "$vault" --reveal --format json' opl "$@" \ | jq -r ' [.fields[] | select(.purpose != "NOTES")] as $f | ([$f[] | .label // "" | length] | max // 0) as $w @@ -136,7 +136,7 @@ envl() { | "\($name) \($lines[0] // "")", ($lines[1:][] | (" " * ($w + 2)) + .)' } -envs() { +ops() { "${DOTFILES_DIR:-$HOME/.dotfiles}/secrets/install.sh" \ && source "$_DOTFILES_CONF/secrets.env" } diff --git a/zsh/zshrc.local.example b/zsh/zshrc.local.example index 59d143c..f67dfde 100644 --- a/zsh/zshrc.local.example +++ b/zsh/zshrc.local.example @@ -36,7 +36,7 @@ # Nothing to set here. Do NOT loop over `op read` in this file: that ran on # every shell. secrets/install.sh stores the service-account token in # ~/.config/dotfiles/op.env and writes the vault's fields to secrets.env, which -# the managed ~/.zshrc loads. Use envr / envc / envd (see zsh/zshrc). +# the managed ~/.zshrc loads. Use opr / opc / opd (see zsh/zshrc). # --- Proxmox ------------------------------------------------------------- # One pair of credentials, several consumers: the proxmox MCP server