The execution boundary for critical infrastructure.
One command to deploy. Every command validated before it reaches a controller. Fail-closed by default.
docker compose upThat's it. MIG Core backend API is running on port 8000. React frontend runs in a separate terminal on port 3000.
MIG Core is a deterministic command validation engine that sits at the IT-OT boundary. It validates every command — human, automated, or adversarial — against operational safety policy before reaching the controller.
Three possible outcomes:
- ALLOW — command is safe, proceed
- DENY — command is blocked, controller never sees it
- APPROVAL — command held for operator confirmation
No AI. No machine learning. No cloud dependency. Pure policy matching. Deterministic. Auditable. Fail-closed.
git clone https://github.com/Indrooneel/mig-core.git
cd mig-core
docker compose upBackend API is now running at http://localhost:8000
In a separate terminal:
cd mig-core/frontend
npm install
npm startFrontend is now running at http://localhost:3000
curl -X POST http://localhost:8000/validate \
-H "Content-Type: application/json" \
-d '{"text": "Set pump speed to 5000 RPM"}'Response:
{
"decision": "DENY",
"policy_id": "POL-OT-DENY-002",
"risk_score": 100,
"matched_policy": "Setpoint changes exceeding 5% are blocked",
"flags": ["PAYLOAD_HIGH_RISK", "SETPOINT_DEVIATION"]
}curl -X POST http://localhost:8000/validate \
-H "Content-Type: application/json" \
-d '{"text": "Read current pump speed from PLC"}'Response:
{
"decision": "ALLOW",
"policy_id": "POL-OT-ALLOW-001",
"risk_score": 10
}curl http://localhost:8000/auditcurl http://localhost:8000/health| Method | Endpoint | Description |
|---|---|---|
| POST | /validate |
Validate a command against policies |
| POST | /approve |
Approve a pending decision |
| POST | /reject |
Reject a pending decision |
| GET | /policies |
List all policies |
| POST | /policies |
Add a new policy |
| DELETE | /policies/{id} |
Remove a policy |
| GET | /zones |
List all zones |
| GET | /audit |
View decision history |
| GET | /audit/stats |
Decision statistics |
| GET | /audit/{id} |
View specific decision |
| GET | /health |
System status |
| GET | /stats |
Full statistics |
MIG Core ships with default OT policies. Customize by editing policies/default_ot_policies.json or adding new JSON files to the policies/ directory.
Example policy:
{
"id": "POL-OT-DENY-002",
"description": "Setpoint changes exceeding 5% are blocked",
"action_type": "write_setpoint_major",
"direction": "DENY",
"enforcement": "critical",
"notify": ["safety_officer"],
"keywords": ["set", "write", "change", "speed", "pressure"]
}Add policies through the API:
curl -X POST http://localhost:8000/policies \
-H "Content-Type: application/json" \
-d '{
"id": "CUSTOM-001",
"description": "Block all writes to zone 3",
"action_type": "write_zone3",
"direction": "DENY",
"enforcement": "critical",
"notify": ["supervisor"],
"keywords": ["zone 3", "zone three"]
}'MIG Core supports Purdue Model zone-based enforcement:
| Zone | Purdue Level | Description |
|---|---|---|
| Safety | Level 1 - SIS | All writes blocked |
| Control | Level 1-2 | Firmware and config export blocked |
| Supervisory | Level 2-3 | Standard access |
| DMZ | Level 3.5 | MIG operates here |
Command Source (any)
│
▼
┌──────────────────────┐
│ MIG Core │
│ │
│ PII Detection │
│ Action Inference │
│ Payload Inspection │
│ Policy Matching │
│ Stage Check │
│ Zone Check │
│ Override Evaluation │
│ Setpoint Analysis │
│ Decision + Audit │
│ │
│ ALLOW → forward │
│ DENY → block │
│ APPROVAL → hold │
└──────────────────────┘
│
▼
Controller / Target System
MIG Core validates commands. The OT Connector delivers them to controllers.
MIG Core is the brain — every command passes through the full validation pipeline.
OT Connector is the hands — translates Modbus register writes, routes them through MIG Core, and only forwards approved commands to the PLC.
Command → OT Connector → MIG Core /validate → Decision
│
┌───────┼───────┐
│ │ │
ALLOW DENY APPROVAL
│ │ │
▼ ✕ ⏸
PLC writes Blocked Held for
the value operator
Step 1 — Start MIG Core:
docker compose upStep 2 — Configure your OT environment:
# Edit with your PLC IP address, register map, and equipment limits
nano configs/ot_deployment_config.jsonThe config file maps your equipment to Modbus registers:
{
"plc_connection": {
"host": "YOUR_PLC_IP",
"port": 502
},
"equipment": [
{
"id": "pump-001",
"name": "Process Water Pump 1",
"registers": {
"speed": { "address": 10, "unit": "RPM" }
},
"limits": {
"speed": {
"min_safe": 10,
"max_safe": 100,
"baseline": 50
}
}
}
]
}Step 3 — Start the OT Connector:
cd backend
pip install pyModbusTCP requests
python mig_ot_connector.pyMIG Core runs on port 8000. OT Connector runs on port 8001.
# Safe write — 50 RPM on pump rated for 100
curl -X POST http://localhost:8001/write \
-H "Content-Type: application/json" \
-d '{"register": 10, "value": 50}'
# → MIG Core: ALLOW → PLC executes
# Dangerous write — 5000 RPM on pump rated for 100
curl -X POST http://localhost:8001/write \
-H "Content-Type: application/json" \
-d '{"register": 10, "value": 5000}'
# → MIG Core: DENY → PLC never sees this command
# Read plant status
curl http://localhost:8001/status
# View pending operator approvals
curl http://localhost:8001/pending
# Approve a held command
curl -X POST http://localhost:8001/approve \
-H "Content-Type: application/json" \
-d '{"decision_id": "dec_xxx", "approved_by": "operator1"}'- MIG Core unreachable → all writes DENY
- MIG Core timeout → all writes DENY
- MIG Core error → all writes DENY
- Unknown register → DENY
The OT Connector never forwards a command without MIG Core approval.
Connect to LabShock Oilsprings Air for testing:
# Get PLC IP from LabShock container
docker inspect lab-plc-1 --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
# Update config with PLC IP
nano configs/ot_deployment_config.json
# Start OT Connector
python backend/mig_ot_connector.py
# Every Modbus write now routes through MIG Core| Method | Endpoint | Description |
|---|---|---|
| POST | /write |
Validate and execute a Modbus write |
| POST | /read |
Read a register from the PLC |
| POST | /text |
Send a text command to MIG Core directly |
| POST | /approve |
Approve a pending command |
| POST | /reject |
Reject a pending command |
| POST | /mode |
Change operational mode |
| GET | /status |
Read all sensor and equipment values |
| GET | /pending |
List commands awaiting approval |
| GET | /equipment |
List configured equipment |
| GET | /sensors |
List configured sensors |
| GET | /health |
System status including MIG Core connection |
| GET | /audit |
Decision history |
House of Galatine — AI cybersecurity for critical infrastructure.
- Website: houseofgalatine.com
- Playground: houseofgalatine.com/playground
- Architecture Docs: github.com/Indrooneel/mig-architecture
Copyright (c) 2026 House of Galatine. All rights reserved.
MIG Core is available for evaluation and non-commercial use. For commercial licensing, contact: neel@houseofgalatine.com