Six specialized AI agents collaborate in real time to triage, hunt, challenge, assess, contain, and report on security incidents — end to end, in under two minutes.
SentinelFlow is an autonomous incident response platform that replaces manual triage-to-report workflows with a coordinated team of six AI agents. When evidence is ingested — a suspicious log entry, an alert payload, raw forensic data — the platform orchestrates a structured investigation pipeline that mirrors how a world-class security operations center actually works.
Each agent operates independently with a defined specialty: the Triage Specialist forms initial hypotheses, the Threat Hunter and Red Team Challenger validate and contest those hypotheses in parallel, the Risk Analyst quantifies business impact, the Incident Commander produces containment actions, and the Executive Reporter compiles everything into a board-ready PDF. The entire pipeline runs on an event-driven backbone powered by Band SDK, with every state transition streamed to the frontend via WebSocket in real time.
The result is a live investigation dashboard where security teams observe AI reasoning as it happens — a knowledge graph that grows node by node, an event timeline with full time-travel capabilities, and a downloadable executive report generated the moment the investigation concludes.
Traditional incident response suffers from three structural problems:
| Problem | Impact | SentinelFlow's Answer |
|---|---|---|
| Sequential bottlenecks | Analysts wait for triage before hunting begins. Mean time to respond (MTTR) balloons. | Parallel agent execution — Hunter-1 and RedTeam-1 fire simultaneously on the same hypothesis. |
| Confirmation bias | A single analyst forms a hypothesis and unconsciously validates it. Adversaries exploit blind spots. | Adversarial architecture — the Red Team Challenger actively contests every hypothesis before risk assessment begins. |
| Reporting lag | Writing executive summaries consumes hours after containment, delaying board-level communication. | Automated PDF generation — the Executive Reporter compiles a structured case file the moment containment is published. |
| Knowledge silos | Context scatters across Slack threads, ticket comments, and analyst memory. | Shared blackboard — every context package is stored, versioned, and visualized as a live knowledge graph. |
| No audit trail | Post-incident reviews rely on incomplete notes and reconstructed timelines. | Immutable event log — every event, claim, and state transition is persisted with full time-travel replay. |
SentinelFlow treats incident response as a coordination problem, not just an analysis problem. The multi-agent architecture enforces structured disagreement, parallel execution, and full observability — by design.
|
Six AI agents execute a structured pipeline from triage through executive reporting. No human intervention required to produce a complete case file. Every hypothesis, validation, dissent, risk assessment, and containment action materializes as a node in a React Flow knowledge graph, with edges tracing provenance. Scrub backward and forward through the investigation timeline. The WebSocket endpoint replays the exact state at any point in time using |
Qwen 2.5-72B handles deep analytical reasoning (triage, risk, command). Mistral Nemo handles rapid validation, adversarial challenge, and narrative synthesis. Band SDK provides the real-time agent-to-agent messaging backbone — investigation rooms, contact management, and persistent message history. Automated report generation with structured sections for hypothesis, evidence chain, risk matrix, containment actions, and executive summary. Board-ready on completion. |
A complete investigation flows through five stages, orchestrated entirely by the event bus:
┌─────────────┐ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐
│ INGEST │───▶│ ANALYZE │───▶│ VALIDATE │───▶│ DECIDE │───▶│ REPORT │
│ │ │ │ │ │ │ │ │ │
│ Evidence │ │ Triage │ │ Hunt + │ │ Risk + │ │ Executive │
│ submitted │ │ Hypothesis │ │ Red Team │ │ Containment │ │ CaseFile │
└─────────────┘ └─────────────┘ └──────────────┘ └─────────────┘ └─────────────┘
Step-by-step breakdown:
-
Evidence Ingestion — A user submits raw evidence (log entries, alert payloads, forensic data) through the investigation launcher. The backend creates a Band room, persists the incident in SQLite, and publishes an
Evidence:Ingestedevent to the BandBus. -
Task Orchestration — The
TaskOrchestratorreceives the event, queries theAGENT_REGISTRYfor agents whosetrigger_eventsmatch, and atomically claims tasks viaTaskClaimManagerto prevent duplicate execution. -
Triage Analysis —
Triage-1receives the claim, builds context from the event store and blackboard, renders its Jinja2 prompt template with the evidence payload, and calls Qwen 2.5-72B to produce a structuredHypothesiscontext package. -
Parallel Validation — The published
Context:Published:Hypothesisevent triggers bothHunter-1(threat validation via Mistral Nemo) andRedTeam-1(adversarial challenge via Mistral Nemo) simultaneously. Both agents have independent context builders and produceValidationandDissentpackages respectively. -
Risk Assessment — Once validation is published,
Risk-1consumes the full context chain — evidence, hypothesis, validation, and dissent — to produce a quantifiedRiskassessment via Qwen 2.5-72B. -
Containment Planning —
Commander-1receives the risk assessment and generates specificContainmentactions: network isolation, credential rotation, forensic preservation — tailored to the incident specifics. -
Executive Reporting —
Reporter-1compiles the entire investigation chain into aCaseFilecontext package. TheReportingServicedetects theContext:Published:CaseFileevent and automatically generates a PDF report. -
Real-Time Streaming — Every event, agent status change, and context publication is broadcast to connected WebSocket clients. The frontend renders each update to the timeline, knowledge graph, and agent status panels in real time.
Every agent in SentinelFlow is defined in the AGENT_REGISTRY with explicit trigger events, output types, prompt templates, and model assignments:
| Agent | ID | Role | Trigger Event | Output Type | Model | Prompt Template |
|---|---|---|---|---|---|---|
| Triage Specialist | Triage-1 |
Security Triage Specialist | Evidence:Ingested |
Hypothesis |
qwen/qwen-2.5-72b-instruct |
triage_specialist.jinja |
| Threat Hunter | Hunter-1 |
Threat Hunter | Context:Published:Hypothesis |
Validation |
mistralai/mistral-nemo |
threat_hunter.jinja |
| Red Team Challenger | RedTeam-1 |
Red Team Challenger | Context:Published:Hypothesis |
Dissent |
mistralai/mistral-nemo |
red_team_challenger.jinja |
| Risk Analyst | Risk-1 |
Risk Analyst | Context:Published:Validation |
Risk |
qwen/qwen-2.5-72b-instruct |
risk_analyst.jinja |
| Incident Commander | Commander-1 |
Incident Commander | Context:Published:Risk |
Containment |
qwen/qwen-2.5-72b-instruct |
incident_commander.jinja |
| Executive Reporter | Reporter-1 |
Executive Report Specialist | Context:Published:Containment |
CaseFile |
mistralai/mistral-nemo |
exec_reporter.jinja |
Each agent follows a deterministic lifecycle managed by the AgentExecutor:
Task:Claimed → Running → Thinking → Publishing → Finished
│
(on error) ▼
Failed
- Claim — The
TaskOrchestratorclaims the task atomically. TheAgentExecutorlistens forTask:Claimedevents. - Context Build — The
ContextBuilderassembles the full investigation state from theEventStoreandBlackboard. - Prompt Render — The agent's Jinja2 template is rendered with the assembled context.
- LLM Call — The
LLMClientsends the prompt to the assigned model with a 120-second timeout. Retries (up to 3 attempts) use exponential backoff viatenacity. - Normalization — Raw LLM JSON is normalized into the internal
ContextPackagecontract with header, payload, and metadata fields. - Validation — The
JsonValidatorenforces structural requirements before the context is published. - Publication — The validated context is published to the BandBus, triggering downstream agents.
Every stage transition emits an Agent:Status event, enabling the frontend to show real-time agent progress indicators.
SentinelFlow integrates Band SDK as the real-time communication backbone for agent-to-agent coordination:
- Investigation Rooms — Each incident creates a dedicated Band room via
band_rooms.py. All agent communication for that incident is scoped to this room. - Agent Identity — The backend authenticates with Band using an API key and retrieves its agent identity on startup. Contact requests are auto-approved via a callback strategy configured in the application lifespan.
- WebSocket Transport — Band's WebSocket connection runs via
agent.run_forever()in anasynciobackground task, maintaining a persistent connection for receiving messages and events. - Adapter Pattern — The
SentinelFlowAdapterbridges Band SDK events with the internalBandBus, translating external messages into the event-driven pipeline.
The Band integration layer consists of eight modules:
| Module | Responsibility |
|---|---|
band_adapter.py |
Bridges Band SDK events to the internal BandBus |
band_agents.py |
Agent identity management and lookup |
band_auth.py |
API key and URL configuration from environment |
band_client.py |
REST client singleton for Band API calls |
band_context.py |
Context package serialization for Band messages |
band_events.py |
Event type mapping between Band and internal formats |
band_messages.py |
Message formatting and chat integration |
band_rooms.py |
Investigation room creation and management |
The investigation knowledge graph is rendered using React Flow (@xyflow/react) and visualizes the complete chain of reasoning:
- Node Types — Custom node components in
nodes.tsxrepresent each context type with distinct visual treatments: Evidence (blue), Hypothesis (amber), Validation (green), Dissent (red), Risk (orange), Containment (purple), CaseFile (emerald). - Edge Routing — Custom edge components in
edges.tsxtrace provenance viaparent_context_idrelationships from the blackboard. - State Management — The
graph.tsZustand store maintains graph state independently, computing node positions and edge connections from incoming WebSocket events. - Real-Time Updates — As each agent publishes a new context package, the corresponding node appears on the canvas with an animated entrance. Edges draw automatically from parent to child context.
- Interactive Canvas — Users can pan, zoom, and select individual nodes to inspect the full context package payload, including confidence scores, evidence references, and model metadata.
The graph grows organically as the investigation progresses — from a single evidence node to a complete reasoning tree, typically consisting of 7–9 nodes for a standard investigation.
SentinelFlow generates executive-grade PDF reports automatically when the investigation completes:
- Trigger — The
ReportingServicesubscribes toContext:Published:CaseFileevents. When the Executive Reporter publishes the final case file, PDF generation begins. - Content Assembly — The
pdf_generator.pyreads the full event history from theEventStore, extracting structured data from each context package. - Report Structure — Generated PDFs include: incident metadata, executive summary, hypothesis chain, threat validation findings, red team dissent analysis, quantified risk assessment, containment action plan, and evidence references.
- Delivery — Reports are available on demand via
GET /api/v1/incidents/{id}/pdfand displayed in a dedicated report viewer page in the frontend. - Library — PDF generation uses fpdf2, producing lightweight, portable documents without external dependencies.
SentinelFlow is built as a monorepo with clear separation between the Next.js frontend, FastAPI backend, and shared type definitions:
graph TB
subgraph "Client Layer"
Browser["Browser"]
Browser --> NextJS["Next.js 16 App Router"]
end
subgraph "Frontend (Vercel)"
NextJS --> Pages["App Pages"]
NextJS --> KG["Knowledge Graph<br/>React Flow"]
NextJS --> WS_Client["WebSocket Client"]
NextJS --> Store["Zustand Stores"]
Pages --> Landing["/ Landing"]
Pages --> Investigate["/investigate Launcher"]
Pages --> Dashboard["/incident/{id} Dashboard"]
Pages --> Report["/incident/{id}/report PDF"]
Pages --> History["/incidents History"]
end
subgraph "Backend (Render)"
API["FastAPI Server"]
API --> IncAPI["POST /api/v1/incidents"]
API --> ListAPI["GET /api/v1/incidents"]
API --> DetailAPI["GET /api/v1/incidents/{id}"]
API --> PDFAPI["GET /api/v1/incidents/{id}/pdf"]
API --> WS_Server["WS /ws/v1/incidents/{id}/stream"]
API --> HealthAPI["GET /api/v1/health"]
subgraph "Event Engine"
BandBus["BandBus<br/>Pub/Sub Backbone"]
Orchestrator["TaskOrchestrator"]
Executor["AgentExecutor"]
Reporting["ReportingService"]
end
subgraph "Persistence"
EventStore["EventStore<br/>Immutable Log"]
Blackboard["Blackboard<br/>Materialized State"]
ClaimMgr["TaskClaimManager<br/>Distributed Locks"]
EvidenceStore["EvidenceStore"]
end
subgraph "AI Agents"
Triage["Triage-1"]
Hunter["Hunter-1"]
RedTeam["RedTeam-1"]
Risk["Risk-1"]
Commander["Commander-1"]
Reporter["Reporter-1"]
end
end
subgraph "External Services"
BandSDK["Band SDK<br/>Agent Messaging"]
AIML["AI/ML API<br/>Qwen 2.5-72B"]
Featherless["Featherless AI<br/>Mistral Nemo"]
OpenRouter["OpenRouter<br/>Multi-Model"]
end
WS_Client -->|WebSocket| WS_Server
WS_Server -->|WebSocket| WS_Client
NextJS -->|REST| API
BandBus --> Orchestrator
Orchestrator --> Executor
Executor --> BandBus
Reporting --> BandBus
Executor --> AIML
Executor --> Featherless
Executor --> OpenRouter
API --> BandSDK
BandSDK --> BandBus
BandBus --> EventStore
BandBus --> Blackboard
Orchestrator --> ClaimMgr
| Decision | Rationale |
|---|---|
| Event sourcing | Every state change is an immutable event. This enables time-travel, full audit trails, and deterministic replay. |
| Shared blackboard | Agents read from and write to a materialized context view. No agent-to-agent coupling — all coordination happens through the blackboard. |
| Atomic task claims | TaskClaimManager prevents duplicate agent execution. Each event-agent pair can only be claimed once. |
| Async-first | SQLAlchemy async sessions, asyncio.create_task for handler dispatch, asyncio.wait_for with 120s timeout on LLM calls. |
| Multi-model routing | Analytical agents (Triage, Risk, Commander) use Qwen 2.5-72B for deep reasoning. Rapid agents (Hunter, RedTeam, Reporter) use Mistral Nemo for speed. |
The AI pipeline processes evidence through a directed acyclic graph of context transformations. Each node represents a context type; edges represent event triggers:
graph LR
E["📥 Evidence:Ingested"] -->|triggers| T["🔬 Triage-1<br/>Qwen 2.5-72B"]
T -->|"publishes Hypothesis"| H["💡 Context:Published:Hypothesis"]
H -->|triggers| TH["🎯 Hunter-1<br/>Mistral Nemo"]
H -->|triggers| RT["🔴 RedTeam-1<br/>Mistral Nemo"]
TH -->|"publishes Validation"| V["✅ Context:Published:Validation"]
RT -->|"publishes Dissent"| D["⚔️ Context:Published:Dissent"]
V -->|triggers| RA["📊 Risk-1<br/>Qwen 2.5-72B"]
RA -->|"publishes Risk"| R["⚠️ Context:Published:Risk"]
R -->|triggers| IC["🛡️ Commander-1<br/>Qwen 2.5-72B"]
IC -->|"publishes Containment"| C["🔒 Context:Published:Containment"]
C -->|triggers| ER["📋 Reporter-1<br/>Mistral Nemo"]
ER -->|"publishes CaseFile"| CF["📄 Context:Published:CaseFile"]
CF -->|triggers| PDF["📑 ReportingService<br/>PDF Generation"]
style E fill:#3B82F6,color:#fff
style H fill:#F59E0B,color:#fff
style V fill:#10B981,color:#fff
style D fill:#EF4444,color:#fff
style R fill:#F97316,color:#fff
style C fill:#8B5CF6,color:#fff
style CF fill:#059669,color:#fff
style PDF fill:#6366F1,color:#fff
Every agent produces a standardized ContextPackage — the universal data format flowing through the pipeline:
{
"header": {
"context_id": "uuid-v4",
"incident_id": "band-room-id",
"parent_context_id": "uuid-v4 | null",
"agent_id": "Triage-1",
"context_type": "Hypothesis",
"timestamp": "2026-06-17T15:30:00Z"
},
"payload": {
// Agent-specific structured output
},
"metadata": {
"confidence": 0.85,
"evidence_references": ["event-id-1"],
"model_used": "qwen/qwen-2.5-72b-instruct"
}
}The AgentExecutor normalizes raw LLM output into this contract before validation. If the LLM returns a flat JSON object without the header/payload/metadata structure, the normalizer infers the structure and assigns generated IDs, timestamps, and confidence scores.
|
Investigation Launcher — Submit raw evidence, select from sample scenarios, or paste log data directly. One click to launch a full autonomous investigation. |
Live Dashboard — Watch the investigation unfold in real time. The knowledge graph grows as agents publish context, the timeline tracks every event, and agent status panels show execution progress. |
|
Agent Pipeline — Six specialized agents form a directed investigation workflow with parallel validation paths and adversarial challenge. |
Investigation History — Browse all past investigations with status tracking, severity indicators, and one-click access to detailed results and PDF reports. |
SentinelFlow is designed with security-first principles appropriate for handling sensitive incident data:
- Local persistence — Investigation data is stored in a local SQLite database via aiosqlite. No incident data is stored in third-party cloud databases.
- Immutable audit log — The
EventStoremaintains an append-only event log. Events cannot be modified or deleted after creation. - Scoped isolation — Each investigation operates in its own Band room with a unique room ID. Cross-investigation data access is prevented by design.
- Environment-based secrets — All API keys (Band, AI/ML API, Featherless, OpenRouter) are loaded from environment variables, never hardcoded.
- CORS configuration — The backend middleware supports configurable origin restrictions. Production deployments should restrict
allow_originsto the frontend domain. - Input validation — All API inputs are validated through Pydantic models with strict type enforcement.
- Atomic task claims — The
TaskClaimManageruses database-level uniqueness constraints to prevent duplicate agent execution, even under concurrent event processing. - Timeout enforcement — LLM calls are wrapped in
asyncio.wait_forwith a 120-second timeout. Failed calls trigger exponential backoff retries (up to 3 attempts). - Output validation — Every LLM response passes through the
JsonValidatorbefore publication. Malformed outputs are rejected and the task is marked as failed. - Confidence scoring — Each context package includes a
confidencescore (0.0–1.0) computed from LLM output or derived heuristically, enabling downstream agents to weight their analysis.
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 16.2.9 | App Router, server components, API proxy |
| React | 19.2.4 | Component framework with concurrent features |
| TypeScript | 5.x | Type-safe development across the frontend |
| TailwindCSS | 4.x | Utility-first styling with PostCSS integration |
| Zustand | 5.0.14 | Lightweight state management for incidents and graph |
React Flow (@xyflow/react) |
12.11.0 | Interactive knowledge graph visualization |
| Framer Motion | 12.40.0 | Animation for agent status transitions and node entrances |
| Zod | 4.4.3 | Runtime schema validation for API responses |
| Technology | Version | Purpose |
|---|---|---|
| FastAPI | 0.115.x | Async REST API and WebSocket server |
| SQLAlchemy | 2.x (async) | ORM with async session support |
| aiosqlite | — | Async SQLite driver for local persistence |
| Pydantic | 2.x | Request/response validation and serialization |
| Band SDK | — | Real-time agent-to-agent collaboration |
| Jinja2 | — | Prompt template rendering for agents |
| fpdf2 | — | PDF report generation |
| tenacity | — | Retry logic with exponential backoff for LLM calls |
| httpx | — | Async HTTP client for LLM API calls |
| Uvicorn | — | ASGI server for production deployment |
| Model | Provider | Agents | Strength |
|---|---|---|---|
qwen/qwen-2.5-72b-instruct |
AI/ML API | Triage-1, Risk-1, Commander-1 | Deep analytical reasoning, structured JSON output |
mistralai/mistral-nemo |
Featherless AI | Hunter-1, RedTeam-1, Reporter-1 | Rapid inference, adversarial analysis, narrative synthesis |
| Multi-model fallback | OpenRouter | All (fallback) | Provider redundancy and model selection flexibility |
SentinelFlow deploys as two independent services with a unified API proxy:
The Next.js frontend deploys to Vercel with automatic API proxying to the backend:
Deploy with the Vercel CLI or connect the GitHub repository for automatic deployments.
The FastAPI backend deploys to Render as a Python web service:
# render.yaml
services:
- type: web
name: sentinelflow-backend
env: python
buildCommand: "cd apps/backend && pip install -e ."
startCommand: "cd apps/backend && uvicorn app.main:app --host 0.0.0.0 --port $PORT"
envVars:
- key: APP_MODE
value: live
- key: BAND_API_KEY
sync: false
- key: BAND_BASE_URL
value: https://app.band.ai
- key: BAND_WS_URL
value: wss://app.band.ai/api/v1/socket/websocket
- key: AIML_API_KEY
sync: false
- key: FEATHERLESS_API_KEY
sync: false
- key: OPENROUTER_API_KEY
sync: false| Variable | Required | Description |
|---|---|---|
BAND_API_KEY |
Yes | Band SDK API key for agent authentication |
BAND_BASE_URL |
No | Band REST API URL (default: https://app.band.ai) |
BAND_WS_URL |
No | Band WebSocket URL (default: wss://app.band.ai/api/v1/socket/websocket) |
AIML_API_KEY |
Yes | AI/ML API key for Qwen 2.5-72B inference |
FEATHERLESS_API_KEY |
Yes | Featherless AI key for Mistral Nemo inference |
OPENROUTER_API_KEY |
No | OpenRouter key for multi-model fallback |
APP_MODE |
No | Set to live for production, demo for demo mode |
NEXT_PUBLIC_API_URL |
Yes | Backend API URL for the frontend (e.g., http://localhost:8000) |
- Node.js ≥ 20 (for Next.js 16)
- Python ≥ 3.11 (for FastAPI async features)
- npm ≥ 10 (workspace support)
git clone https://github.com/aryanthopate/SentinelFlow.git
cd SentinelFlow
# Install frontend dependencies (npm workspaces)
npm installcd apps/backend
# Create a virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS/Linux
source .venv/bin/activate
# Install backend dependencies
pip install -e .
# Configure environment
cp .env.example .env
# Edit .env and add your API keys:
# BAND_API_KEY=your_band_api_key
# AIML_API_KEY=your_aiml_api_key
# FEATHERLESS_API_KEY=your_featherless_api_keycd apps/frontend
# Configure environment
cp .env.example .env.local
# Edit .env.local:
# NEXT_PUBLIC_API_URL=http://localhost:8000Option A: Manual start
# Terminal 1 — Backend
cd apps/backend
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# Terminal 2 — Frontend
npm run dev:frontendOption B: Docker Compose
docker-compose upThis starts both services:
- Frontend:
http://localhost:3000 - Backend:
http://localhost:8000 - API docs:
http://localhost:8000/docs
# Health check
curl http://localhost:8000/api/v1/health
# Expected: {"status":"healthy","service":"sentinelflow-api"}
# Open the frontend
# Navigate to http://localhost:3000sentinelflow/
├── apps/
│ ├── frontend/ # Next.js 16 application
│ │ ├── src/
│ │ │ ├── app/
│ │ │ │ ├── page.tsx # Landing page
│ │ │ │ ├── investigate/page.tsx # Investigation launcher
│ │ │ │ ├── incident/[id]/page.tsx # Live investigation dashboard
│ │ │ │ ├── incident/[id]/report/page.tsx # PDF report viewer
│ │ │ │ ├── incidents/page.tsx # Investigation history
│ │ │ │ └── layout.tsx # Root layout
│ │ │ ├── components/
│ │ │ │ ├── graph/
│ │ │ │ │ ├── KnowledgeGraphCanvas.tsx # React Flow canvas
│ │ │ │ │ ├── nodes.tsx # Custom node renderers
│ │ │ │ │ └── edges.tsx # Custom edge renderers
│ │ │ │ ├── incident/
│ │ │ │ │ ├── InvestigationControlPanel.tsx # Agent controls
│ │ │ │ │ ├── CompletionModal.tsx # Investigation complete modal
│ │ │ │ │ └── TimeScrubber.tsx # Time-travel scrubber
│ │ │ │ ├── band/
│ │ │ │ │ └── EventBusTerminal.tsx # Event bus terminal view
│ │ │ │ ├── layout/
│ │ │ │ │ ├── CommandCenterLayout.tsx # Investigation layout wrapper
│ │ │ │ │ └── GlobalHeader.tsx # Global navigation header
│ │ │ │ └── ui/
│ │ │ │ └── Widgets.tsx # Shared UI components
│ │ │ ├── hooks/
│ │ │ │ └── useBandWebsocket.ts # WebSocket connection hook
│ │ │ └── stores/
│ │ │ ├── incident.ts # Incident state (Zustand)
│ │ │ └── graph.ts # Knowledge graph state (Zustand)
│ │ ├── package.json
│ │ ├── next.config.ts
│ │ ├── tsconfig.json
│ │ └── postcss.config.mjs
│ │
│ └── backend/ # FastAPI application
│ └── app/
│ ├── main.py # FastAPI lifespan, Band agent startup
│ ├── api/
│ │ ├── router.py # API router aggregation
│ │ ├── incidents.py # Incident CRUD + PDF endpoints
│ │ └── ws.py # WebSocket connection manager
│ ├── agents/
│ │ ├── registry.py # AGENT_REGISTRY (6 agents)
│ │ ├── executor.py # AgentExecutor (LLM calls, retry)
│ │ ├── context_builder.py # Context assembly for prompts
│ │ ├── prompt_builder.py # Jinja2 template rendering
│ │ ├── json_validator.py # Output validation
│ │ └── prompts/
│ │ ├── triage_specialist.jinja
│ │ ├── threat_hunter.jinja
│ │ ├── red_team_challenger.jinja
│ │ ├── risk_analyst.jinja
│ │ ├── incident_commander.jinja
│ │ └── exec_reporter.jinja
│ ├── band/
│ │ ├── bus.py # BandBus event pub/sub
│ │ ├── orchestrator.py # TaskOrchestrator
│ │ ├── repository.py # EventStore, Blackboard, TaskClaimManager
│ │ ├── reporting.py # PDF auto-generation on CaseFile
│ │ └── middleware.py # Event validation middleware
│ ├── integrations/band/
│ │ ├── band_adapter.py # Band SDK ↔ BandBus adapter
│ │ ├── band_agents.py # Agent identity management
│ │ ├── band_auth.py # Environment-based auth config
│ │ ├── band_client.py # REST client singleton
│ │ ├── band_context.py # Context serialization
│ │ ├── band_events.py # Event type mapping
│ │ ├── band_messages.py # Message formatting
│ │ └── band_rooms.py # Room creation and management
│ ├── core/
│ │ ├── database.py # SQLAlchemy async engine + sessions
│ │ ├── llm_client.py # Multi-provider LLM client
│ │ └── telemetry.py # Structured logging
│ ├── models/ # SQLAlchemy ORM models
│ │ ├── incident.py
│ │ ├── event_log.py
│ │ ├── context.py
│ │ ├── evidence.py
│ │ └── task_claim.py
│ ├── schemas/ # Pydantic request/response schemas
│ │ ├── band.py
│ │ └── common.py
│ ├── services/ # Business logic services
│ └── utils/
│ └── pdf_generator.py # Executive PDF generation
│
├── packages/
│ └── shared-types/ # Shared TypeScript type definitions
│
├── docs/ # Documentation
├── docker-compose.yml # Local multi-service development
├── vercel.json # Vercel frontend deployment config
├── render.yaml # Render backend deployment config
├── package.json # npm workspaces root
└── start_servers.bat # Windows convenience script
All endpoints are prefixed with /api/v1. The backend serves both REST and WebSocket protocols.
| Method | Endpoint | Description | Request Body | Response |
|---|---|---|---|---|
GET |
/health |
Service health check | — | { "status": "healthy", "service": "sentinelflow-api" } |
POST |
/incidents |
Create a new investigation | { "evidence": "string", "title": "string" } |
Incident record with Band room ID |
GET |
/incidents |
List all investigations | — | { "incidents": [...] } with status and severity |
GET |
/incidents/{id}/events |
Get full event history | — | { "incident_id": "...", "events": [...] } |
GET |
/incidents/{id}/state |
Get current blackboard state | — | { "incident_id": "...", "state": [...] } |
GET |
/incidents/{id}/pdf |
Download executive PDF report | — | application/pdf binary response |
| Endpoint | Description |
|---|---|
ws://host/ws/v1/incidents/{id}/stream |
Real-time event stream for an investigation |
WebSocket message types:
| Direction | Type | Description |
|---|---|---|
| Server → Client | NEW_EVENT |
New event published (agent status, context, evidence) |
| Client → Server | SCRUB_TIME |
Request state replay at a specific timestamp |
| Server → Client | REPLAY_STATE |
Full state snapshot at the requested timestamp |
| Server → Client | ERROR |
Error response for invalid requests |
Example: Time-travel request
// Client sends:
{
"type": "SCRUB_TIME",
"target_timestamp": "2026-06-17T15:30:00Z"
}
// Server responds:
{
"type": "REPLAY_STATE",
"target_timestamp": "2026-06-17T15:30:00Z",
"state": [ /* context packages active at that time */ ],
"events": [ /* all events up to that timestamp */ ]
}SentinelFlow is built on an extensible event-driven architecture. Planned enhancements include:
- Agent Plugins — User-defined agents with custom trigger events, prompt templates, and model assignments. Register new agents at runtime without modifying the core registry.
- SIEM Integration — Native connectors for Splunk, Elastic Security, and Microsoft Sentinel to ingest alerts directly into the investigation pipeline.
- Threat Intelligence Enrichment — Automatic enrichment of indicators (IPs, domains, hashes) via VirusTotal, AbuseIPDB, and Shodan APIs during the hunting phase.
- Multi-Incident Correlation — Cross-incident analysis to identify attack campaigns spanning multiple investigations, powered by graph-based pattern matching on the knowledge store.
- RBAC and Audit — Role-based access control for investigation viewing and management, with a comprehensive audit trail for compliance (SOC 2, ISO 27001).
- Custom Model Routing — Per-agent model override via environment variables or API configuration, enabling teams to bring their own fine-tuned models.
- Export and Integration — STIX/TAXII export for threat intelligence sharing, Jira/ServiceNow ticket creation, and Slack/Teams notifications on investigation milestones.
- Human-in-the-Loop — Optional approval gates between pipeline stages, allowing analysts to review and override agent decisions before downstream processing continues.
SentinelFlow is released under the MIT License.
MIT License
Copyright (c) 2026 SentinelFlow Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.









