Template
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
140 lines
4.5 KiB
Bash
Executable File
140 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# clone-as.sh — clone a git repository as a specific agent identity.
|
|
#
|
|
# Wraps `git clone` so the clone authenticates with the agent's Gitea token
|
|
# (from Bitwarden) and the resulting repo has the correct per-repo git
|
|
# identity (user.name + user.email) set automatically.
|
|
#
|
|
# Usage:
|
|
# clone-as.sh <agent> <repo-url> [target-dir]
|
|
#
|
|
# Examples:
|
|
# clone-as.sh vp-techops https://git.knownelement.com/KNEL/PFVCluster.git
|
|
# clone-as.sh vp-techops https://git.knownelement.com/KNEL/PFVCluster.git ~/projects/pfv
|
|
# clone-as.sh reachableceo ssh://git@git.knownelement.com:29418/KNEL/PFVCluster.git
|
|
#
|
|
# After cloning, subsequent `git push` uses bw-git-credential.sh (configured
|
|
# in ~/.gitconfig) which reads the repo's user.email to fetch the token.
|
|
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
# shellcheck disable=SC1091
|
|
source "$HERE/lib/common.sh"
|
|
|
|
###############################################################################
|
|
|
|
if [ $# -lt 2 ]; then
|
|
sed -n '2,22p' "$0"
|
|
exit 1
|
|
fi
|
|
|
|
CLONE_AGENT="$1"
|
|
CLONE_URL="$2"
|
|
CLONE_DIR="${3:-}"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Display name mapping
|
|
# ---------------------------------------------------------------------------
|
|
|
|
case "$CLONE_AGENT" in
|
|
vp-techops) display="VP TechOps" ;;
|
|
vp-secops) display="VP SecOps" ;;
|
|
vp-techcompliance) display="VP TechCompliance" ;;
|
|
coo) display="Chief Operating Officer" ;;
|
|
svp-knel) display="SVP KNEL" ;;
|
|
svp-tctc) display="SVP TCTC" ;;
|
|
reachableceo) display="Charles N Wyble" ;;
|
|
*) display="$CLONE_AGENT" ;;
|
|
esac
|
|
|
|
if [ "$CLONE_AGENT" = "reachableceo" ]; then
|
|
email="reachableceo@turnsys.com"
|
|
else
|
|
email="${CLONE_AGENT}@turnsys.com"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# If SSH URL, clone directly (SSH key auth, no credential helper needed)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
if [[ "$CLONE_URL" == ssh://* ]] || [[ "$CLONE_URL" == git@* ]]; then
|
|
log_info "Cloning (SSH): $CLONE_URL as $CLONE_AGENT"
|
|
|
|
if [ -n "$CLONE_DIR" ]; then
|
|
git clone "$CLONE_URL" "$CLONE_DIR"
|
|
cd "$CLONE_DIR"
|
|
else
|
|
git clone "$CLONE_URL"
|
|
# Derive repo dir name from URL
|
|
repo_base=$(basename "$CLONE_URL" .git)
|
|
cd "$repo_base"
|
|
fi
|
|
|
|
# Set per-repo identity
|
|
git config user.name "$display"
|
|
git config user.email "$email"
|
|
log_ok "Cloned to $(pwd) — identity: $display <$email>"
|
|
exit 0
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# HTTPS URL — need credential helper for clone authentication
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Ensure Bitwarden session
|
|
if [ -z "${BW_SESSION:-}" ]; then
|
|
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
|
|
die "No BW session — cannot fetch Gitea token for $CLONE_AGENT"
|
|
fi
|
|
|
|
# Fetch token for clone auth
|
|
token=$(bw get password "$CLONE_AGENT Gitea" 2>/dev/null || echo "")
|
|
if [ -z "$token" ]; then
|
|
die "No Gitea token in BW for: $CLONE_AGENT Gitea"
|
|
fi
|
|
|
|
log_info "Cloning (HTTPS): $CLONE_URL as $CLONE_AGENT"
|
|
|
|
# Set AGENT_CLONE_AS so bw-git-credential.sh knows which agent this is
|
|
# (needed only if the credential helper is wired; we also inject directly)
|
|
export AGENT_CLONE_AS="$CLONE_AGENT"
|
|
|
|
# Inject token into URL for clone auth, then strip after clone
|
|
# (avoids storing the token in .git/config)
|
|
url_path="${CLONE_URL#https://}"
|
|
injected_url="https://${CLONE_AGENT}:${token}@${url_path}"
|
|
|
|
if [ -n "$CLONE_DIR" ]; then
|
|
git clone "$injected_url" "$CLONE_DIR"
|
|
cd "$CLONE_DIR"
|
|
else
|
|
git clone "$injected_url"
|
|
repo_base=$(basename "$CLONE_URL" .git)
|
|
cd "$repo_base"
|
|
fi
|
|
|
|
# Strip the token from the remote URL (so it's not stored in .git/config)
|
|
remote_url=$(git remote get-url origin 2>/dev/null || echo "")
|
|
clean_url="https://${remote_url#https://*@}"
|
|
git remote set-url origin "$clean_url"
|
|
|
|
# Set per-repo identity
|
|
git config user.name "$display"
|
|
git config user.email "$email"
|
|
|
|
log_ok "Cloned to $(pwd) — identity: $display <$email>"
|
|
log_info "Remote URL sanitized (token stripped). Push will use bw-git-credential.sh."
|