Technology Apr 26, 2026 · 5 min read

How are you managing git & gh access with Agents?

TLDR - I want to steal your Git workflows for agents. I talk about some of my config and setup recently, but I'm still not fully happy with where I'm at. My setup was treating "AI Agent" and "Me" at the same level of trust. Local tools can push code, create PRs, and act as me on GitHub with almost...

DE
DEV Community
by Ryan Swift
How are you managing git & gh access with Agents?

TLDR - I want to steal your Git workflows for agents. I talk about some of my config and setup recently, but I'm still not fully happy with where I'm at.

My setup was treating "AI Agent" and "Me" at the same level of trust. Local tools can push code, create PRs, and act as me on GitHub with almost no friction. That's starting to feel sketchy, and I don't want to waste maintainers' time with slop PRs.

I've had pretty persistent imposter syndrome as a developer. At work I've managed our internal ERP (Zoho Creator if you're curious) for years, which has tens of thousands of lines of code at this point. But I've never quite felt like I do 'real' dev work.

I've helped thousands of next-gen devs with their projects at hackathons. I am pretty good at fixing folks' Git issues in the wild. Historically though, Git was not a tool I needed heavily day to day. That's been changing recently with AI coding agents.

Recently, I embarrassed myself with a few slop PRs opened without human review. I didn't realize what my agents were doing with my GitHub identity, which is the actual problem. Nothing catastrophic, but I don't want a reputation and I don't want to bug maintainers.

Ambient Authority

Most AI agents just "ambiently" inherit your authority. They use your SSH agent, your gh tokens, and your Git identity/config.

For local edits and personal projects, that's great. For open source and published repos, it's dangerous. Agents had the same level of access that I had as a human user.

I had one too many slop PRs out there in my name, and wanted to update my workflow.

Current Setup

  1. Action Split: I forced all pushes to a passphrase-protected SSH key while keeping other actions like fetches on HTTPS. This means pulls are silent and low-friction, but pushes should hit both a human confirmation step and the passphrase-protected SSH key.
  2. SSH Passphrase: I created a dedicated key for GitHub and told SSH not to use my running SSH agent for that key (IdentityAgent none). It's intentionally inconvenient; every push requires a passphrase.
  3. Read-Only CLI: I swapped my main gh CLI auth for a Fine-Grained Token that is strictly read-only. Agents can see PR status, but gh pr create now fails server-side.
  4. A Pre-Push Hook: More on this below since it's the piece I'm most chuffed with!

The Read-Only CLI is suddenly the most inconvenient part of my workflow right now. If anyone has advice on better controlling gh CLI, I'd love to hear about it.

What I really want is a way to let agents inspect issues, PRs, checks, and reviews, while requiring human confirmation for anything that writes to GitHub.

Pre-Push Hook

I wrote a global Git hook that intercepts pushes, checks for a graphical session, and gets explicit approval from the user.

Instead of a generic passphrase prompt, I get a popup that shows me a summary of what is being pushed and where. If an agent tries to push in the background, it hits both the confirmation dialog and the SSH passphrase prompt.

If you're on Linux (KDE), you can use this. If you're on GNOME, just swap kdialog for zenity. I would still read the hook first unless you trust my agents.

The Hook (~/.config/git/hooks/pre-push):

#!/usr/bin/env bash
set -euo pipefail

remote_name=${1:-unknown}
remote_url=${2:-unknown}
repo_path=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
branch=$(git branch --show-current 2>/dev/null || true)
zero=0000000000000000000000000000000000000000

# Capture the refs being pushed
updates_file=$(mktemp)
trap 'rm -f "$updates_file"' EXIT
cat >"$updates_file"

# Generate a short summary of the ref updates and new commits
summary=$(while read -r local_ref local_oid remote_ref remote_oid; do
  if [ "$local_oid" = "$zero" ]; then
    printf -- '- Delete %s\n' "$remote_ref"
  elif [ "${remote_oid:-}" = "$zero" ]; then
    printf -- '- Create %s\n' "$remote_ref"
    git log --format='  - %s' -n 5 "$local_oid" 2>/dev/null || true
  else
    printf -- '- Update %s\n' "$remote_ref"
    git log --format='  - %s' -n 5 "$remote_oid..$local_oid" 2>/dev/null || true
  fi
done <"$updates_file" | awk '!seen[$0]++')

message=$(cat <<EOF
Git push requested from $repo_path

Branch: ${branch:-detached HEAD}
Remote: $remote_name ($remote_url)

Summary of push:
${summary:-No ref updates found}

Allow this push?
EOF
)

# 1. Try KDE Popup
if [ -n "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ] && command -v kdialog >/dev/null 2>&1; then
  if kdialog --title "Git Push Confirmation" --warningcontinuecancel "$message"; then
    exit 0
  fi
  exit 1
fi

# 2. Fallback to Terminal
if [ -r /dev/tty ] && [ -w /dev/tty ]; then
  printf '%s\n\nType '\''push'\'' to continue: ' "$message" >/dev/tty
  read -r answer </dev/tty
  [ "$answer" = "push" ] && exit 0
fi

# 3. Fail closed if non-interactive
echo "Push blocked: No human confirmation available." >&2
exit 1

To make this work across every project on your machine, just run:

git config --global core.hooksPath ~/.config/git/hooks

This is not a security boundary. A process running as me can bypass hooks with --no-verify or modify my Git config. I'm treating this as a safety check: it catches accidental or low-effort agent actions during normal pushes, but I still rely on GitHub permissions and branch protection for anything important.

How are you handling Git access and authorship?

I'm spending a couple of cycles thinking about the "process" of coding right now. I am trying to build a more robust setup for my own projects. This Git hangup is part of that, but it still doesn't feel solved. Do you have a better setup? Let me steal it please!

DE
Source

This article was originally published by DEV Community and written by Ryan Swift.

Read original article on DEV Community
Back to Discover

Reading List