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
136 lines
4.5 KiB
Bash
136 lines
4.5 KiB
Bash
#!/usr/bin/env bash
|
|
# agent-profile.sh — switch agent identity context.
|
|
#
|
|
# Source this script to become a specific agent. Sets git author/committer
|
|
# identity, registers a tea login (from Bitwarden), and exports the agent
|
|
# name for other tools (bw-run.sh, clone-as.sh, etc.).
|
|
#
|
|
# Usage:
|
|
# . agent-profile.sh vp-techops
|
|
# . agent-profile.sh vp-secops
|
|
# . agent-profile.sh reachableceo (back to Charles's identity)
|
|
#
|
|
# Prerequisites:
|
|
# - Bitwarden session active (BW_SESSION exported) OR BW_CLIENTID/
|
|
# BW_CLIENTSECRET in ~/.config/bw/env
|
|
# - Agent credentials provisioned in Bitwarden (see agent-identity-bootstrap.md)
|
|
|
|
# Do NOT set -euo pipefail — this script is sourced, and the caller controls
|
|
# their own shell options. We guard each operation explicitly.
|
|
|
|
AGENT_PROFILE_NAME="${1:-}"
|
|
|
|
if [ -z "$AGENT_PROFILE_NAME" ]; then
|
|
echo "Usage: . agent-profile.sh <agent-name>" >&2
|
|
echo " e.g. . agent-profile.sh vp-techops" >&2
|
|
echo " . agent-profile.sh reachableceo" >&2
|
|
# shellcheck disable=SC2317 # reachable when executed (not sourced)
|
|
return 1 2>/dev/null || exit 1
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Display name mapping (for git author name)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
case "$AGENT_PROFILE_NAME" 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="$AGENT_PROFILE_NAME"
|
|
;;
|
|
esac
|
|
|
|
# Domain mapping
|
|
_domain="turnsys.com"
|
|
if [ "$AGENT_PROFILE_NAME" = "reachableceo" ]; then
|
|
_email="reachableceo@turnsys.com"
|
|
else
|
|
_email="${AGENT_PROFILE_NAME}@${_domain}"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Export agent identity environment variables
|
|
# ---------------------------------------------------------------------------
|
|
|
|
export AGENT_NAME="$AGENT_PROFILE_NAME"
|
|
export AGENT_DISPLAY="$_display"
|
|
export AGENT_EMAIL="$_email"
|
|
export GIT_AUTHOR_NAME="$_display"
|
|
export GIT_COMMITTER_NAME="$_display"
|
|
export GIT_AUTHOR_EMAIL="$_email"
|
|
export GIT_COMMITTER_EMAIL="$_email"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Ensure Bitwarden session is active
|
|
# ---------------------------------------------------------------------------
|
|
|
|
_bw_session_setup() {
|
|
if [ -n "${BW_SESSION:-}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
local 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
|
|
BW_SESSION=$(BW_PASSWORD="${BW_PASSWORD:-}" bw unlock --raw 2>/dev/null || true)
|
|
if [ -n "$BW_SESSION" ]; then
|
|
export BW_SESSION
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
echo "agent-profile: WARNING — no BW session, tea login will not be configured" >&2
|
|
return 1
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Register tea login for this agent (if credentials exist in BW)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
_tea_setup() {
|
|
# Only set up tea for agents that have Gitea credentials in BW
|
|
local token
|
|
token=$(bw get password "${AGENT_NAME} Gitea" 2>/dev/null || echo "")
|
|
if [ -z "$token" ]; then
|
|
# Not an error — some agents may not have Gitea access yet
|
|
return 0
|
|
fi
|
|
|
|
# Check if login already exists
|
|
if tea login list --output csv 2>/dev/null | grep -q "^${AGENT_NAME},"; then
|
|
# Already registered — just set as default
|
|
tea login default "$AGENT_NAME" >/dev/null 2>&1 || true
|
|
return 0
|
|
fi
|
|
|
|
# Register the login
|
|
tea login add \
|
|
--name "$AGENT_NAME" \
|
|
--url "https://git.knownelement.com" \
|
|
--token "$token" \
|
|
--ssh-host "git.knownelement.com" \
|
|
>/dev/null 2>&1 || true
|
|
|
|
tea login default "$AGENT_NAME" >/dev/null 2>&1 || true
|
|
}
|
|
|
|
if _bw_session_setup; then
|
|
_tea_setup
|
|
fi
|
|
|
|
# Clean up helper functions from the environment
|
|
unset -f _bw_session_setup _tea_setup 2>/dev/null || true
|
|
unset _display _email _domain 2>/dev/null || true
|
|
|
|
echo "agent-profile: now operating as ${AGENT_PROFILE_NAME} (${AGENT_DISPLAY})" >&2
|