No description
Find a file
2026-09-01 17:38:11 -03:00
demo style: improve code formatting 2026-09-01 15:48:11 -03:00
src/quo refactor(domain): separate drift from risk 2026-09-01 17:38:11 -03:00
.dockerignore feat: initial architecture blueprint and e2e telemetry lifecycle runtime 2026-05-26 20:06:07 -03:00
.env.example feat(config): add QUO_STATE_PATH live-state root 2026-09-01 11:33:19 -03:00
.gitignore style: improve code formatting 2026-09-01 15:48:11 -03:00
CHANGELOG.md docs: add CHANGELOG for v0.1.0 2026-09-01 15:32:52 -03:00
demo.py feat: initial architecture blueprint and e2e telemetry lifecycle runtime 2026-05-26 20:06:07 -03:00
pyproject.toml feat: initial architecture blueprint and e2e telemetry lifecycle runtime 2026-05-26 20:06:07 -03:00
README.md refactor(domain): separate drift from risk 2026-09-01 17:38:11 -03:00
requirements.txt chore: pin runtime dependencies in requirements.txt 2026-09-01 11:33:10 -03:00

QUO — Autonomous Infrastructure Governance & Drift Remediation

QUO is a local-first, AI-augmented autonomous agent that detects, analyzes, and remediates configuration drift in critical infrastructure files. It bridges deterministic enforcement (SHA-256 integrity verification, policy gates) with AI-driven reasoning via Ollama (Qwen 2.5 3B) and orchestrates the full lifecycle through a LangGraph state machine.

Drift events flow through a configurable workflow: static severity-based policy evaluation, notification preparation, and optionally human-in-the-loop approval via Telegram before enforcement. The system is designed with fail-closed integrity, append-only forensic logging, and a hexagonal (ports-and-adapters) architecture that makes notification backends swappable.


Architecture

src/quo/
├── cli.py              Bootstrap — config → observability → runtime → signal wait
├── config/             Resolves CLI args, env vars, and defaults into QUOConfig
├── domain/             Event types (QUODriftEvent, QUOHITLDecision) and payloads
├── services/           Policy engine, SHA-256 integrity verification, watcher
│   ├── watcher/        Polls live files vs vault baselines; emits QUODriftEvents on drift
│   ├── integrity/      Streaming SHA-256 hashing with fail-closed verification
│   └── policy_engine/  Stub — planned YAML-based governance rule evaluation
├── graph/              LangGraph state machine (orchestration, routing, nodes)
│   ├── state.py        QUOAgentState TypedDict — shared workflow state
│   ├── factory.py      StateGraph construction with AsyncSqliteSaver checkpointing
│   ├── runtime.py      QUOGraph wrapper — invoke, HITL registry, shutdown
│   ├── routing.py      Conditional edge routing between graph nodes
│   └── nodes/
│       ├── policy_gate.py   Severity-based policy evaluation (high/critical → audit)
│       ├── notifier.py      Notification preparation + HITL requirement flagging
│       ├── auditor.py       Stub — planned LLM-based risk analysis via Ollama
│       ├── hitl_wait.py     Stub — planned interrupt/resume point
│       └── enforcer.py      Stub — planned MCP-based remediation execution
├── runtime/            Service assembly, lifecycle management, drift consumer loop
├── integrations/       Telegram adapter (alerts + inline approve/reject buttons)
├── observability/      Append-only JSONL forensic logger with stdout mirroring
└── application/        Protocol interfaces (QUONotificationPort)

Workflow

File Change → Watcher → asyncio.Queue → DriftConsumer → LangGraph StateGraph → Notification / Enforcement
  1. Detection — QUOWatcherService polls every protected file against its vault baseline (SHA-256) and pushes a QUODriftEvent onto an asyncio.Queue for each new deviation. A clean boot emits nothing, a file moving further away from baseline emits again, and a return to baseline silently re-arms.
  2. Consumption — drift_consumer pulls events from the queue, builds graph state, and invokes the compiled LangGraph with a unique thread_id for checkpoint isolation.
  3. Policy Gate — policy_gate_node applies severity-based rules: high/critical → audit path, everything else → notify path.
  4. Auditor (stub) — Planned: delegates to Ollama (Qwen 2.5 3B) for LLM-based risk scoring and remediation recommendations.
  5. Notifier — notifier_node prepares the alert payload and flags high/critical events as requiring HITL.
  6. HITL Wait (stub) — Planned: pauses execution via LangGraph interrupt_before, awaiting operator approve/reject through Telegram inline buttons.
  7. Enforcer (stub) — Planned: executes remediation through a sandboxed MCP subprocess, keeping the main runtime unprivileged.

Getting Started

Prerequisites

  • Python 3.12+
  • Ollama (optional, for LLM-based risk analysis) — qwen2.5:3b recommended
  • Docker + Docker Compose (optional, for the demo sandbox only)

Installation

git clone <repo-url> && cd quo
python -m venv .venv && source .venv/bin/activate
pip install -e .
pip install -r requirements.txt

The pyproject.toml declares no runtime dependencies; use the pinned requirements.txt until that is resolved.

Configuration

Configuration is resolved with priority CLI args > environment variables > defaults.

cp .env.example .env

Key environment variables:

Variable Default Description
QUO_MODE PRODUCTION PRODUCTION or DRY_RUN (log only, no modifications)
OLLAMA_HOST http://localhost:11434 Ollama endpoint for LLM inference
OLLAMA_MODEL qwen2.5:3b Model used as the reasoning layer
TELEGRAM_BOT_TOKEN — Bot token from @BotFather (optional — without it, QUO runs without HITL)
TELEGRAM_CHAT_ID — Chat ID from @userinfobot
QUO_WATCH_FILES — Comma-separated file paths to monitor
QUO_WATCH_PATH watch/live Base directory where watched files are surfaced (shared volume)
QUO_STATE_PATH watch/state Bind-mounted live state (.bashrc, hosts) not covered by the live volume
QUO_VAULT_PATH vault Golden baseline directory containing MANIFEST.sha256
QUO_DB_PATH data/quo_state.sqlite LangGraph checkpoint database
QUO_LOG_PATH logs/audit_trail.jsonl Append-only forensic audit log
QUO_MCP_SERVER_SCRIPT mcp/server.py MCP enforcement server path

Run

python -m quo                     # production mode
python -m quo --dry-run           # simulate only, no file modifications

Without a Telegram token, QUO runs without HITL and auto-remediates based on policy thresholds.


Demo Sandbox

python -m demo        # or: python demo.py

Launches a Docker Compose stack with two containers:

  • quo-target — "victim" node built from Alpine 3.19 (demo/Dockerfile.target) with writable configuration files. Because Docker bind-manages /etc/hosts and /root/.bashrc lies outside the shared volume, both are surfaced to the watcher via bind-mounted demo/state/ files (state/hosts, state/.bashrc).
  • quo-agent — QUO daemon: demo/bootstrap.py seeds golden baselines into /watch/live (shared volume aliasing the target's /etc), /watch/state (bind-mounted state files), and /watch/vault, then the watcher polls those surfaces against the vault MANIFEST.sha256.

An interactive menu lets you inject five simulated attacks and watch QUO respond in real time:

Attack Target Risk
Enable SSH root login /etc/ssh/sshd_config HIGH
Enable SSH password auth /etc/ssh/sshd_config HIGH
Add passwordless sudoer backdoor /etc/sudoers CRITICAL
Inject exfiltration hook /root/.bashrc MEDIUM
Poison /etc/hosts (DNS hijack) /etc/hosts MEDIUM

Severities shown are those reported by the watcher for each demo attack. Every injected attack produces exactly one alert (a second change to an already-dirty file re-alerts); the Restore all menu action copies golden baselines back without spurious events.

Attacks are defined declaratively in demo/attacks.yaml, making it trivial to add new test vectors without touching Python code.

Monitoring:

docker logs -f quo-agent
docker exec quo-agent tail -f /app/logs/audit_trail.jsonl

Press q in the menu to tear down all containers and volumes.


Entry Points

Command Description
python -m quo Start the QUO agent daemon (blocks on SIGINT/SIGTERM)
python -m demo Interactive Docker sandbox with simulated attacks (or python demo.py)
quo Same as python -m quo (installed via pip install -e .)

Key Design Properties

  • LangGraph orchestration — Drift events flow through a StateGraph with conditional edges, thread-isolated checkpointing via AsyncSqliteSaver, and interrupt/resume capability for HITL workflows.
  • Fail-closed integrity — QUOIntegrityEngine uses streaming SHA-256 with constant-time comparison (hmac.compare_digest), timing-attack resistant. Returns False for any error: missing files, unreadable files, missing hashes, or mismatches.
  • Hexagonal (ports-and-adapters) architecture — QUONotificationPort protocol class defines a clean adapter boundary. Telegram is the current implementation; Slack, email, or other channels can be swapped in without touching core logic.
  • Queue-based decoupling — Watcher and consumer communicate via asyncio.Queue, preventing backpressure propagation.
  • Append-only forensics — QUOForensicLogger writes UTC-timestamped JSONL entries with automatic module attribution (via inspect.stack()). Stdout mirroring for live observability.
  • Dry-run mode — QUO_MODE=DRY_RUN or --dry-run logs all intended actions without executing them, enabling safe testing on production systems.
  • Signal-driven lifecycle — SIGINT/SIGTERM triggers graceful stop_runtime() with ordered shutdown: cancel tasks, stop services, flush checkpoints.
  • Thread-isolated checkpointing — Each drift event receives a unique thread_id, ensuring complete workflow isolation and replay capability.

Development Status

QUO is in early-stage MVP development.

Implemented:

  • Config resolution pipeline (CLI args > env vars > defaults)
  • Append-only forensic JSONL logging
  • LangGraph assembly with SQLite checkpointing (AsyncSqliteSaver)
  • Telegram integration with inline Approve/Reject buttons for HITL
  • Drift event domain models (QUODriftEvent, QUODriftPayload, QUORiskAssessment, QUOHITLDecision) with risk separated from raw drift facts
  • SHA-256 integrity engine with manifest loading (MANIFEST.sha256)
  • Runtime lifecycle (start/stop/signal handling)
  • Static severity-based policy gate node (high/critical → audit)
  • Notification preparation node with HITL requirement flagging
  • Polling filesystem watcher: SHA-256 comparison against vault baselines, one alert per new deviation, silent re-arm on restore (no false positives on clean boot)
  • Unified drift diff generation (golden vs live, truncated for large diffs)
  • Interactive Docker demo sandbox with 5 attack scenarios (data-driven via YAML) — all five verified to alert
  • Live coverage of state files outside the shared volume (/etc/hosts, /root/.bashrc) via a bind-mounted state root (QUO_STATE_PATH) and a custom target image (demo/Dockerfile.target)
  • requirements.txt with pinned dependencies (multi-stage image build installs to prefix)
  • QUOGraph wrapper with HITL registry and checkpoint lifecycle management
  • Total=False TypedDict graph state for progressive enrichment across nodes

Planned / In Progress:

  • LLM-based auditor node (Ollama Qwen 2.5 3B for risk scoring)
  • HITL interrupt/resume via LangGraph interrupt_before
  • MCP enforcement server for sandboxed remediation execution
  • YAML-based policy engine (governance rule evaluation)

License

DATORUM — Autonomous Infrastructure Governance