Skip to content

Repository files navigation

EPAGOGE — Agentic Network Security (ANS)

© 2026 EPAGOGE LLC. All rights reserved.

EPAGOGE ANS is a deterministic agent-governance substrate. Its founding invariant is AI off the reliability path: deterministic, testable controls decide; models only advise, and every advisory is sealed and logged, never gating. It governs both ends of an autonomous agent's activity on one hybrid post-quantum (Ed25519 + ML-DSA-65) sealed chain — an inbound network perimeter that screens what reaches an agent, and an outbound gateway (intent-lineage gate + egress wall + capability-earning) that governs what an agent does. npm start opens a live trust console over it.

It also carries the original causal network-behavioral layer this repository began as: security derived from physical causality rather than mathematical hardness — detecting credential-theft, lateral-movement, and exfiltration by behavioral-signature mismatch rather than signature matching. Both layers put deterministic controls on the reliability path and seal every decision.

This is a working prototype (originally built for an SBIR Phase I submission). Honest metrics and limits are stated throughout, and in full in SECURITY_ARCHITECTURE.md.

📐 SECURITY_ARCHITECTURE.md — the hard background. Every security control in this codebase, what it defends against, how it actually works, and where it is honestly limited: the intent-lineage gate, the hybrid post-quantum sealed chain, the outbound egress wall (IFC), the inbound perimeter + semantic + trajectory-drift layers, IntentCapability tokens, cross-surface corroboration, the Overwatch deny-floor, and the canary oracle. Read that for the machinery; this README is the face.

Quick start

A fresh clone runs with one command — Node bootstraps the Python runtime for you (creates a virtualenv, installs deps, launches the console, opens your browser). No manual pip/venv steps.

git clone https://github.com/EPAGOGE/agentic-network-security.git
cd agentic-network-security
npm start

Then open http://localhost:8079 (the launcher opens it for you). That's it — you're in.

Requirements: Python 3.11+ and Node 18+ on your PATH. First run takes a minute or two to install dependencies; later runs launch instantly. Everything else is optional and degrades gracefully — no API keys, no Ollama, and no post-quantum library are needed to start (the console tells you honestly what's active).

Command What it does
npm start Launch the console in simulation mode (the default demo — baseline + attack cycles)
npm run live Launch in live mode (empty start; real events arrive via POST /api/ingest)
npm test Run the test suite (installs test deps on first use)
npm run demo Run the end-to-end governed session in the terminal (no browser)
npm run setup Install dependencies only, without launching

Optional feature extras (power users): pip install -e '.[full]' inside .venv adds the world tab, Overwatch-AI (Claude), the local Hermes lane, post-quantum signing, and S3 ingestion. The core console needs none of them.

What's in the repository

cwca/                       # Python package — the architecture (import name kept as `cwca`)
│
│   # ── Agent-governance substrate (the console) ──
├── gateway/                # Outbound gateway — intent-lineage gate, egress wall (IFC),
│                           #   capability-earning, overwatch deny-floor, canary oracle
├── intent/                 # Intent lineage — anchored vs orphan, earned trust envelope, decay
├── network/                # Inbound perimeter + semantic screen + trajectory-drift monitor
├── connections/            # Cross-surface corroboration (account-takeover freeze)
├── provenance/             # Genealogy + keystore (sealed provenance)
├── attestation.py          # Hybrid Ed25519 + ML-DSA-65 tamper-evident sealed chain
│
│   # ── Causal network-behavioral layer ──
├── model/                  # Event, AbsenceRecord, BehavioralProfile, Histogram
├── storage/                # StorageBackend + SQLite implementation
├── gossip/                 # Gossip protocol, signing, transport, ObservationStore
├── dashboard/              # FastAPI + HTML live trust console
├── rules.py                # Causal predecessor dependency rules
├── absence.py              # Absence set generation
├── scoring.py              # Four-dimension confidence scoring
├── anomaly.py              # Anomaly detection
├── node.py                 # Per-node event processing pipeline
├── election.py             # Supernode election (diversity + pulse + stranger)
├── rotation.py             # Truncated-exponential tenure timing
├── handoff.py              # Encrypted fragmented supernode handoff (X25519/ChaCha20)
├── cluster_state.py        # Per-cluster seat lifecycle + election orchestration
├── summary.py              # SupernodeSummary production
├── tower.py                # Tower-layer compromise detection, adversarial cross-check
├── baseline.py             # UserProfileLibrary + baseline traffic generator
├── attack.py               # Network + AttackSimulator + three-act demo
├── validation.py           # End-to-end validator producing the Section 9 report
└── __main__.py             # CLI: `python -m cwca validate`

tests/                      # 1,289 tests across every module (more with the optional world extra)
deploy/                     # Dockerfile, docker-compose, Terraform for AWS Fargate
scripts/launch.mjs          # Zero-dependency Node bootstrap/launcher behind `npm start`
SECURITY_ARCHITECTURE.md    # The full control-by-control security machinery + honest limits
VALIDATION_REPORT.txt       # Latest honest-metrics output

Manual / advanced (without npm)

npm start above is the recommended path. To drive the Python package directly:

python -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'

python -m pytest                                   # run the tests
python -m cwca validate --baseline-hours 72        # full end-to-end validation (writes a report)
python -m cwca dashboard --mode simulation --port 8079   # the live console

The dashboard binds to 127.0.0.1 (loopback) by default. The mutating API has no auth, so only pass --host 0.0.0.0 behind a trusted proxy you control — never expose it directly.

Latest validation results

See VALIDATION_REPORT.txt for the full output.

Summary (72-hour simulated baseline, ~13,700 steady-state interactions):

Act Target Outcome Mechanism
1 <10s, <0.4 conf 7s, 0.398 ✓ confidence threshold (bootstrap zone)
2 <30s, <0.4 conf 2s ✓ (anomaly fired) relationship_novelty — user's session reaches a never-accessed target
3 <60s, <0.4 conf 2s ✓ (anomaly fired) directional_anomaly — per-target payload in the extreme tail for a known counterparty

False-positive rate: 0 anomalies across 13,794 baseline interactions — meets the Section 9 target (<1 per 10,000).

Overall: All three acts meet their criteria. Each detects via its intended primitive, not via residual state from a prior act. The directional_anomaly and relationship_novelty detectors became the Act 2 and Act 3 mechanisms after the cross-phase audit surfaced that the earlier "0s detection" readings were bootstrap-zone carryover through a sleep-only cooldown. See the honest-metrics notes below for what each mechanism does and doesn't cover.

Honest-metrics notes (spec Section 0)

Observations worth flagging for grant reviewers:

  1. Act 1's detection signal is the attacker's bootstrap-zone low confidence, not credential-identity linkage. The spec's Act 1 narrative implies the legitimate user's profile alerts when their credential is used from an unusual source. The prototype doesn't carry credentials on events — that's a Phase II architectural addition. The current signal (bootstrap-zone confidence on a fresh attacker source) hits the time budget and the <0.4 confidence threshold, but is architecturally narrower than what the full spec envisions.

  2. Act 2 detects via relationship_novelty, not credential-aware profile linkage. The attack is scripted with source=legitimate_user to represent the stolen-credential session. The user's mature profile (≥20 interactions across ≥3 distinct counterparties, both gates set in cwca/constants.py) is used to judge whether the access target has any prior history. A never-before-seen target raises the anomaly. Full credential-aware detection (profiles keyed by credential, actor-source novelty) remains Phase II; what exists today is the graph-novelty piece.

  3. Act 3 detects via directional_anomaly — per-target payload outlier. The per-target distribution histogram (see BehavioralProfile.outbound_payload_per_target) lets the detector ask "has this source ever sent this much to THIS counterparty?" independently of the global per-event-type payload_deviation check. Exfiltration through a known-good intermediary (default drain_target="svc-docs") fires directional_anomaly; exfiltration to an unknown destination would fire relationship_novelty instead — both paths are covered. True inbound-vs-outbound traffic-direction detection (flagging a reversal in which side initiates) requires Node to also process events from the target perspective; that's Phase II.

  4. Temporal detection requires a matured activity model (≥24 simulated hours of observation). During the learning period, the temporal dimension returns 1.0 for any hour — the architecture refuses to flag "novel hour" as anomalous until it has had a chance to observe the user's full cycle. This eliminates first-day FPs cleanly. For deployments shorter than 24h, temporal-based detection is unavailable by design (the system doesn't yet know what normal looks like for temporal patterns).

Deployment

deploy/ contains a production-ready Dockerfile and Terraform for single- service AWS Fargate deployment. See deploy/README.md for the build/push/apply runbook. Multi-service decomposition (separate node/supernode/tower Fargate services) requires a TCP Transport implementation and is a Phase II refactor — the Phase H Terraform is structured so expansion is additive.

Phase summary

Phase Scope Status
A Core data model + SQLite storage done
B Single-node behavior + scoring done
C Gossip protocol + ObservationStore done
D Supernode election, rotation, handoff done
E Tower layer + adversarial cross-check done
F Attack simulator + baseline done (all three acts detect via intended primitives)
G Dashboard (FastAPI + WebSocket) done
H AWS Fargate deployment artifacts artifacts authored; never applied — no live deploy run or verified on AWS
I Validation runner + honest report done

Architectural extensions left for Phase II

The following are architecturally accommodated (clean interfaces exist) but not implemented in the prototype:

  • Credential-identity linkage (Event carries credential_id; profile keyed by credential; actor-source novelty detection).
  • Real TCP Transport replacing InProcessTransport for true multi-service deployment.
  • Zone-based containment (routing compromised entities into quarantine zones based on tower alerts).
  • Interrogator investigators (Layer 3) — dormant probes activated by tower escalations.
  • RDS PostgreSQL + ElastiCache Redis for persistent state at production scale (prototype uses in-memory SQLite).
  • Recording learned ExpectedEventRule instances automatically from observed traffic regularity.

Architectural extensions landed after audit

These items were audit-flagged gaps and are now implemented:

  • TTL-based gossip dedup (cwca/gossip/engine.py:_TTLCacheSet). Replaces the earlier LRU-only cache with a 300-second TTL window per spec Section 4. Time function is injectable so tests can pin a fake clock. Size bound (dedup_cache_size, default 10,000) remains as a memory guard during bursts.
  • Absence corroboration escalation (cwca/gossip/store.py). record_observation and record_absence now share a single escalation path, so a missed heartbeat corroborated by 3+ / 6+ independent observers fires the local / cluster callbacks identically to any other anomaly. Synthetic anomaly tag (absence:<event_type>) keeps them from colliding with same-bucket observation corroboration.
  • Tower orchestrator with pairwise cross-check and quorum flag (cwca/tower.py:TowerOrchestrator). Drives the Layer 4 pipeline end-to-end in one cycle: summary production → bus publication → per-tower detection → pairwise adversarial_cross_check → cross-cluster spread detection → insufficient_quorum alert when a cluster under-reports.
  • Edge nodes and cross-cluster spread (cwca/tower.py:ClusterTopology, EdgeNodeMembership). Adjacency is derived from registered edge nodes; Tower.detect_cross_cluster_spread flags counterparties with cluster-level escalations in two or more adjacent clusters, surfacing attacks that bridge cluster boundaries via edge-node gossip.
  • Periodic tower execution via TowerScheduler (cwca/tower.py). TowerOrchestrator.run_cycle is now driven on an asyncio timer matching the GossipEngine.gossip_loop pattern. The dashboard backend spawns it during FastAPI's lifespan and tears it down on shutdown. on_cycle callbacks let consumers react to each produced OrchestratorCycle without reaching into scheduler state.
  • Full engine wired into the dashboard (cwca/dashboard/backend.py). SimulationSession now stands up a 5-seat ClusterState, three Tower instances on a TowerBus, a ClusterTopology, the TowerOrchestrator, and the TowerScheduler alongside the existing Layer-1 Node. Every processed event replicates into each non-muted supernode's ObservationStore, so tower cycles see real cluster divergence. New endpoints: /api/cluster, /api/tower, /api/mute/{sn}, /api/unmute/{sn}. WebSocket stream emits tower_cycle frames on every orchestrator pass.
  • Auto-cycling attack scenarios (AutoAttackScheduler). Drives the three-act sequence on a configurable pair of intervals (act_pause_s between acts, cycle_pause_s between cycles) and resets attacker profile state at cycle boundaries so each new cycle starts from a clean bootstrap. /api/auto_attack, /api/auto_attack/start, /api/auto_attack/stop. WebSocket stream emits auto_attack frames on act transitions. Dashboard AUTO button toggles live.
  • Hygiene pass: LOW_CONFIDENCE_HISTORY_GATE named in cwca/constants.py (removed the magic 0.5 in anomaly.py). Truncated-exponential KS test in tests/test_rotation.py validates 1000 draws match the spec's distribution (Section 9 line 882). Deterministic tied-score election test in tests/test_election.py pins node_id tie-break behavior. Handoff fragment-loss visibility in HandoffReassembler.pending_handoffs() and purge_stale(ttl_s), with WARNING logs on timed-out partial state and on fragment-0-missing reassembly — no more silent state accumulation.
  • role_reversal detector (cwca/anomaly.py, cwca/model/profile.py:inbound_* fields). The Node pipeline now updates both source and target profiles per event, so a target accumulates inbound history. When an entity that has historically been a receiver from peer X (≥ ROLE_REVERSAL_MIN_INBOUND, ≤ ROLE_REVERSAL_MAX_OUTBOUND) suddenly appears as source sending to X, role_reversal fires. Distinct from directional_anomaly — payload size is irrelevant; the signal is who initiates.

About

EPAGOGE Agentic Network Security (ANS) — a deterministic agent-governance substrate. Inbound perimeter + outbound gateway on one hybrid post-quantum sealed chain. One command to run: npm start.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages