diff --git a/git/install.sh b/git/install.sh index b3925fb..a242461 100755 --- a/git/install.sh +++ b/git/install.sh @@ -30,4 +30,25 @@ say "fetch.prune = true (stale remote-tracking refs cleaned on every fetch)" git config --global credential.helper store say "credential.helper = store (~/.git-credentials, created on first auth)" -say "Done. On the next HTTPS push/pull to a new host, git prompts once and caches the credential in ~/.git-credentials." +# Our own Gitea authenticates from $GITEA_KEY (exported by secrets/ from the +# vault), not from ~/.git-credentials. +# +# WHY: git never reads GITEA_KEY by itself. With only `store`, the token was +# whatever got typed at the first prompt, copied into ~/.git-credentials, and +# it silently went stale when the vault's key was rotated — or, on a box that +# never pushed, there was no credential at all and the push just failed. Now +# `opc GITEA_KEY` is the only step when the token changes. +# +# The empty helper first clears the inherited `store` for this host, so a +# rejected token is never cached and a stale cached one can never win. Gitea +# accepts the token as the password; the username is informational (GITEA_USER +# overrides it). With GITEA_KEY unset the helper prints nothing and git falls +# back to prompting, as before. +GITEA_URL="https://git.nic-oconnor.com" +git config --global --unset-all "credential.$GITEA_URL.helper" 2>/dev/null || true +git config --global --add "credential.$GITEA_URL.helper" '' +git config --global --add "credential.$GITEA_URL.helper" \ + '!f() { test "$1" = get && test -n "${GITEA_KEY:-}" && printf "username=%s\npassword=%s\n" "${GITEA_USER:-$(id -un)}" "$GITEA_KEY"; }; f' +say "credential helper for $GITEA_URL = \$GITEA_KEY (from secrets.env)" + +say "Done. $GITEA_URL uses \$GITEA_KEY; other HTTPS hosts prompt once and cache in ~/.git-credentials."