ank3it's picture
Add model card / README
3c45901 verified
|
Raw
History Blame
10 kB
metadata
library_name: sklearn
tags:
  - fraud-detection
  - agentic-commerce
  - agent-safety
  - mcp
  - random-forest
  - tabular-classification
  - session-graph
  - anomaly-detection
pipeline_tag: tabular-classification
inference: false
extra_gated_prompt: >-
  This model is part of the ACB-Guard research suite. Access is granted for
  research and evaluation purposes.

ACB-Guard · Session Graph RandomForest (session_graph_rf)

A structural fraud detector for agentic commerce sessions. Every agent session is represented as a directed graph of MCP (Model Context Protocol) calls, reduced to a compact 20-dimensional feature vector, and scored by a scikit-learn RandomForestClassifier. It is a novel baseline for AgentCommerceBench (ACB) and ships as a drop-in per-event detector.

Core idea. MCP call sequences form distinctive graphs per persona. Clean sessions produce regular, low-density graphs. Attacks introduce structural anomalies — high out-degree (reconnaissance), recursive purchase cycles, amount-variance spikes (price poisoning / ratcheting), and timing bursts. A graph view catches behavioral attacks that a text classifier alone will miss.


Model at a glance

Model name session_graph_rf
Task Binary session classification — clean (0) vs attacked (1)
Algorithm RandomForestClassifier (scikit-learn), 200 trees, max_depth=10, class_weight="balanced"
Input An agent commerce session (ordered list of MCP events)
Output Fraud probability P(fraud) ∈ [0, 1] + top contributing feature flags
Feature space 20 hand-engineered session-graph features
Serialized as session_graph_rf.joblib (~833 KB, joblib/pickle)
Interface detect(event, history) -> (score, flags) — drop-in with other ACB detectors
Access 🔒 Gated

Why a graph model

ACB attacks fall into two broad families, and each needs a different lens:

  • L1 — prompt / payload attacks. Injected instructions, base64-encoded payloads, "SYSTEM:" overrides, and settlement-proxy redirects embedded in request text. These are best caught by an LLM safety baseline and by lightweight payload heuristics.
  • L2 — behavioral attacks. Reconnaissance sweeps, recursive purchases, price ratcheting, and scope violations that look fine per message but are anomalous at the session level. Text classifiers, which score one message at a time, are effectively blind to these.

session_graph_rf targets the L2 gap by modelling the shape of a whole session, while still carrying two cheap L1 signals (has_override, has_b64) so it degrades gracefully when both attack families appear together. It is designed to complement, not replace, the LLM safety baseline in the ACB-Guard ensemble.


How it works

1. Session → graph

Each session is treated as a directed graph:

  • Nodes — the agent plus every distinct service_id / operation_id it touches.
  • Edges — directed call edges (FIND_SERVICE → service, AUTHORIZE → service, …).
  • Edge attributes — normalized USDC amount, inter-event timing gap (seconds), and service category.

2. Graph → 20-dim feature vector

session_to_features(session) reduces the graph to a fixed vector. Grouped by the signal it is meant to expose:

# Feature Signal
0 n_events session size
1 n_find_service discovery volume
2 n_authorize authorization volume
3 n_settle settlement volume
4 find_authorize_ratio reconnaissance (search-heavy, buy-light)
5 n_distinct_services breadth of services touched
6 service_diversity entropy of the service distribution
7 total_amount_usdc total spend
8 max_amount_usdc largest single transfer
9 amount_std_usdc price ratcheting / poisoning (variance)
10 amount_max_ratio spike vs. session mean
11 timing_gap_mean_s pacing
12 timing_gap_std_s burst irregularity
13 timing_gap_min_s tightest burst
14 n_categories category breadth
15 dominant_category_frac scope violation (purity)
16 n_a2a_transfers agent-to-agent transfer count
17 a2a_amount_usdc agent-to-agent spend
18 has_override_keyword L1SYSTEM: / override / proxy-redirect in payload
19 has_b64_blob L1 — suspicious base64 blob in payload

Amounts are converted from integer units to USDC (amount_units / 1_000_000). service_diversity is Shannon entropy over the service-call distribution. The two L1 flags run regex/base64 checks over each event's original_request.

3. Vector → score

The RandomForest returns P(fraud). Scores below 0.30 are suppressed to 0.0 to keep the false-positive rate low. When a session is flagged, the detector attributes the decision by ranking feature_importance × |feature_value| and emitting the top-3 contributing features as human-readable flags (e.g. sgrf:find_auth_ratio=8.00).


The detector interface

The model plugs into the ACB harness through a per-event detect call and scores the full session (history + current event) each time:

def detect(event: Event, history: list[Event]) -> tuple[float, list[str]]:
    ...
  • Returns 0.0, [] until the session has ≥ 4 events (not enough context to judge).
  • Caches per (session_id, session_length) so the RandomForest runs at most once per session growth step — cheap enough to call on every event.
  • score is P(fraud); flags are the top contributing features for attribution.

Usage

The repository ships two files:

  • session_graph.py — feature extraction + SessionGraphModel class and module-level API.
  • session_graph_rf.joblib — the fitted RandomForestClassifier.

Load the trained classifier

import joblib
from huggingface_hub import hf_hub_download

# Gated repo — authenticate first: `huggingface-cli login`
path = hf_hub_download(
    repo_id="withgordon/acb-guard-session-graph-rf",
    filename="session_graph_rf.joblib",
)
clf = joblib.load(path)   # sklearn RandomForestClassifier

# clf expects a 20-dim feature vector produced by session_to_features(...)
# proba = clf.predict_proba(features_20d.reshape(1, -1))[0][1]  # P(fraud)

Score a session end-to-end

from benchmark.models.session_graph import SessionGraphModel

model = SessionGraphModel()
model.fit(train_sessions)               # list[Session]
score, flags = model.detect(event, history)   # drop-in detector interface
print(score, flags)                     # e.g. 0.87 ['sgrf:find_auth_ratio=8.00', ...]

Note. session_graph.py imports session/event schema types from the ACB harness (harness.simulate.schema: Session, Event, ActionType). Feature extraction and the detect interface require those types to be importable, so run it inside the ACB benchmark environment.


Training

  • Estimator. RandomForestClassifier(n_estimators=200, max_depth=10, class_weight="balanced", random_state=42).
  • Labels. 0 for session.is_clean, 1 otherwise.
  • Features. The 20-dim vector above, stacked across all training sessions.
  • Class balance. Handled via class_weight="balanced" (attacked sessions are the minority class).
  • Determinism. random_state=42 for reproducible fits.

Retraining is a single call:

model = SessionGraphModel(n_estimators=200, max_depth=10)
model.fit(train_sessions)
joblib.dump(model.clf, "session_graph_rf.joblib")

Intended use & scope

Intended. A behavioral, session-level fraud baseline for AgentCommerceBench and for research on safety in agentic commerce / MCP tool-use settings. Best used as one member of an ensemble alongside an LLM safety baseline.

Out of scope. Not a standalone production fraud system; not a general payments risk model; not intended for real financial authorization decisions. The two embedded L1 flags are convenience signals, not a substitute for a dedicated prompt-injection defense.


Limitations

  • Feature-engineered, not learned graph structure. The model consumes hand-crafted aggregate features rather than a learned graph embedding (no GNN). It captures the intended structural signals but not arbitrary graph patterns.
  • Cold start. Returns 0.0 for the first 3 events of every session by design; very short attacks may complete before enough context accumulates.
  • Threshold coupling. The 0.30 suppression threshold trades recall for precision and may need re-tuning per deployment / attack mix.
  • Distribution shift. Trained on ACB-simulated sessions; behavior on real-world agent traffic, unseen attack strategies, or different MCP schemas is not characterized here.
  • Attribution is heuristic. Flags rank importance × |value|, an approximation of true per-prediction contribution — treat them as hints, not SHAP-grade explanations.
  • Serialization caveat. Distributed as a joblib/pickle artifact; only load it from a source you trust.

Files

File Description
session_graph.py Feature extraction, SessionGraphModel, and module-level detect API
session_graph_rf.joblib Fitted scikit-learn RandomForestClassifier (~833 KB)

Citation

@software{acb_guard_session_graph_rf,
  title  = {ACB-Guard: Session Graph RandomForest for Agentic Commerce Fraud Detection},
  author = {withgordon},
  year   = {2026},
  note   = {A novel session-graph baseline for AgentCommerceBench},
  url    = {https://huggingface.co/withgordon/acb-guard-session-graph-rf}
}

Part of the ACB-Guard suite for AgentCommerceBench. This model targets L2 behavioral attacks and is designed to complement an LLM safety baseline that handles L1 payload attacks.