Home / Blog / Claude Code Approval Gates: When to Let Agents Run and When to Stop Them
Claude Code approval gates HITL human oversight

Claude Code Approval Gates: When to Let Agents Run and When to Stop Them

April 26, 2026 · 8 min read

The first instinct when deploying Claude Code in production: approve everything. Every file write, every command, every Git operation — a human reviews first. This lasts about one day before the team realizes they’ve created a system requiring more human effort than doing the work manually.

The second instinct: approve nothing. Let the agent run freely. This works until something goes wrong, and then the conversation becomes about why nobody was watching.

The right answer is in between, and finding it requires understanding what actually needs oversight.

The Approval Taxonomy

Every Claude Code operation falls into four categories:

Always allow. Operations with no blast radius and easy reversibility: reading files, running tests in a sandbox, listing directories, checking Git status, querying read-only APIs. Gating these creates friction with zero security benefit.

Allow with logging (notify gate). Operations with minor side effects within expected scope: writing files in the working directory, creating Git commits on a feature branch, running linters, installing development dependencies. Log and make visible, but don’t stop the agent.

Allow with approval (approval gate). Operations with significant side effects on shared resources: pushing to Git, creating pull requests, modifying infrastructure, writing to production databases, sending external communications. A human confirms before proceeding.

Never allow (deny gate). Operations exceeding the agent’s intended scope: pushing to main/production branches, deleting infrastructure, modifying IAM policies. Blocked by policy regardless of approval. If the agent tries, that’s an alert.

Implementing Approval Gates in Slack

Slack is the natural approval interface because it’s where engineers already work. A well-implemented gate:

  1. Agent hits an operation requiring approval
  2. Gateway sends Slack message with full context: operation, agent session, developer who launched it, why the agent wants to do it
  3. Authorized approver clicks “Approve” or “Deny”
  4. Gateway receives callback, allows or denies the operation
  5. Decision logged with approver identity and timestamp

What the message should include:

Agent Request: Push to feature/auth-refactor
Session: sess_a8f3b21c (jordan@company.com)
Project: backend-api
Files changed: 4 (auth/middleware.ts, auth/types.ts, tests/auth.test.ts, README.md)
Commit: "Refactor auth middleware to use session tokens"
[Approve] [Deny] [View Diff]

The “View Diff” button lets the approver review changes without leaving Slack. The approver has enough context to make an informed decision in under 30 seconds.

Avoiding Approval Fatigue

The biggest risk isn’t too few gates — it’s too many. When every operation requires approval, approvers click “Approve” without reading. This is worse than no gates: it creates false security while adding latency.

Signs of fatigue: Average approval time under 10 seconds (nobody is reading), approval rate over 99% (gates aren’t catching anything), developers complaining agents are too slow, approvers auto-approving from mobile notifications.

Prevention: Gate only operations where denial is a realistic outcome. Group related operations into a single approval (approve the entire push, not each file individually). Track metrics on approval times and rates — deteriorating numbers indicate fatigue.

Timeout Behavior

When nobody responds to an approval request, what happens?

Block forever: Agent waits indefinitely. The work stalls completely if the request comes in after hours.

Auto-approve after timeout: Undermines the entire point. Attackers just wait.

Auto-deny after timeout (recommended): The operation is denied, the agent is notified and can attempt an alternative approach or stop. Fail closed. This is the right default.

Escalate then deny: Primary approver gets 15 minutes. No response → escalate to secondary. No response within 30 minutes → auto-deny. Balances responsiveness with security.

Building Toward More Autonomy

Approval gates should evolve as confidence in the agent increases.

Phase 1: Gate all write operations, all Git pushes, all infrastructure changes. You’re learning what the agent does.

Phase 2: After a month, review approval logs. Operations with 100% approval rate → convert to notify gates. Operations that were denied → keep the gates, they’re working.

Phase 3: Different policies for different projects. The internal tooling project needs minimal gates. The production API needs strict gates.

Phase 4: Track the agent’s history per project. 50 successful sessions with zero incidents and zero denials → consider loosening gates. An incident → tighten and require additional approval for that operation type.

A Mature Setup

For a team of eight with well-tuned policies:

  • Read operations: no gate (100+ per session)
  • Feature branch commits: notify (10-20 per session)
  • Feature branch pushes: approval (2-3 per session)
  • Pull request creation: approval (1 per session)
  • Production infrastructure: approval from team lead (rare)
  • Direct push to main: denied (never)

The agent runs at full speed for 95% of operations. The 5% requiring approval are meaningful decisions where a human check adds real value. Approvers handle 3-5 requests per session — manageable without fatigue.

This is the balance. Not security theater where everything is gated and everyone rubber-stamps. Not cowboy mode where nothing is controlled. Thoughtful gates at the right decision points, with a path toward more autonomy as confidence grows.

// get-started

Put this into practice with Sentrely

Everything covered in this article is built into Sentrely's managed control plane. Get early access and have it running against your Claude agents in minutes.