Skip to content
Docs/Platforms/IRFlow
Edit on GitHub

IRFlow

IRFlow is the incident response workflow engine for the opensecstack ecosystem. It manages the full incident lifecycle — from detection through containment, eradication, recovery, and closure — while enforcing CITADEL MARSHAL governance and tracking NIS2 Article 23 notification deadlines at every step.

Overview

IRFlow is a Go service (v1.0.0) licensed under AGPL-3.0. It listens on port 8083 and exposes a JWT-protected REST API alongside public HMAC-SHA256 signed webhook endpoints for receiving events from APIGuard, CITADEL, and ThreatFlow. PostgreSQL 16 is the single source of truth; the service is stateless and can run behind a load balancer with multiple replicas.

Key features

  • Guarded incident state machine — incidents follow a strict lifecycle: open → investigating → contained → eradicating → recovering → closed. The API enforces all transitions.
  • CITADEL MARSHAL governance — every privileged action is evaluated through the 5-gate MARSHAL engine. A REFUSE or HARD_STOP outcome prevents local persistence and returns HTTP 403. CITADEL is never bypassed even when unreachable.
  • CITADEL WORM anchoring — incident creation is anchored in the tamper-evident audit chain; the returned worm_entry_id is persisted on the incident record.
  • NIS2 Article 23 notifications — regulatory-significant incidents (P1/P2/P3) trigger an asynchronous notification to the NIS2 Compass Article 21(2)(b) Incident Handling control. The async design ensures a slow Compass API can never block the incident creation path.
  • Graph-based playbook executor — playbooks are defined as graphs with OnSuccess / OnFailure branching, per-step timeouts, and a cycle guard (max 100 steps per execution).
  • HMAC-signed webhook ingestion — inbound events from APIGuard, CITADEL, and ThreatFlow are verified with HMAC-SHA256 and a ±5-minute replay protection window.
  • IOC enrichment — incidents can have indicators of compromise (IOCs) attached and cross-referenced with ThreatFlow intelligence.
  • JWT + RBAC — HS256 bearer tokens with five canonical roles: admin, operator, verifier, viewer, and service.
  • Observability — Prometheus metrics at /metrics; structured JSON audit log with request_id propagation; the audit middleware fires before authentication so rejected requests are also logged.

Architecture

IRFlow has three concentric responsibility layers:

  1. Transport — a chi HTTP router with a middleware stack providing request IDs, audit logging, Prometheus metrics, JWT authentication, and HMAC verification for webhook routes.
  2. Domain services — incident.Service encodes lifecycle rules, Separation of Duties checks, and NIS2 notification thresholds. playbook.Service drives the graph-traversal executor.
  3. Persistence + governance — PGStore adapters backed by PostgreSQL 16 (pgxpool); CitadelClient for MARSHAL evaluation and WORM emission; NIS2Client for Article 23 notifications. All boundary crossings are HMAC-signed.
PackageRole
cmd/irflowCLI: serve, migrate, version, auth issue
internal/apichi router, middleware stack, HTTP handlers
internal/authJWT verification, RBAC guards, audit logging
internal/incidentDomain types, Service, governance interfaces, Stats
internal/playbookDomain types, Service, Executor (graph traversal)
internal/governanceCitadelClient (MARSHAL + WORM), NIS2Client
internal/dbpgxpool, PGStore (incidents), PGPlaybookStore
internal/webhookHMAC-SHA256 verifier and typed inbound payloads

The service layer depends on interfaces defined next to its own domain types — not on concrete db or governance packages — so unit tests run against in-memory mocks and integration tests run against live PostgreSQL without changing any service code.

Ports & endpoints

ServiceDefault port
IRFlow API8083
MethodPathAuthDescription
GET/healthpublicLiveness check
GET/health/detailpublicLiveness + DB ping + version info
GET/metricspublicPrometheus scrape endpoint
POST/api/v1/webhooks/apiguardHMACInbound APIGuard scan events
POST/api/v1/webhooks/citadelHMACInbound CITADEL governance events
POST/api/v1/webhooks/threatflowHMACInbound ThreatFlow IOC events
GET / POST/api/v1/incidentsJWTList / create incidents
GET / PATCH / DELETE/api/v1/incidents/{id}JWTFetch / update / delete incident
POST / GET/api/v1/incidents/{id}/actionsJWTSubmit / list governed actions
GET/api/v1/incidents/{id}/timelineJWTChronological incident timeline
POST / GET/api/v1/incidents/{id}/iocsJWTAttach / list IOCs
GET / POST/api/v1/playbooksJWTList / create playbooks
POST/api/v1/playbooks/{id}/executeJWTAsync execution; returns 202 + Execution
GET/api/v1/statsJWTDashboard aggregation
Quick start
Bash
"cm"># Build and run
make build
./bin/irflow migrate
./bin/irflow serve

"cm"># Or with Docker
docker build -t irflow .
docker run -p 8083:8083 --env-file .env irflow

"cm"># Issue a dev JWT (local testing only)
export IRFLOW_AUTH_SECRET=local-secret
./bin/irflow auth issue --user alice --role operator --ttl 1h

"cm"># Hit a protected endpoint
curl -H "Authorization: Bearer $TOKEN" http://localhost:8083/api/v1/incidents

Integration

sinauth (identity)

IRFlow authenticates operators via sinauth SSO — the SIN identity provider (OAuth 2.0 / OIDC, authorization code + PKCE). Access tokens are RS256-signed JWTs issued by https://auth.sin.to and validated against the sinauth JWKS endpoint at https://auth.sin.to/.well-known/jwks.json. See the sinauth integration guide for token validation setup, RBAC mapping, and MFA configuration.

CITADEL (governance)

IRFlow integrates with CITADEL at two points. Every privileged action is evaluated by CITADEL MARSHAL via a dual-control Kerkese call; a REFUSE or HARD_STOP outcome returns HTTP 403 and the action is never persisted locally. Incident creation is anchored in the CITADEL WORM audit chain. Set IRFLOW_CITADEL_API_URL and IRFLOW_CITADEL_KEY_SECRET in production — omitting these leaves IRFlow in dev mode where governance is not enforced.

NIS2 Compass (compliance)

When an incident with severity P1, P2, or P3 is created, IRFlow fires an asynchronous notification to NIS2 Compass (IRFLOW_NIS2_API_URL) to update the Article 21(2)(b) Incident Handling control. The notification has a 30-second per-attempt timeout; failures are logged and nis2_notified_at is only persisted on success.

APIGuard (API security)

IRFlow accepts HMAC-signed webhook events from APIGuard at POST /api/v1/webhooks/apiguard. Critical or high findings from APIGuard can automatically open new incidents or enrich existing ones. Configure the shared secret with IRFLOW_WEBHOOK_APIGUARD_SECRET.

ThreatFlow (threat intelligence)

IRFlow accepts HMAC-signed events from ThreatFlow at POST /api/v1/webhooks/threatflow. ThreatFlow also receives incident artefacts from IRFlow for retroactive IOC matching, and pushes STIX 2.1 IOC bundles back for incident enrichment. Configure the shared secret with IRFLOW_WEBHOOK_THREATFLOW_SECRET.

Note: Minimum production configuration requires IRFLOW_DB_PASSWORD, IRFLOW_AUTH_SECRET, IRFLOW_CITADEL_API_URL, IRFLOW_CITADEL_KEY_SECRET, IRFLOW_NIS2_API_URL, IRFLOW_NIS2_API_KEY, IRFLOW_NIS2_ASSESSMENT_ID, and one webhook secret per integrated source. An empty IRFLOW_AUTH_SECRET enables dev mode — never use in production.

Full documentation

The complete IRFlow documentation lives in the irflow/docs folder on GitHub. Key references:

  • docs/api.md — complete REST API reference with examples and Prometheus metrics catalogue
  • docs/architecture.md — component map, package layout, request lifecycle, and design decisions
  • CHANGELOG.md — release history
  • SECURITY.md — vulnerability reporting and threat model

SIN — Security Intelligence Network — Open-source cybersecurity & compliance for the EU Digital Decade.

Apache-2.0 & AGPL-3.0 · GitHub · Contribute