Architecture Reference

Event Bus Architecture

The Event Bus is the central nervous system of Sentinel AI SOC — a 10-step pipeline that processes every security event from ingestion to response.


Design Philosophy

Why HTTP/2 JSON (Not gRPC)?

Sentinel uses HTTP/2 JSON for all inter-component communication. This is a deliberate architectural decision:

FactorgRPCHTTP/2 JSON
CGO Dependency❌ Requires CGO for protobuf✅ Zero CGO (pure Go)
DeploymentComplex (proto gen, shared types)Simple (standard HTTP client)
DebuggabilityOpaque binary framesHuman-readable JSON
Throughput~550 events/sec~520 events/sec
Latency (p50)0.8ms1.1ms
Binary size+12MB (grpc-go + protobuf)0 additional

Red Team Validation: In production red team exercises, the ~5% throughput difference was negligible for SOC workloads (target: ≥500 events/sec). The Zero CGO invariant eliminates entire classes of build and deployment issues.


Pipeline Architecture

┌─────────────┐ │ Sensor │ (sentinel-core, Shield, immune, custom) └──────┬──────┘ │ HTTP POST /api/v1/soc/events ▼ ┌──────────────────────────────────────────────────────┐ │ EVENT BUS │ │ │ │ Step 0: Secret Scanner (INVARIANT — non-disableable)│ │ ↓ │ │ Step 1: Sensor Authentication (PSK / mTLS) │ │ ↓ │ │ Step 2: Rate Limiter (≤100/sec per sensor) │ │ ↓ │ │ Step 3: Deduplication (10s sliding window) │ │ ↓ │ │ Step 4: Schema Validation (AlertEvent JSON Schema) │ │ ↓ │ │ Step 5: Decision Logger (SHA-256 hash chain) │ │ ↓ │ │ Step 6: Persistence (SQLite WAL mode) │ │ ↓ │ │ Step 7: Correlation Engine (15 rules) │ │ ↓ │ │ Step 8: Playbook Trigger (auto-response ≤ MEDIUM) │ │ ↓ │ │ Step 9: Webhook / SSE Push (dashboard + external) │ │ │ └──────────────────────────────────────────────────────┘

Step Details

Step 0: Secret Scanner

Type: INVARIANT — cannot be disabled by any configuration.

Scans every incoming event payload for leaked secrets:

PatternExamples
API Keyssk-..., AKIA..., gsk_...
Tokensghp_..., xoxb-..., Bearer ...
CredentialsPasswords, connection strings
Private Keys-----BEGIN RSA PRIVATE KEY-----

If a secret is detected, the event is:

  1. Redacted — secret replaced with [REDACTED:key_type]
  2. Flaggedsecret_detected: true metadata added
  3. Forwarded — processing continues with clean payload
Go
// pipeline.go — Secret Scanner is always first func (p *Pipeline) Process(event *AlertEvent) error { // Step 0: Secret Scanner (INVARIANT — never skip) event.Payload = p.secretScanner.Scan(event.Payload) // All subsequent steps... }

Step 1: Sensor Authentication

Every sensor must authenticate before events are accepted:

MethodConfigurationUse Case
PSKPre-shared key in headerSimple deployments
mTLSClient certificateProduction deployments
NoneDisabledDevelopment only
YAML
# syntrex.yaml sensors: - type: sentinel-core auth: type: "psk" key: "${SENSOR_CORE_PSK}"

Step 2: Rate Limiter

Token bucket algorithm per sensor_id:

  • Default: 100 events/sec per sensor
  • Burst: 150 events (1.5x bucket)
  • Overflow: Events queued, then dropped with warning
Sensor → [Token Bucket: 100/sec] → Accept or Queue

When a sensor exceeds its rate limit:

  1. SOC generates a rate_limit_exceeded alert
  2. Events are queued (up to buffer capacity)
  3. If queue is full, events are dropped with dropped_events metric increment

Step 3: Deduplication

Sliding window deduplication using event fingerprinting:

Fingerprint = SHA256(source + category + description + severity)
SettingDefaultDescription
dedup_window10sTime window for duplicate detection
AlgorithmSHA-256 fingerprintExact match dedup

If a duplicate is found, it is silently dropped. The dedup_count metric tracks filtered duplicates.

Step 4: Schema Validation

Every event must conform to the AlertEvent schema:

JSON
{ "source": "sentinel-core", // Required: sensor identifier "severity": "HIGH", // Required: INFO|LOW|MEDIUM|HIGH|CRITICAL "category": "jailbreak", // Required: attack category "description": "...", // Required: human-readable description "confidence": 0.95, // Optional: 0.0-1.0 "payload": {}, // Optional: additional data "timestamp": "2026-03-13T..." // Auto-set if not provided }

Invalid events are rejected with HTTP 400 and logged.

Step 5: Decision Logger

Immutable audit trail using SHA-256 hash chains:

Entry N: event_id: EVT-1710295200-042 action: "accepted" timestamp: 2026-03-13T01:00:00Z prev_hash: "a3b8c1d2e5f6..." hash: SHA256(entry_data + prev_hash) = "7f8e9d0c..."

Each entry is cryptographically linked to the previous one. Any modification breaks the chain and is detected by gomcp doctor.

Storage: Append-only JSONL file with O_APPEND flag (kernel-level atomicity).

Optional: TPM 2.0 sealing for hardware-bound integrity (SEC-006).

Step 6: Persistence

Events are persisted to SQLite in WAL (Write-Ahead Logging) mode:

SettingValue
EngineSQLite 3.40+
ModeWAL (concurrent reads)
JournalWAL mode
SynchronousNORMAL
Max DB sizeConfigurable (default: 10GB)

Step 7: Correlation

Events are matched against 15 correlation rules. See Correlation Engine for full details.

Step 8: Playbook Trigger

If a correlation rule matches and a playbook is configured:

SeverityAction
INFO / LOWAuto-execute playbook (if configured)
MEDIUMAuto-execute playbook
HIGHRequire operator approval (Zero-G mode)
CRITICALRequire operator approval (Zero-G mode)

Step 9: Webhook / SSE Push

After processing, events and incidents are pushed to:

TargetProtocolPurpose
DashboardSSEReal-time UI updates
WebhooksHTTP POSTExternal SIEM integration
Slack/TeamsWebhookOperator notifications

Ring Buffer

The Event Bus uses a lock-free ring buffer for ingestion:

┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ ↑ ↑ Read pointer Write pointer
SettingDefaultDescription
buffer_size10,000Ring buffer capacity
batch_size100Events per processing batch
flush_interval1sMax wait before batch flush

Metrics

The Event Bus exposes Prometheus metrics:

MetricTypeDescription
sentinel_events_totalcounterTotal events received
sentinel_events_processedcounterEvents successfully processed
sentinel_events_droppedcounterEvents dropped (rate limit / buffer full)
sentinel_events_deduplicatedcounterDuplicate events filtered
sentinel_pipeline_latency_mshistogramEnd-to-end pipeline latency
sentinel_secrets_detectedcounterSecrets found by scanner
sentinel_buffer_usagegaugeCurrent ring buffer utilization

Error Handling

ErrorBehavior
Sensor auth failureHTTP 401, logged, auth_failures metric
Rate limit exceededHTTP 429, queued, rate_limited metric
Schema validation failureHTTP 400, logged, validation_failures metric
Database write failureRetry 3x, then queue, alert generated
Correlation failureEvent persisted, correlation skipped, alert

Next Steps