Skip to main content

axor-sentinel

Cross-session behavioral analysis layer for axor-core. Detects slow-and-low staging attacks — coordinated data exfiltration spread across many sessions over days or weeks — that are invisible to per-session anomaly detection.

The problem it solves

Per-session anomaly detectors see each session in isolation. An attacker staging an exfiltration across dozens of short, individually normal sessions — touching sensitive resources a little each time, then exfiltrating later — never exceeds any single-session threshold.

axor-sentinel maintains a resource reputation graph across all sessions. Resources accumulate suspicion over time, and that suspicion is fed back to axor-core as observe-only telemetry: it never denies a request on its own. The only enforcement coupling is opt-in — when a resource's suspicion is high enough, core's DegradationEngine (configured with a detection_floor) can tighten the session's degradation level, narrowing the surface. Reputation is a signal that raises caution, not a gate.

How it works

sessions (axor-core)
        │
        ▼
  SentinelCycle          ← background audit, runs every ~1h
  ├── evidence sets       ← windowed typed facts per resource (30-day TTL, exact expiry)
  ├── predicates P1–P4    ← declared, decidable: export-denied / distinct-origin
  │                         export-adjacency / staging count / staged-then-export
  ├── fanout quota        ← > N distinct containers in one tainted session
  │                         (N declared per actor class — no self-trained baseline)
  ├── adjacency labels    ← sharing a container with a FLAGGED resource ⇒ WATCH
  └── snapshot swap       ← atomic write to disk (symlink rename / os.replace)
        │
        ▼
  ReputationSnapshot      ← resource_id → LEVEL_SUSPICION[level], a FINITE
                            codomain (0.0 clean / 0.4 watch / 1.0 flagged) +
                            level names and the facts behind each verdict;
                            the old scalar scores ride along as telemetry
        │
        ▼
  SnapshotIntentEnricher  ← converts suspicion → trust, populates
        │                    NormalizedIntent.target_resource_reputation (telemetry)
        ▼
  IntentLoop (axor-core)  ← observe-only: records the reputation signal; with an
                            opt-in detection_floor it can only TIGHTEN degradation,
                            never deny. (floor in (0.001, 0.6) ⇒ FLAGGED-only;
                            floor ≥ 0.6 ⇒ WATCH too — decidable end-to-end)

Polarity note. Sentinel scores suspicion (high = bad). Core's reputation field is trust (a positive reading <= detection_floor crosses and tightens; 0.0 = unknown). SnapshotIntentEnricher converts at the boundary (reputation = 1 - suspicion), so core tightens on suspicious resources.

Score accumulation uses logarithmic diminishing returns — each signal contributes proportionally to remaining headroom, so scores are bounded to [0, 1] and saturate naturally:

new_score = current + new_weight × (1 − current)

Quick start

pip install -e ".[neo4j]"
from pathlib import Path
from axor_sentinel.sentinel.cycle import SentinelCycle
from axor_sentinel.integration.intent_enricher import SnapshotIntentEnricher
from axor_sentinel.sentinel.weight import FLAG_THRESHOLD
from axor_core.degradation.engine import DegradationEngine

snapshot_dir = Path("~/.axor/sentinel").expanduser()

# Background audit cycle (runs hourly, not on hot path)
cycle = SentinelCycle(neo4j_session, snapshot_dir=snapshot_dir)
snapshot = cycle.run_once(sessions)

# Hot-path enrichment — pure dict lookup, no Neo4j
enricher = SnapshotIntentEnricher.from_dir(snapshot_dir)

# Wire into axor-core IntentLoop. Enrichment alone only populates telemetry; to act
# on it, give the loop a DegradationEngine with a detection_floor so a suspicious
# resource TIGHTENS degradation (never denies). The floor pairs with the suspicion
# flag threshold: floor = 1 - FLAG_THRESHOLD.
degradation = DegradationEngine(detection_floor=1.0 - FLAG_THRESHOLD)
loop = IntentLoop(..., reputation_enricher=enricher, degradation_engine=degradation)

Bench suite

820-scenario synthetic dataset (paper baseline):

pip install -e ".[bench]"
from axor_sentinel.bench.dataset.composer import DatasetComposer
from axor_sentinel.bench.eval.metrics import evaluate

scenarios = DatasetComposer().compose()        # 820 scenarios, seed=42
result = evaluate(scenarios, scores=my_scores)
print(result.tpr_at_fpr_budget)               # TPR @ FPR ≤ 0.02

See docs/architecture.md for the full design: graph schema, weight model, invariants, attack patterns, and bench composition.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

axor_sentinel-0.4.1.tar.gz (141.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

axor_sentinel-0.4.1-py3-none-any.whl (75.4 kB view details)

Uploaded Python 3

File details

Details for the file axor_sentinel-0.4.1.tar.gz.

File metadata

  • Download URL: axor_sentinel-0.4.1.tar.gz
  • Upload date:
  • Size: 141.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for axor_sentinel-0.4.1.tar.gz
Algorithm Hash digest
SHA256 a04c8d0be704a5b65e01d4b604ee3a588bc900a00aa71f8cdff9718bcd0be1c5
MD5 6a2a8d91031f5154dcfac08c3844e7f0
BLAKE2b-256 81c8dffdc56b9ebd621edabd3ce7a1fc308fb34eea910f985d2cf45b2ee21a0c

See more details on using hashes here.

Provenance

The following attestation bundles were made for axor_sentinel-0.4.1.tar.gz:

Publisher: ci.yml on Bucha11/axor-sentinel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file axor_sentinel-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: axor_sentinel-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 75.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for axor_sentinel-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7d8495bb969f45e5d7d86e76814bd2d5dabb8a849e65cd89fb8aa3cf8b9d9cd3
MD5 0a3bef50662ce53b77aa270e95da537b
BLAKE2b-256 813467933a2fefdf76e5346f60c5ab6c3f96aefd0c5c9c571a2f9eb04b1dd98f

See more details on using hashes here.

Provenance

The following attestation bundles were made for axor_sentinel-0.4.1-py3-none-any.whl:

Publisher: ci.yml on Bucha11/axor-sentinel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 files

0.3.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page