Agentic AI · Security · Human-in-the-Loop

Autonomous Security
Triage Agent

A ReAct agent investigates a security incident — reads logs, enriches threat intel, proposes containment. Destructive actions pause for human approval. An autonomy dial sets how much it can do alone.

ReAct agent 3 function-calling tools Gemini 2.5 Flash Python · Streamlit
At a glance 30-second read

What it is

An autonomous SOC triage agent. ReAct loop on Gemini 2.5 Flash, three function-calling tools, human-in-the-loop gate on every destructive action. Live demo, open source.

Maps to

AI / Agent Engineer · Applied AI Engineer · Security Engineer (AI) · Forward-Deployed Engineer

Skills demonstrated

  • ReAct agent loop architecture
  • Function-calling tool design (read-only vs destructive)
  • Human-in-the-loop approval on destructive actions
  • Autonomy dial: advisory vs active modes
  • Schema-declared tools — the app owns execution
Python Streamlit Gemini 2.5 Flash ReAct Function Calling HITL
What it is
Person Operator opens an incident
AI Gemini 2.5 Flash reasons, picks a tool
This project sentinel three tools
Data SOC environment logs + threat intel

The agent can reason about a threat, but it should not act on production infrastructure unsupervised. Sentinel keeps a human in the loop on every destructive action.

3
focused tools
2
autonomy modes
1
human-approval gate
0
actions taken without consent
See it run one take, no narration

Detection to containment.

A full triage of incident INC-4471 — the agent scans the logs, enriches the threat intel, and proposes containment, then stops at the human-approval gate before anything executes.

sentinel-triage · incident INC-4471 [ RECORDED RUN ]

Recorded from a live run against Gemini 2.5 Flash. Or run it yourself — open the live demo →

01 — The Tools three jobs, three tools

One tool per job.

Three tools that match what a Tier-1 analyst does to triage an incident.

Scan the logs
scan_logs
Analyses an incident's traffic for anomalies — suspicious ports, brute force, beaconing, data egress.
Read-only
Enrich an IP
enrich_threat_data
Cross-references an address against threat intelligence — reputation, category, confidence.
Read-only
Quarantine a host
isolate_node
Cuts a compromised node off the network. Destructive — never runs without a human approval click.
Destructive · gated
02 — The Loop reason, act, observe

It reasons, then asks.

A ReAct loop: the agent thinks, calls one tool, reads the result, and repeats — narrating each step into a live thinking log. When it wants to contain a host, it stops and waits for a person.

incident INC-4471 · final verdict [ ACTUAL OUTPUT ]

Severity: Critical. Outbound beaconing and possible data exfiltration from FIN-WKSTN-08 to a known malicious Tor exit node / C2 relay (185.220.101.47).

Abnormal traffic volume — 188 connections, 1,920,044 bytes egress — to port 4444. The node was quarantined after operator approval.

The verdict above. The full run that produced it, below.

INC-4471 · reasoning trace [ THINK · ACT · OBSERVE · GATE ]
Step 1 think Outbound traffic to 185.220.101.47 looks unusual for a finance workstation. I should check threat intel before doing anything else.
Step 2 act query_threat_intel(ip="185.220.101.47")
Step 3 observe { match: true, type: "Tor exit / C2 relay", confidence: 0.94 }
Step 4 think Confirmed malicious destination. I need volume and duration to assess scope before proposing containment.
Step 5 act query_logs(host="FIN-WKSTN-08", dst="185.220.101.47", window="24h")
Step 6 observe { connections: 188, bytes_egress: 1,920,044, port: 4444, sustained: true }
Step 7 think Sustained beaconing, large egress volume to a confirmed C2 relay. Proposing host quarantine. This is destructive — I have to stop and ask.
Step 8 propose quarantine_host("FIN-WKSTN-08") · destructive — HITL required
Step 9 approve operator: bdavis · signed 14:08:22 · reason: "confirmed active C2"
Step 10 act quarantine_host("FIN-WKSTN-08") — success

Ten steps · three tool calls · one approval. The agent reasoned through the evidence before proposing the destructive action — and the loop stopped on its own at step 8 because quarantine_host is declared destructive in the tool schema. The model didn’t bypass the gate; the schema made it unreachable without approval.

03 — Control the agent proposes; the person decides

Built to be supervised.

It acts on a company's infrastructure, so the design assumes the agent can be wrong. Three decisions keep a person in command.

The Autonomy Dial
A slider between Advisory — chat only — and Active, where the agent runs tools. The operator decides how much rope it gets.
Human-in-the-loop
Destructive actions pause the loop. Nothing is quarantined until a person reviews the proposal and clicks approve.
The code owns execution
Tools are declared as schemas, not auto-run. The model only proposes; the app decides. That is what makes the gate possible.