Claude Code Using Your Personal Email? Lock Down Git Identity

Claude Code Using Your Personal Email? Lock Down Git Identity

Aident AI

A warm oval remains behind a translucent violet boundary while a cool ribbon passes through a separate opening.

Claude Code Using Your Personal Email? Lock Down Git Identity

A July 25, 2026 Claude Code issue reports that version 2.1.220 placed the signed-in account email in a userEmail context block. The reporter also observed Claude Code passing git -c user.email=<personal-address> for commits, overriding an existing no-reply Git identity. The issue remains open, and Anthropic has not confirmed the intent or published a supported opt-out in that thread.

You can still contain the public Git risk today. Set an explicit repository no-reply identity, make Git refuse guessed identities, add a pre-commit identity guard, enable GitHub's email protection, and audit reachable history. These controls do not remove the address from Claude Code's context. They stop an unapproved address at the commit or push boundary.

The Short Fix

From the affected repository, inspect the effective identity:

git config --show-origin --show-scope --get-all user.email
git var GIT_AUTHOR_IDENT
git var GIT_COMMITTER_IDENT

Then copy your exact GitHub-provided no-reply address from GitHub Settings > Emails and configure it for this repository:

git config --local user.name "YOUR_GITHUB_NAME"
git config --local user.email "YOUR_GITHUB_NOREPLY_ADDRESS"
git config --global user.useConfigOnly true

Expected result: both git var commands show the approved no-reply address. Add the commit guard below before asking any agent to commit again.

What Is Reported, and What Is Not Confirmed

The primary evidence is a public bug report, not an Anthropic incident report. Its author documented this context block in Claude Code 2.1.220:

# userEmail
The user's email address is <account email>.

The same author reported that the model emitted the address and used it for ten local commits. A separate Reddit discussion repeated the concern, and several commenters described similar Git, package-author, output, or outbound-request behavior. Those are user reports. They do not establish how often the behavior occurs or why Anthropic added the field.

The practical distinction is important:

Boundary

What you can verify now

What remains unresolved

Claude Code context

The public report includes a version, code path, and reproduction

Whether Anthropic will remove the field or add an opt-out

Local Git identity

git var shows the author and committer identity Git would use

An agent can still attempt an explicit override

Commit creation

A hook can reject an unapproved author or committer email

Local hooks can be bypassed with --no-verify or configuration changes

GitHub push

GitHub can block the most recent commit when it exposes a private account email

That setting is not a substitute for checking every commit in a multi-commit push

Treat the context concern as unresolved. Enforce the boundary you control.

Prerequisites

You need:

  • Git installed and an existing repository;

  • the exact no-reply address shown in your GitHub email settings;

  • permission to change local Git configuration;

  • a clean understanding of whether the affected commits were pushed.

Run privacy checks in a private terminal. The inspection commands print the configured address, so do not paste their output into an issue, livestream, or shared agent transcript.

Step 1: Find the Effective Git Identity

Git configuration has several scopes. A repository value can override a global value, while environment variables or git -c can override both for one command.

git config --show-origin --show-scope --get-all user.name
git config --show-origin --show-scope --get-all user.email
git var GIT_AUTHOR_IDENT
git var GIT_COMMITTER_IDENT

Expected result: the final two lines use the identity you intend to publish. If multiple values appear, --show-origin and --show-scope identify the file and scope that supplied each value.

Do not ask the agent to explain the output if that would copy a private address back into its context. Inspect it yourself.

Step 2: Set a Repository No-Reply Identity

GitHub provides a no-reply address in Settings > Emails. Copy that exact value. Formats vary by account, so do not guess the numeric prefix or username.

git config --local user.name "YOUR_GITHUB_NAME"
git config --local user.email "YOUR_GITHUB_NOREPLY_ADDRESS"
git config --global user.useConfigOnly true

Git documents user.useConfigOnly=true as a way to stop Git from guessing user.name and user.email when they are not configured. It does not prevent an explicit one-command override such as git -c user.email=.... The repository setting establishes the safe default; the next step checks the identity at commit time.

Verify it:

git var GIT_AUTHOR_IDENT
git var GIT_COMMITTER_IDENT

Expected result: both use YOUR_GITHUB_NOREPLY_ADDRESS.

Step 3: Add a Commit-Time Identity Guard

Locate the repository's current pre-commit hook:

git rev-parse --git-path hooks/pre-commit

If that file already exists, do not overwrite it. Add the following check to the existing hook or ask the hook owner to compose both checks. Otherwise, save this as the path returned above and replace the placeholder with your exact no-reply address:

#!/bin/sh
set -eu

expected='YOUR_GITHUB_NOREPLY_ADDRESS'
author_email=$(git var GIT_AUTHOR_IDENT | sed -n 's/.*<\([^<>]*\)>.*/\1/p')
committer_email=$(git var GIT_COMMITTER_IDENT | sed -n 's/.*<\([^<>]*\)>.*/\1/p')

if [ "$author_email" != "$expected" ] || [ "$committer_email" != "$expected" ]; then
  printf '%s\n' \
    'Commit blocked: author or committer email is not the approved no-reply address.' >&2
  exit 1
fi

Make it executable:

hook_path=$(git rev-parse --git-path hooks/pre-commit)
chmod +x "$hook_path"

Test the rejection without creating a commit:

hook_path=$(git rev-parse --git-path hooks/pre-commit)
GIT_AUTHOR_EMAIL=not-approved@example.invalid \
GIT_COMMITTER_EMAIL=not-approved@example.invalid \
  "$hook_path"

Expected result: the hook exits nonzero and prints only the generic rejection message. It does not echo the rejected address.

Now run the hook with the configured identity:

"$(git rev-parse --git-path hooks/pre-commit)"

Expected result: it exits silently with status zero.

This guard also evaluates the identity Git resolves when a commit command supplies a temporary configuration override. It is defense in depth, not a security boundary: git commit --no-verify, a changed hook path, or a modified hook can bypass it. For a team repository, enforce the same allowlist in CI or a server-side receive rule.

Step 4: Enable GitHub's Push Protection

In GitHub Settings > Emails:

  1. Enable Keep my email addresses private.

  2. Enable Block command line pushes that expose my email.

GitHub says this check blocks a push when its most recent commit uses a private email connected to your account. That is valuable protection, but review every commit in a multi-commit push yourself or in CI. A safe final commit should not hide an earlier unsafe one from your audit.

Step 5: Audit Existing History

Fetch the remote references you are authorized to inspect, then list unique author and committer addresses:

git fetch --all --prune
git log --all --format='%H%x09%ae%x09%ce' | sort -u

Inspect the current commit separately:

git show -s --format='author=%an <%ae>%ncommitter=%cn <%ce>' HEAD

Expected result: reachable commits contain only addresses intended for that repository. These commands print addresses locally. Do not upload the output without redaction.

If only the latest unpushed commit is wrong, set the correct identity first, confirm the diff, and amend it:

git status --short
git commit --amend --reset-author --no-edit
git show -s --format='author=%ae%ncommitter=%ce' HEAD

If several unpushed commits are affected, or any affected commit was pushed, stop before rewriting. Coordinate with repository owners and follow GitHub's sensitive-data removal guidance. History rewriting changes commit IDs, affects every clone and open branch that contains them, and may require cache cleanup. An email address is not an access token, but it can still be personal data you do not want indexed.

Common Failure Modes

Attempt

Why it falls short

Better control

Put “never use my email” in CLAUDE.md

It relies on model compliance and does not remove the value from context

Enforce the allowed identity outside the model

Set only global user.email

Repository, environment, and command-scoped values can override it

Inspect scopes, set the repo value, and validate at commit time

Rely only on user.useConfigOnly

It stops guessing, not an explicit git -c override

Add a hook plus CI or server enforcement

Rely only on a local hook

Hooks can be bypassed or replaced

Add GitHub protection and review all pushed commits

Edit ~/.claude.json by hand

Authentication may repopulate it, and the file is not a supported privacy control

Keep auth state intact and track the upstream issue

Set ANTHROPIC_UNIX_SOCKET

It selects a transport path, not a documented privacy option

Do not repurpose it as a workaround

Use IS_DEMO=1

The report says it hides display surfaces but not the context field

Treat it as display hygiene only until Anthropic documents otherwise

Rewrite pushed history immediately

It can disrupt collaborators without removing every public copy

Coordinate and follow the official removal procedure

Why This Containment Works

The model may propose a Git command, but Git resolves the author and committer identities before creating the commit. The repository config supplies the safe default. The pre-commit hook compares the resolved values against one approved address and exits nonzero before the commit object is created. GitHub adds a separate push-time check for a private account email.

The controls are independent of Claude Code's prompt. That is the point: data-handling instructions inside a model cannot be your only defense against data the model can already see.

This follows the same structure that makes Aident's Ollama networking guide useful: name the exact risk, inspect the active boundary, apply one reproducible change, state the expected result, and cover look-alike failures. For broader agent-generated changes, use the AI coding-agent verification checklist. For untrusted repository content and tool output, see securing agentic GitHub workflows against prompt injection.

Keep Provider Credentials Out of the Prompt Too

Git identity and provider authentication are different boundaries. Aident Loadout does not remove Claude's account email from Claude Code's context. It keeps supported integration credentials in Vault and lets the agent discover a typed Action instead of asking you to paste provider tokens into a prompt or script.

After the Git identity guard passes, install or update Loadout and run:

aident account auth status
aident vault vault --action status
aident capabilities search \
  --queries '["GitHub get repository"]' \
  --types '["action"]' \
  --limit 5

Choose the exact read-only result and inspect its schema before execution:

aident capabilities get <EXACT_CAPABILITY_NAME> --schema

Expected result: Loadout returns a typed input schema without requiring a GitHub token in the command or chat. That is a measurable second boundary, not a workaround for the Claude Code issue.

Use Aident Loadout to inspect one read-only GitHub Action schema without exposing a provider token.

Sources

Refresh this guide when Anthropic documents or changes the userEmail behavior, adds a supported opt-out, closes the primary issue with a verified fix, or Git or GitHub changes identity and push-protection behavior.

Home

Home

Home

Integrations

Integrations

Integrations

Vault

Vault

Vault

Audit

Audit

Audit

Arana Grande

Arana Grande

Arana Grande

Free

Free

Free

30-day audit summary

30-day audit summary

30-day audit summary

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

View Audit

View Audit

View Audit

Loadout usage

Loadout usage

Loadout usage

617 action calls in the last 30 days

617 action calls in the last 30 days

617 action calls in the last 30 days

May 19 - Jun 17

May 19 - Jun 17

May 19 - Jun 17

10 active days

10 active days

10 active days

Less

Less

Less

More

More

More

Recent activity

Recent activity

Recent activity

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Shopify

Shopify

Shopify

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Success

Success

Success

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Success

Success

Success

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Failed

Failed

Failed

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Connected integration coverage

Connected integration coverage

Connected integration coverage

162

162

162

of 753 accessible connected

of 753 accessible connected

of 753 accessible connected

Callable actions

Callable actions

Callable actions

1,126

1,126

1,126

Vault credentials

Vault credentials

Vault credentials

8

8

8

Explore what's possible

Explore what's possible

Explore what's possible

See all Integrations

See all Integrations

See all Integrations

Google Ads

Google Ads

Google Ads

All available Goolge Ads tools via...

All available Goolge Ads tools via...

All available Goolge Ads tools via...

X (twitter)

X (twitter)

X (twitter)

All available X tools via...

All available X tools via...

All available X tools via...

Github

Github

Github

All available Github tools via...

All available Github tools via...

All available Github tools via...

Notion

Notion

Notion

All available Notion tools via...

All available Notion tools via...

All available Notion tools via...

Slack

Slack

Slack

All available Slack tools via...

All available Slack tools via...

All available Slack tools via...

Firecrawl

Firecrawl

Firecrawl

All available Firecrawl tools via...

All available Firecrawl tools via...

All available Firecrawl tools via...

753 integrations are available for loadouts.

753 integrations are available for loadouts.

753 integrations are available for loadouts.

Plug your entire stack into your AI agents.

Plug your entire stack into your AI agents.

Plug your entire stack into your AI agents.

Skip the integration headache. Plug 750+ tools into Claude Code, Codex, and OpenClaw in one go, and let your agents execute today.

Skip the integration headache. Plug 750+ tools into Claude Code, Codex, and OpenClaw in one go, and let your agents execute today.