Give AI agents their own bot identity when committing and pushing to GitHub.
AgentGit authenticates as a GitHub App using the JWT-to-installation-token flow, then commits and pushes with the app's bot identity. No more AI commits showing up as a human.
git commit -m "message"
|
v
AgentGit intercepts (via hook or direct invocation)
|
v
Generate JWT (RSA + Client ID)
|
v
Look up installation for target repo
|
v
Exchange JWT for installation token
|
v
git commit as YourApp[bot] with bot email
|
v
git push with token auth (via GIT_ASKPASS)
Commits appear as your GitHub App bot — e.g., stand-sure-ai[bot] — with the proper @users.noreply.github.com email, just like other GitHub App bots (Dependabot, Renovate, etc.).
You need a GitHub App to give your agent its own identity. This takes about 5 minutes.
- Go to GitHub Settings > Developer settings > GitHub Apps > New GitHub App
- Direct link: https://github.com/settings/apps/new
- Fill in:
- GitHub App name: Something like
my-agentormy-org-ai-bot(this becomes the[bot]name in commits) - Homepage URL: Your repo URL or any URL
- Webhook: Uncheck "Active" (AgentGit doesn't need webhooks)
- GitHub App name: Something like
Under Repository permissions, set:
| Permission | Access | Why |
|---|---|---|
| Contents | Read & Write | Commit and push to repositories |
That's it — no other permissions needed.
Under Where can this GitHub App be installed?:
- Only on this account — if you only need it for your personal repos
- Any account — if you want to install it on organizations too
Click Create GitHub App.
After creation, you'll be on the app's settings page. Note these values:
| Setting | Where to find it | Example |
|---|---|---|
| App ID | General > About > App ID | 123456 |
| Client ID | General > About > Client ID | Iv23liXXXXXXXXXXXXXX |
| App name | The slug in the URL (see below) | my-agent |
Note: For personal apps, the settings URL is
github.com/settings/apps/<name>. For org-owned apps, it'sgithub.com/organizations/<org>/settings/apps/<name>.
- On the app settings page, scroll to Private keys
- Click Generate a private key
- A
.pemfile downloads — save it somewhere secure - Set permissions:
chmod 600 /path/to/your-key.pem(AgentGit enforces this)
- In the app settings, click Install App in the left sidebar
- Choose the account/organization
- Select All repositories or Only select repositories
- Click Install
Repeat for each organization you want the agent to commit to. AgentGit dynamically looks up the installation for each repo, so a single app can work across multiple orgs.
- .NET 10 SDK (for building from source)
- A GitHub App (see above)
ghCLI (optional, for PR watch features)
git clone https://github.com/innago-property-management/AgentGit.git
cd AgentGit
dotnet publish src/AgentGit/AgentGit.csproj -c Release -o binThis produces a native AOT binary (~8MB, no .NET runtime required at runtime).
cp src/AgentGit/appsettings.json.example src/AgentGit/appsettings.json
appsettings.jsonis gitignored — your credentials won't be accidentally committed.
Edit src/AgentGit/appsettings.json:
{
"GitHubApp": {
"ClientId": "your-github-app-client-id",
"AppId": 123456,
"PrivateKeyPath": "/path/to/your-app.private-key.pem",
"AgentName": "your-app-name"
}
}Alternatively, set environment variables (useful for CI or secret managers):
export GitHubApp__ClientId="your-client-id"
export GitHubApp__AppId="123456"
export GitHubApp__PrivateKeyPath="/path/to/key.pem"
export GitHubApp__AgentName="your-app-name"scripts/agent-git.sh /path/to/repo -m "your commit message"
scripts/agent-git.sh /path/to/repo -am "stage and commit"
scripts/agent-git.sh /path/to/repo --allow-empty -m "empty commit"All arguments after the repo path pass through to git commit unchanged.
AgentGit was designed for Claude Code. A PreToolUse:Bash hook can intercept git commit commands and rewrite them to use AgentGit. With the hook installed, agents just run git commit normally and get bot identity automatically.
| Variable | Default | Purpose |
|---|---|---|
AGENT_GIT_REPO |
Current directory | Target repository path |
AGENT_GIT_WATCH_PR |
true |
Emit watch_request JSON after push if a PR exists |
AgentGit is a .NET 10 console app published as a Native AOT binary:
- Config — Generic Host loads
appsettings.json(or env vars) intoGitHubAppSettingsviaIOptions<T> - JWT —
JwtGeneratorsigns a JWT with RSA private key and Client ID asiss(pure BCL crypto, source-generated JSON) - Installation lookup —
RemoteUrlParserextractsowner/repofrom git remote,GitHubAppAuthenticatorcalls the GitHub API - Token exchange —
GitHubAppAuthenticatorswaps JWT for a scoped installation access token via direct HTTP (no Octokit) - Commit —
GitProcessRunnerrunsgit commitwith bot identity env vars (GIT_AUTHOR_NAME,GIT_COMMITTER_EMAIL, etc.) - Push —
GitProcessRunnerrunsgit pushwithGIT_ASKPASSfor token auth (token never visible inps aux)
- Private key permissions enforced (
PrivateKeyValidatorrejects world-readable keys) - Token passed via
GIT_ASKPASS+ env var, never in CLI args or URLs - Credential helpers disabled during push to prevent keychain override
AskPassScriptManagercreates temporary scripts with restrictive permissions, cleaned up after use
- Name:
{AgentName}[bot] - Email:
{AppId}+{AgentName}[bot]@users.noreply.github.com
| Package | Purpose |
|---|---|
| Microsoft.Extensions.Hosting | Generic Host for configuration and DI |
| Microsoft.Extensions.Http | HttpClient factory for GitHub API calls |
Zero reflection. All JSON serialization uses compile-time source generators for Native AOT compatibility.