Cross-session behavioral analysis for Axor via weighted resource reputation graph
Project description
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; when a highly reputated resource is accessed in a new session, axor-core can deny the request deterministically before any LLM inference.
How it works
sessions (axor-core)
│
▼
SentinelCycle ← background audit, runs every ~1h
├── time decay ← scores halve every 30 days
├── hot weights ← READ=0.4 / READ_SUMMARIZE=0.6 / EXPORT_ADJACENT=0.8 / EXPORT_FAILED=1.0
├── caution weights ← adjacent resources get BASE_CAUTION=0.3 × topology_factor
├── fanout detection ← z-score vs agent's historical baseline (fires at z > 2.5)
└── snapshot swap ← atomic write to disk (symlink rename / os.replace)
│
▼
ReputationSnapshot ← flat dict resource_id → score, loaded at startup
│
▼
SnapshotIntentEnricher ← populates NormalizedIntent.target_resource_reputation
│
▼
IntentLoop (axor-core) ← Phase 1: score ≥ 0.8 + after_external_read → deterministic deny
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
# Background audit cycle (runs hourly, not on hot path)
cycle = SentinelCycle(neo4j_session, snapshot_dir=Path("~/.axor/sentinel"))
snapshot = cycle.run_once(sessions)
# Hot-path enrichment — pure dict lookup, no Neo4j
enricher = SnapshotIntentEnricher.from_dir(Path("~/.axor/sentinel"))
# Wire into axor-core IntentLoop:
loop = IntentLoop(..., reputation_enricher=enricher)
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file axor_sentinel-0.1.0.tar.gz.
File metadata
- Download URL: axor_sentinel-0.1.0.tar.gz
- Upload date:
- Size: 63.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fba1e8f11a24173a277bf8e38788da64ac7d1ddfba52ff5068e57d76797b7ae3
|
|
| MD5 |
8eac3eed9065e3913790d63f0294c806
|
|
| BLAKE2b-256 |
5ccb5b47bc9ef7b1882325e32190ba1581a0a5db37ee9d68b70796ed38050e8b
|
Provenance
The following attestation bundles were made for axor_sentinel-0.1.0.tar.gz:
Publisher:
ci.yml on Bucha11/axor-sentinel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axor_sentinel-0.1.0.tar.gz -
Subject digest:
fba1e8f11a24173a277bf8e38788da64ac7d1ddfba52ff5068e57d76797b7ae3 - Sigstore transparency entry: 1706204000
- Sigstore integration time:
-
Permalink:
Bucha11/axor-sentinel@05d8dbf55508df7c28fdd6f7b5988d090cbe8917 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Bucha11
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@05d8dbf55508df7c28fdd6f7b5988d090cbe8917 -
Trigger Event:
push
-
Statement type:
File details
Details for the file axor_sentinel-0.1.0-py3-none-any.whl.
File metadata
- Download URL: axor_sentinel-0.1.0-py3-none-any.whl
- Upload date:
- Size: 50.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03e0d3b1b7a40f446afebb1078516559224bd18a1a7d2d8ae4fc59ff59ce3b26
|
|
| MD5 |
488143374fa73b5221ca26d7ec3e7101
|
|
| BLAKE2b-256 |
ac403b33a809d406f33599abe69a257d83c94fd692e9449685b3f2d3e21303ef
|
Provenance
The following attestation bundles were made for axor_sentinel-0.1.0-py3-none-any.whl:
Publisher:
ci.yml on Bucha11/axor-sentinel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axor_sentinel-0.1.0-py3-none-any.whl -
Subject digest:
03e0d3b1b7a40f446afebb1078516559224bd18a1a7d2d8ae4fc59ff59ce3b26 - Sigstore transparency entry: 1706204014
- Sigstore integration time:
-
Permalink:
Bucha11/axor-sentinel@05d8dbf55508df7c28fdd6f7b5988d090cbe8917 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Bucha11
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@05d8dbf55508df7c28fdd6f7b5988d090cbe8917 -
Trigger Event:
push
-
Statement type: