DEV Community

Sourabh Yogi
Sourabh Yogi

Posted on

I built an AI on-call copilot that can diagnose incidents fast but can never act without a human's cryptographic sign-off

The problem with AIOps right now

Most tools in this space land on one of two extremes:

  • Alert louder — more dashboards, more pages, same 3am scramble to figure out what actually happened.
  • Auto-remediate blindly — an agent decides something's wrong and just... restarts/rolls back/scales, and you find out after the fact whether it guessed right.

Neither is great. The first doesn't save you any time. The second means an AI's hallucination can now take down prod on its own authority.

I wanted something in between: fast AI diagnosis, zero AI authority to act.

What it does

incident-approval-gate is an open-source service that sits between your alerting stack and your infrastructure:

  1. An alert fires (Dynatrace, Prometheus/Alertmanager, or a generic webhook)
  2. It pulls recent metrics (Prometheus), logs (Loki or a log file), and deploy history (git/GitHub) for context
  3. An LLM (Anthropic or Gemini) produces a structured diagnosis: root cause, confidence, and one proposed action
  4. Depending on the action type, one of two things happens:

Propose mode (e.g. revert_pr, manual_investigation) — fully automatic. If the fix is a code-level revert, it opens a real PR with the diagnosis in the description. Nothing executes until a human merges it through your normal CI/CD. This is safe by construction — a PR is just a diff.

Execute mode (restart, rollback, scale) — always gated. It posts to Slack (interactive buttons), Microsoft Teams (Adaptive Card), or email (confirmation link) and creates a pending approval. Nothing runs yet.

The part that actually matters: the approval gate

This is ported directly from an earlier project of mine, tf-approval-gate, which gates Terraform applies behind the same design. The rules:

  • Every approval request mints a cryptographically signed, single-use, short-TTL HMAC token, bound to a checksum of the exact proposed action. If the action changes, the old token is invalid.
  • State transitions (pending → approved/rejected, approved → consumed) are each a single guarded SQL UPDATE ... WHERE status = '...' — so a double-click, a race, or a replayed token can never execute twice.
  • The LLM-proposed target (e.g. a service name) is never passed to kubectl until it's matched against an explicit allowlist (config/execution-allowlist.yml) mapping service → namespace → max replicas. The model can propose "restart payment-service" all it wants; if payment-service isn't in the allowlist, nothing happens.
  • Execution uses execFile with array arguments — never shell string interpolation — so there's no path from alert text or LLM output to command injection.
  • Every alert, diagnosis, approval decision, token consumption, and execution result is written to an append-only audit log.

The server never trusts an agent's own claim that "a human approved this." It re-verifies the signature, expiry, single-use status, and the action payload itself, every time.

A real trace from testing

Here's an actual run (not a canned example) from when I was testing this:

alert_received       -> checkout-service, critical, CrashLoopBackOff
diagnosis_produced    -> root cause: bad pod state post-rollout
                         action: restart, risk: high
Policy decision        -> mode: execute (restart always requires approval)
approval_created        -> signed token minted, posted to Slack
[human clicks Approve in Slack]
approval_approved       -> actor: <slack user id>
approval_consumed       -> token verified + burned, single-use enforced
kubectl rollout restart deployment/checkout-service -n production
Enter fullscreen mode Exit fullscreen mode

Every step is logged, every step is real — no mocked LLM response, no fabricated approval.

Why I built it this way

I have another project, tf-approval-gate, that gates Terraform applies behind this exact trust model. Building this made me realize the pattern generalizes: any AI agent that can touch production needs the same three properties — fast/useful reasoning, zero unilateral authority to act, and a human approval that's cryptographically verified rather than merely claimed. Alerting is just the next surface where that matters.

Try it

git clone https://github.com/SORABH13/incident-approval-gate.git
cd incident-approval-gate
npm install && npm run build
cp .env.example .env   # add an LLM key (Anthropic or Gemini's free tier) + a notifier
npm start
Enter fullscreen mode Exit fullscreen mode

It's MIT licensed and I'd genuinely like feedback — especially from anyone who's dealt with an AIOps tool that acted before it should have.

🔗 github.com/SORABH13/incident-approval-gate

Top comments (0)