Date: February 13, 2026 Project: FoodProject SOC Platform (Wazuh + Shuffle + IRIS-web + SOC Integrator)
The MVP platform is operational and running end-to-end in the lab environment. Core integrations are in place:
All major containers are currently up, and key health checks are passing.
run-combined-stack.sh)up, down, logs, status, helpwazuh, iris, shuffle, pagerduty, integrator)soc-status.sh)POST /mvp/incidents/ingestPOST /mvp/ioc/evaluatePOST /mvp/vpn/evaluateGET /mvp/config/policiesPUT /mvp/config/policiesGET /mvp/health/dependenciessoc-integrator-db)scripts/send-wazuh-test-events.shREADME.md.gitignoreCurrent stack status: UP
Healthy/available components:
Endpoint checks:
/health: OK@startuml
title FoodProject SOC Platform - System Architecture (MVP)
skinparam componentStyle rectangle
actor "Analyst" as analyst
cloud "External Log Sources" as logs
rectangle "SOC Shared Docker Network" {
node "Wazuh Stack" as wazuh {
component "Wazuh Manager" as wazuh_mgr
component "Wazuh Indexer" as wazuh_idx
component "Wazuh Dashboard" as wazuh_dash
}
node "Shuffle Stack" as shuffle {
component "Shuffle Frontend" as shuf_fe
component "Shuffle Backend" as shuf_be
component "Shuffle Orborus" as shuf_orb
component "Shuffle OpenSearch" as shuf_os
}
node "IRIS-web Stack" as iris {
component "IRIS Web App" as iris_app
database "IRIS DB" as iris_db
component "IRIS RabbitMQ" as iris_mq
}
node "SOC Integrator Stack" as integ {
component "soc-integrator API" as soc_api
database "soc-integrator-db" as soc_db
}
component "PagerDuty Stub" as pd_stub
}
logs --> wazuh_mgr : Security events
wazuh_mgr --> wazuh_idx : Index alerts
analyst --> wazuh_dash : Investigate alerts
wazuh_dash --> wazuh_idx : Query data
wazuh_mgr --> soc_api : Alert/incident input
soc_api --> soc_db : Persist incidents\npolicies\naudit
soc_api --> iris_app : Create/update cases
soc_api --> pd_stub : Escalation (MVP)
soc_api --> shuf_be : Trigger automation
shuf_fe --> shuf_be : UI/API
shuf_be --> shuf_os : Read/write workflow data
shuf_orb --> shuf_be : Execution queue polling
shuf_orb --> shuf_os : Workflow state interactions
iris_app --> iris_db : Case data
iris_app --> iris_mq : Async jobs
@enduml
Next milestone: MVP UAT Completion
Target outputs:
Date: February 26, 2026 Project: FoodProject SOC Platform (Wazuh + Shuffle + IRIS-web + SOC Integrator)
soc-integrator:
POST /ioc/enrichPOST /ioc/evaluateGET /ioc/historyPOST /ioc/upload-filePOST /ioc/evaluate-fileGET /ioc/analysis/{analysis_id}ioc_trace) and repository methods for audit/history.soc-integrator:
POST /iris/ticketsGET /iris/ticketsscripts/seed-iris-demo-data.shshuffle-workflows/sample-webhook-soc-integrator-iris-workflow.jsonshuffle-workflows/sample-webhook-soc-integrator-iris-workflow.mdscripts/update-shuffle-workflow-from-template.sh07ecad05-ff68-41cb-888d-96d1a8e8db4b) with:
http 1.4.0) to call soc-integrator ticket APIsoc-integrator by attaching soc-integrator service to Shuffle execution network(s) in:
compose-overrides/soc-integrator.ymlhttp://soc-integrator:8080/health.env and .env.* to root .gitignore (kept .env.example tracked).soc-integrator/.env for Shuffle, IRIS, VirusTotal, and AbuseIPDB.soc-integrator health endpoint: reachable.--forever) to simulation scripts for long-running lab traffic generation.scripts/send-wazuh-test-events.shDate: March 4, 2026 Project: FoodProject SOC Platform (Wazuh + Shuffle + IRIS-web + SOC Integrator)
scripts/send-wazuh-proposal-required-events.shscripts/send-wazuh-proposal-appendix-b-events.sh--profile=simulation|production (default remains simulation)production profile, simulator messages omit section/usecase_id/usecase markers and emit production-like key/value fields to support real parser/decoder testing.POST /ingest/wazuh-alert in soc-integrator:
GET /ingest/wazuh-alert/samples with practical sample request/response cases for:
soc-integrator/app/services/mvp_service.pycountry and/or src_lat/src_lon)section/usecase_id C1 markers are kept as fallback for backward compatibility.110xxx production rules with consistent hit evidence.flowchart LR
A[Wazuh Raw Alert<br/>full_log + rule + agent] --> B[POST /wazuh/sync-to-mvp<br/>or /ingest/wazuh-alert]
B --> C[mvp_service.normalize_wazuh_hit]
C --> D[KV parse from full_log<br/>src_ip user country event_type]
D --> E[Normalized Event Schema<br/>source event_type timestamp severity<br/>asset network payload risk_context]
E --> F{C-Detection Evaluate}
F --> C1[C1 Impossible Travel<br/>geo context + success login + user/src_ip]
F --> C2[C2 Credential Abuse<br/>off-hours / dormant / service interactive / rapid privilege]
F --> C3[C3 Lateral Movement<br/>multi-host auth / SMB-RDP burst / internal scan]
C1 --> G[Persist c_detection_events]
C2 --> G
C3 --> G
G --> H[Optional Incident Pipeline<br/>IRIS case + Shuffle + PagerDuty stub]
scripts/send-wazuh-endpoint-agent-test-events.shscripts/ for firewall and endpoint scenarios with continuous mode enabledSecurity Detection & Threat Intelligence Enhancement Proposal-2.mdRequest:
curl -sS -X POST http://localhost:8088/ioc/enrich \
-H 'Content-Type: application/json' \
-d '{
"ioc_type": "domain",
"ioc_value": "google.com",
"sources": ["virustotal"]
}'
Sample response:
{
"success": true,
"ioc_type": "domain",
"ioc_value": "google.com",
"enrichment": {
"virustotal": {
"reputation": 120,
"last_analysis_stats": {
"malicious": 0,
"suspicious": 0,
"harmless": 90
}
}
}
}
Request:
curl -sS -X POST http://localhost:8088/ioc/evaluate \
-H 'Content-Type: application/json' \
-d '{
"ioc_type": "hash",
"ioc_value": "44d88612fea8a8f36de82e1278abb02f",
"sources": ["virustotal"]
}'
Sample response:
{
"success": true,
"matched": true,
"severity": "high",
"reason": "VirusTotal marked IOC as malicious",
"ioc_type": "hash",
"ioc_value": "44d88612fea8a8f36de82e1278abb02f"
}
Request:
curl -sS -X POST http://localhost:8088/iris/tickets \
-H 'Content-Type: application/json' \
-d '{
"title": "Suspicious domain detected",
"description": "Automated ticket from IOC evaluation pipeline",
"severity": "medium",
"source_ref": "shuffle-webhook-demo"
}'
Sample response:
{
"success": true,
"ticket_id": 53,
"case_id": 53,
"status": "open"
}
enrich for context, evaluate for action/verdict) that downstream automation can trust.soc-integrator history for audit, tuning, and UAT evidence.sequenceDiagram
autonumber
participant Sim as Log Simulator
participant Wz as Wazuh
participant Sh as Shuffle
participant SI as soc-integrator
participant VT as VirusTotal/AbuseIPDB
participant IR as IRIS
Sim->>Wz: Send FortiGate/Endpoint simulated logs
Wz->>Wz: Parse + correlate + trigger alert rule
Wz->>Sh: Trigger workflow (webhook/API)
Sh->>SI: POST /ioc/enrich (ioc_type, ioc_value)
SI->>VT: Query IOC intelligence
VT-->>SI: Enrichment data
SI-->>Sh: Enrichment result
Sh->>SI: POST /ioc/evaluate (ioc + enrichment context)
SI->>SI: Apply decision logic + write ioc_trace
SI-->>Sh: matched/severity/reason
alt matched == true
Sh->>SI: POST /iris/tickets
SI->>IR: Create ticket/case
IR-->>SI: ticket_id/case_id
SI-->>Sh: Ticket creation success
else matched == false
Sh-->>Sh: End workflow without ticket
end
| Group | Method | Endpoint | Notes |
|---|---|---|---|
| Core | GET | /health |
Service health and target configuration |
| Core | POST | /ingest/wazuh-alert |
Normalize inbound Wazuh alert payload |
| Core | POST | /action/create-incident |
Create PagerDuty incident |
| Core | POST | /action/trigger-shuffle |
Trigger Shuffle workflow execution |
| Core | POST | /action/create-iris-case |
Create IRIS case (legacy action endpoint) |
| IRIS | POST | /iris/tickets |
Create IRIS ticket/case via soc-integrator |
| IRIS | GET | /iris/tickets |
List/query IRIS tickets/cases |
| IOC | POST | /ioc/enrich |
IOC enrichment from configured intel sources |
| IOC | POST | /ioc/evaluate |
IOC decisioning/verdict |
| IOC | POST | /ioc/upload-file |
Upload file to IOC backend (VirusTotal flow) |
| IOC | GET | /ioc/analysis/{analysis_id} |
Retrieve IOC analysis status/result |
| IOC | POST | /ioc/evaluate-file |
Evaluate file indicator or uploaded sample |
| IOC | GET | /ioc/history |
Retrieve stored IOC trace history |
| Shuffle | GET | /shuffle/health |
Shuffle service reachability check |
| Shuffle | GET | /shuffle/auth-test |
Validate Shuffle API key access |
| Shuffle | POST | /shuffle/login |
Login against Shuffle API |
| Shuffle | POST | /shuffle/generate-apikey |
Generate Shuffle API key from credentials |
| Shuffle | GET | /shuffle/workflows |
List workflows |
| Shuffle | GET | /shuffle/workflows/{workflow_id} |
Get workflow detail |
| Shuffle | POST | /shuffle/workflows/{workflow_id}/execute |
Execute specific workflow |
| Shuffle | GET | /shuffle/apps |
List installed/available Shuffle apps |
| Shuffle | POST | /shuffle/proxy |
Generic proxy request to Shuffle API |
| Wazuh | GET | /sync/wazuh-version |
Fetch Wazuh version information |
| Wazuh | GET | /wazuh/auth-test |
Validate Wazuh API authentication |
| Wazuh | GET | /wazuh/manager-info |
Manager information |
| Wazuh | GET | /wazuh/agents |
List Wazuh agents |
| Wazuh | GET | /wazuh/alerts |
Query recent Wazuh alerts |
| Wazuh | GET | /wazuh/manager-logs |
Read manager logs |
| Wazuh | POST | /wazuh/sync-to-mvp |
Sync Wazuh alerts into MVP pipeline |
| Wazuh | GET | /wazuh/auto-sync/status |
Auto-sync loop status |
| MVP | POST | /mvp/incidents/ingest |
Ingest incident into MVP flow |
| MVP | POST | /mvp/ioc/evaluate |
Evaluate IOC under MVP policy |
| MVP | POST | /mvp/vpn/evaluate |
Evaluate VPN event under MVP policy |
| MVP | GET | /mvp/config/policies |
Read MVP policy configuration |
| MVP | PUT | /mvp/config/policies |
Update MVP policy configuration |
| MVP | GET | /mvp/health/dependencies |
Dependency health snapshot |
Additional FastAPI-generated endpoints:
GET /docsGET /openapi.jsonDate: March 4, 2026 Project: FoodProject SOC Platform (Wazuh + Shuffle + IRIS-web + SOC Integrator)
This update documents production log sources and required fields for Appendix C detections implemented in soc-integrator.
C1-01 Impossible Travelevent_id=4624)asset.usernetwork.src_iptimestamppayload.success=true or equivalent)network.country and network.src_lat/src_lon) or GeoIP enrichment from source IPc1_max_travel_speed_kmph)C2-01 Privileged off-hours loginC2-02 Dormant account activationC2-03 Service account interactive logonC2-04 Rapid privilege escalation followed by sensitive access4624, 4672, 4728, 4732, 5145)asset.user, asset.is_admin, asset.is_servicepayload.logon_type, payload.event_id, payload.action, payload.successnetwork.src_ip, network.dst_host, network.dst_porttimestampC3-01 Multi-host authentication success burstC3-02 SMB/RDP lateral movement burst patternC3-03 Admin account accessing many servers rapidlyC3-04 Internal scanning/enumeration burstasset.user, asset.is_adminnetwork.src_ip, network.dst_host, network.dst_porttimestamp4624 Successful logon4672 Special privileges assigned to new logon4728, 4732 Privileged group membership changes5145 Detailed file share accessscripts/send-wazuh-proposal-appendix-c-events.sh| Source | Log Path / Channel | Must-Have Fields | Use Cases | Verification Query (Wazuh/Indexer) |
|---|---|---|---|---|
| VPN Gateway (FortiGate/SSL-VPN) | Syslog export from firewall/VPN device | timestamp, user, src_ip, action/result, event_id (if mapped), country (optional) |
C1, C2 | full_log:*vpn* AND full_log:*user=* |
| Active Directory / Windows DC | Windows Security Event Log (agent/forwarder) | event_id, timestamp, user/account, src_ip (where present), logon_type, success/failure |
C1, C2, C3 | rule.id:* AND (data.win.system.eventID:4624 OR full_log:*event_id=4624*) |
| Cloud IdP (Entra/Okta/Google) | API export / SIEM connector -> syslog/json | user, src_ip, event_time, outcome, geo.country (if available), app/service |
C1, C2 | full_log:*source=*idp* OR full_log:*okta* OR full_log:*entra* |
| Windows Endpoints/Servers | Wazuh agent + Sysmon/Security logs | event_id, user, src_ip, dst_host, dst_port, process/action |
C2, C3 | full_log:*source=windows* AND rule.id:* |
| Linux Servers | auth.log / secure / sudo / sshd | timestamp, user, src_ip, action, success |
C2, C3 | full_log:*sshd* OR full_log:*sudo* |
| East-West Firewall | Internal traffic logs (allow/deny/flow) | src_ip, dst_ip/dst_host, dst_port, action, timestamp |
C3 | full_log:*src_ip=* AND full_log:*dst_port=* |
| IDS/NDR | IDS alerts / network detection logs | src_ip, dst_ip/dst_host, dst_port, signature/category, timestamp |
C3 | full_log:*scan* OR full_log:*lateral* OR full_log:*enumeration* |
soc-integratorwazuh-alerts-* within expected ingestion latencyDate: March 17, 2026 Project: FoodProject SOC Platform (Wazuh + Shuffle + IRIS-web + SOC Integrator)
d5a720d1b99b) and stamped the DB directlyioc.case_id column (ALTER TABLE ioc ADD COLUMN IF NOT EXISTS case_id ...) skipped by the migrationui/dist) had never been builtnpm install && npm run build inside the iris-web/ui container to produce dist//kpi):
iris-web/source/app/blueprints/pages/kpi_dashboard/iris-web/ui/src/pages/kpi_dashboard.js, iris-web/ui/src/css/kpi_dashboard.cssscripts/seed-kpi-test-data.pymanage_cases.html and case.html templates for KPI-related display fieldsPassword (capital P) as bcrypt ($2a$ prefix for Go compat)SHUFFLE_DEFAULT_PASSWORD was blank; password was auto-generated and not savedSHUFFLE_DEFAULT_USERNAME, SHUFFLE_DEFAULT_PASSWORD, and SHUFFLE_DEFAULT_APIKEY in Shuffle/.envSHUFFLE_DEFAULT_APIKEYpass.txt at project root documenting all system credentials (IRIS, Shuffle, Wazuh, SOC Integrator, third-party API keys)/shuffle/apps and /shuffle/workflows returning 401:
docker restart does NOT re-read env_filesoc-integrator/.env, and used --force-recreate to pick up the new keysoc-integratorwazuh-alerts-* patternreferences[] and searchSourceJSON.indexRefName entries to point to wazuh-alerts-*full_log:*usecase_id* filters across all dashboards with production-data filters:
rule.groups: soc_prod*rule.id is a keyword field in OpenSearch — range queries are lexicographic, not numeric; ID-based range filtering is unreliablerule.groups: soc_prod* is the correct discriminator — all SOC custom rules carry this group; no built-in Wazuh rules dorule.id: 110xxx values and rule.groups: appendix_a/b splitsfull_log:*usecase_id* → rule.groups: soc_prod*; A/B panel splits use rule.groups: appendix_a and rule.groups: appendix_brule.id: __no_rule__ (intentional no-match)wazuh-alerts-* datascripts/test-firewall-syslog.py:
--via-docker flag to preserve source IP through Docker NATwazuh_manager.conf allowed listlogall and logall_json in Wazuh manager config for improved debug visibilitysamples/:
samples/appendix-a-production-samples.logsamples/appendix-b-production-samples.logsamples/appendix-c-production-samples.logsamples/README.md documenting log format and usagewazuh-alerts-* and generated summary_rule_match.mdActive rules with events (2026-03-17):
| Rule | Description | Events |
|---|---|---|
| 110341 | A4-01 Windows privileged account auth failure | 1 |
| 110342 | A4-02 Windows service account auth failure | 46 |
| 110354 | A4-13 Windows DC DSRM password set (4794) | 285,769 ⚠️ |
| 110359 | A4-19 Windows authentication failure (4625) | 55 |
run-combined-stack.sh: added dedup command (fixed missing elif branch) and recreate commandREADME.md: full rewrite covering all stack commands, KPI dashboard, current endpoint list, and macOS bind-mount notescripts/README.md: documented test-firewall-syslog.py, seed-kpi-test-data.py, and new dashboard ndjson filesdocs/wazuh-decoders-rules.md: documentation for custom decoder/rule structureDate: March 4, 2026 Project: FoodProject SOC Platform (Wazuh + Shuffle + IRIS-web + SOC Integrator)
0de071e -> Head: 5e215c0)0de071e7c9327c8c9135f0c15cf80c31c9b2e59a5e215c0soc-integrator/app/ui/index.htmlsoc-integrator/app/ui/assets/app.jssoc-integrator/app/ui/assets/styles.csssoc-integrator/app/services/c_detection_service.pysoc-integrator/app/main.pysoc-integrator/app/models.pysoc-integrator/app/repositories/mvp_repo.pysoc-integrator/app/adapters/geoip.pyscripts/send-wazuh-proposal-appendix-b-events.shscripts/send-wazuh-proposal-appendix-c-events.shscripts/events/*.ndjsonscripts/import-wazuh-dashboard.shwazuh-docker/single-node/config/wazuh_cluster/local_decoder.xmlwazuh-docker/single-node/config/wazuh_cluster/local_rules.xmlwazuh-docker/single-node/config/wazuh_cluster/rules/soc-*.xmlActive custom rules are currently defined in:
wazuh-docker/single-node/config/wazuh_cluster/local_rules.xmlRule groups/ranges implemented:
100200: base marker for synthetic SOC events (soc_mvp_test=true)100210: Appendix A classifier100220: Appendix B classifier100230: Appendix C classifierA1 IOC/DNS: 100301-100302A2 FortiGate firewall/IPS/IDS: 100311-100320A3 VPN anomalies: 100331-100335A4 Windows/AD behaviors: 100341-100364B1 VMware/vCenter/ESXi: 100401-100403B2 Log-loss monitor signal: 100411B3 Sysmon-focused detections: 100421-100426C1 Impossible travel: 100501C2 Credential abuse/privilege misuse: 100511-100514C3 Lateral movement/internal recon: 100521-100524Operational note:
wazuh_cluster/rules/soc-*.xml exist as staging artifacts in this workspace; active detection content is loaded from local_rules.xml.run-combined-stack.shcompose-overrides/soc-integrator.ymlsoc-integrator/Dockerfilesoc-integrator/.env.exampleSecurity Detection & Threat Intelligence Enhancement Proposal-revise.mdprogress-update.md) including: