Template
feat: add per-agent git identity tooling [#442]
Three scripts that let multiple AI agents share a single Linux account
while maintaining per-identity attribution for all git operations:
- bw-git-credential.sh: git credential helper that sources Gitea tokens
from Bitwarden based on the repo's user.email config. Handles both
push (reads repo config) and clone (reads AGENT_CLONE_AS env var).
- agent-profile.sh: sourceable context switcher. Sets git author/
committer identity, registers tea login from BW, exports AGENT_NAME.
- clone-as.sh: clone wrapper that authenticates with the agent's BW
token, sets per-repo identity, strips token from remote URL.
No SSH key juggling, no tokens on disk, no multiple Linux accounts.
All credential material stays in Bitwarden.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
# bw-git-credential.sh — Git credential helper that sources Gitea tokens from Bitwarden.
|
||||
#
|
||||
# This eliminates the need for per-agent SSH keys or on-disk tokens for git
|
||||
# operations. Each repo has a git identity (user.email) that identifies which
|
||||
# agent is working. This helper reads that identity, fetches the matching
|
||||
# Gitea API token from Bitwarden, and provides it to git.
|
||||
#
|
||||
# Setup (once per environment, in ~/.gitconfig):
|
||||
# [credential "https://git.knownelement.com"]
|
||||
# helper = /path/to/bw-git-credential.sh
|
||||
#
|
||||
# How it works:
|
||||
# - During git push (in an existing repo): reads `git config user.email`
|
||||
# to determine the agent, fetches "<agent> Gitea" from Bitwarden.
|
||||
# - During git clone (no repo yet): reads AGENT_CLONE_AS env var, which
|
||||
# clone-as.sh sets before calling git clone.
|
||||
# - If neither is set, exits silently (lets other credential helpers run).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_HOST="git.knownelement.com"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Read git credential input from stdin
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
declare -A cred
|
||||
while IFS='=' read -r key value; do
|
||||
# Empty line terminates the credential block
|
||||
[ -z "$key" ] && break
|
||||
cred["$key"]="$value"
|
||||
done
|
||||
|
||||
host="${cred[protocol]:-}://${cred[host]:-}"
|
||||
|
||||
# Only handle our Gitea instance
|
||||
if [ "${cred[host]:-}" != "$GITEA_HOST" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Determine which agent identity to use
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
agent=""
|
||||
|
||||
# During clone: clone-as.sh sets this env var
|
||||
if [ -n "${AGENT_CLONE_AS:-}" ]; then
|
||||
agent="$AGENT_CLONE_AS"
|
||||
else
|
||||
# During push/fetch: read the repo's configured identity
|
||||
agent_email=$(git config user.email 2>/dev/null || echo "")
|
||||
if [ -n "$agent_email" ]; then
|
||||
agent=$(echo "$agent_email" | cut -d@ -f1)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$agent" ]; then
|
||||
# No agent identity — let other credential helpers handle it
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Ensure Bitwarden session is active
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if [ -z "${BW_SESSION:-}" ]; then
|
||||
# Try to establish from the env file
|
||||
bw_env="${HOME}/.config/bw/env"
|
||||
if [ -f "$bw_env" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$bw_env"
|
||||
fi
|
||||
|
||||
if [ -n "${BW_CLIENTID:-}" ] && [ -n "${BW_CLIENTSECRET:-}" ]; then
|
||||
bw login --apikey >/dev/null 2>&1 || true
|
||||
export BW_SESSION
|
||||
BW_SESSION=$(BW_PASSWORD="${BW_PASSWORD:-}" bw unlock --raw 2>/dev/null || true)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${BW_SESSION:-}" ]; then
|
||||
echo "bw-git-credential: no BW session — cannot fetch token for $agent" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Fetch the Gitea token from Bitwarden
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
item_name="$agent Gitea"
|
||||
token=$(bw get password "$item_name" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$token" ]; then
|
||||
echo "bw-git-credential: no Gitea token in BW for: $item_name" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Output credentials for git
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
echo "username=$agent"
|
||||
echo "password=$token"
|
||||
Reference in New Issue
Block a user