2026-01-20 · Authensor

How to Prevent AI Agents from Force Pushing

SafeClaw by Authensor denies git push --force and all its variants (-f, --force-with-lease) by default, preventing AI agents from rewriting remote Git history. Install with npx @authensor/safeclaw and force push attempts are blocked and cryptographically logged before they reach the remote.

Why Force Pushing Is Dangerous When AI Agents Do It

Force pushing overwrites remote branch history. When a human does it deliberately on a feature branch, the risk is contained. When an AI agent does it autonomously, the consequences escalate: the agent may rebase incorrectly, lose commits from other contributors, or destroy the only record of a production hotfix. Agents operating in retry loops can force-push repeatedly, compounding data loss. Unlike a regular push rejection from branch protection rules, a successful --force push is often irreversible without reflog access to the remote — which most hosted Git providers do not expose.

The Exact SafeClaw Policy to Block Force Push

Add these rules to .safeclaw/policy.yaml:

rules:
  - id: deny-git-force-push
    action: shell.exec
    match:
      command: "git push --force*"
    effect: deny
    audit: true
    message: "Force push is permanently denied for AI agents."

- id: deny-git-force-push-short
action: shell.exec
match:
command: "git push -f*"
effect: deny
audit: true
message: "Force push (-f) is permanently denied for AI agents."

- id: deny-git-force-with-lease
action: shell.exec
match:
command: "git push --force-with-lease*"
effect: deny
audit: true
message: "Force-with-lease push is denied for AI agents."

Three rules are necessary because Git accepts multiple flag formats. SafeClaw's glob matching catches the command regardless of which remote or branch argument follows the flag. All three rules produce audit entries.

What Happens When the Agent Tries

When an agent running on Claude or OpenAI attempts git push --force origin main:

  1. SafeClaw's policy engine intercepts the shell.exec action request.
  2. The deny-git-force-push rule matches on git push --force*.
  3. Execution is blocked — the git binary is never invoked.
  4. A hash-chained audit entry is recorded:
{
  "timestamp": "2026-02-13T09:15:44Z",
  "action": "shell.exec",
  "command": "git push --force origin main",
  "effect": "deny",
  "rule": "deny-git-force-push",
  "agent": "refactor-agent-03",
  "hash": "b7d2e4...chain_link"
}
  1. The agent receives the denial message and can communicate it to the user.
SafeClaw's 446-test suite includes specific cases for force push flag permutations, ensuring no variant slips through.

How to Allow Force Push with Approval (If You Must)

In rare cases — such as a supervised repository cleanup — you may want to permit force push with explicit human sign-off:

rules:
  - id: force-push-with-approval
    action: shell.exec
    match:
      command: "git push --force*"
    effect: approval
    audit: true
    approvers:
      - role: lead-engineer
    timeout: 120
    message: "Force push requires lead engineer approval within 2 minutes."

- id: deny-force-push-fallback
action: shell.exec
match:
command: "git push -f*"
effect: deny
audit: true
message: "Use --force flag (not -f) to trigger approval workflow."

This configuration routes --force through the approval workflow while still hard-denying the -f shorthand. The timeout ensures the agent does not hang indefinitely waiting for approval.

Combining with Regular Push Gating

For maximum safety, layer force push denial above your regular push gate:

rules:
  # Force push rules first (higher priority)
  - id: deny-git-force-push
    action: shell.exec
    match:
      command: "git push --force*"
    effect: deny
    audit: true
    message: "Force push denied."

- id: deny-git-force-push-short
action: shell.exec
match:
command: "git push -f*"
effect: deny
audit: true
message: "Force push denied."

# Regular push gating second
- id: gate-git-push-approval
action: shell.exec
match:
command: "git push*"
effect: approval
audit: true
approvers:
- role: developer
timeout: 300

First-match-wins ordering ensures force pushes hit the hard deny before reaching the approval-gated regular push rule.

Verification

npx @authensor/safeclaw simulate --action 'shell.exec' --command 'git push --force origin main'

Expected: deny, rule: deny-git-force-push

Related Pages

Try SafeClaw

Action-level gating for AI agents. Set it up in your browser in 60 seconds.

$ npx @authensor/safeclaw