ADR Sensor
Agentic Detection & Response (ADR) Sensor - Security observability for AI coding agents.
ADR Sensor is a Python library that collects telemetry from AI coding agents to enable security monitoring, threat detection, and observability. It parses logs from multiple AI agent platforms and normalizes them into a unified schema for downstream analysis.
Paper: ADR: An Agentic Detection System for Enterprise Agentic AI Security
Code: github.com/uber/ADR
Supported AI Agents
| Agent | Log Format | Platform |
|---|---|---|
| Claude Code | JSONL (~/.claude/projects/) |
macOS, Linux |
| Cursor IDE | SQLite (state.vscdb) |
macOS, Linux |
| Cline (Claude Dev) | JSON task files | macOS, Linux |
| Claude Desktop Agent Mode | JSONL audit logs | macOS |
| OpenAI Codex CLI | JSONL (~/.codex/sessions/) |
macOS, Linux |
| Warp Terminal | SQLite (warp.sqlite) |
macOS |
Architecture
┌─────────────────────────────────────────────────────────┐
│ AI Agent Logs │
│ Claude Code │ Cursor │ Cline │ Codex │ Warp │ Desktop │
└──────┬───────┴───┬────┴───┬───┴───┬───┴──┬───┴────┬─────┘
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ Source-Specific Parsers │
│ (Each implements BaseParser) │
└─────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Unified Schema (AgentEvent) │
│ session_id │ timestamp │ chat_history │ tools │ model │
└─────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ AgentObserver (Orchestrator) │
│ Ingest → Filter → Display → Export │
└─────────────────────┬───────────────────────────────────┘
│
┌───────┴───────┐
▼ ▼
JSON/JSONL Your Detection
Export Pipeline / SIEM
Quick Start
Installation
pip install adr-sensor
Or install from source:
git clone https://github.com/uber/ADR
cd ADR/Sensor
pip install -e ".[dev]"
CLI Usage
# Ingest from all supported agents
adr-sensor
# Ingest from a specific source
adr-sensor --source claude
adr-sensor --source cursor
adr-sensor --source codex
# Save individual session files (incremental)
adr-sensor --save-sessions
# Export as JSONL
adr-sensor --output-format jsonl
# Include all history (not just last 2 weeks)
adr-sensor --all-history
# Custom output directory
adr-sensor --output-dir ./my-output
Python API
from adr_sensor import AgentObserver
# Create observer
observer = AgentObserver()
# Ingest from all sources
events, configs = observer.ingest_all()
# Or from a specific source
events, configs = observer.ingest_all(source_filter="claude")
# Display summary
observer.display_summary(events, configs)
# Save to file
observer.save_to_file(events, configs, output_format="json")
# Analyze events
for event in events:
print(f"Source: {event.source}, Session: {event.session_id}")
print(f"Messages: {len(event.chat_history)}")
for msg in event.chat_history:
if msg.tools:
for tool in msg.tools:
print(f" Tool: {tool.tool_name} ({tool.tool_type})")
print(f" Args: {tool.arguments}")
Output Schema
AgentEvent
Each parsed session produces an AgentEvent with the following structure:
{
"uuid": "sha256-hash",
"timestamp": "2025-06-15T10:30:00+00:00",
"source": "claude",
"session_id": "claude_abc123",
"hostname": "my-laptop",
"username": "developer",
"model": "claude-sonnet-4-20250514",
"project_path": "/home/user/my-project",
"chat_history": [
{
"role": "user",
"content": "Help me fix this bug",
"tools": [],
"sequence_id": "msg_0"
},
{
"role": "assistant",
"content": "Let me look at the code.",
"tools": [
{
"tool_name": "read_file",
"tool_type": "tool_use",
"arguments": {"path": "main.py"},
"result": "def hello(): ...",
"status": "success"
}
],
"sequence_id": "msg_1"
}
]
}
Adding a New Parser
ADR Sensor is designed to be extensible. To add support for a new AI agent:
- Create a new parser in
adr_sensor/parsers/:
from adr_sensor.parsers.base_parser import BaseParser
from adr_sensor.schemas.agent_event_schema import AgentEvent, ChatMessage, ToolUsage
class MyAgentParser(BaseParser):
def __init__(self):
self.base_path = Path.home() / ".my-agent/logs"
def parse_all(self) -> list[AgentEvent]:
entries = []
# Parse your agent's log files
# Convert to AgentEvent objects
return entries
- Register it in
adr_sensor/observer.py:
from .parsers.my_agent_parser import MyAgentParser
class AgentObserver:
def __init__(self, ...):
...
self.my_agent_parser = MyAgentParser()
def ingest_all(self, source_filter="all"):
...
if source_filter in ["all", "my_agent"]:
entries = self.my_agent_parser.parse_all()
all_entries.extend(entries)
- Add tests in
tests/.
Security Use Cases
ADR Sensor enables detection of:
- Suspicious tool usage - Unusual MCP tools, unauthorized file access, credential exfiltration
- Prompt injection - Malicious content injected into agent conversations
- Supply chain risks - Malicious MCP server configurations, suspicious packages
- Data exfiltration - Sensitive data accessed or transmitted by agents
- Anomalous behavior - Activity outside normal patterns, burst tool usage
Development
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run tests with coverage
pytest tests/ -v --cov=adr_sensor
# Lint
ruff check adr_sensor/
ruff format adr_sensor/
Project Structure
adr-sensor/
├── adr_sensor/
│ ├── __init__.py # Package exports
│ ├── cli.py # CLI entry point
│ ├── observer.py # AgentObserver orchestrator
│ ├── parsers/
│ │ ├── base_parser.py # Abstract base class
│ │ ├── claude_parser.py
│ │ ├── cursor_parser.py
│ │ ├── cline_parser.py
│ │ ├── claude_desktop_parser.py
│ │ ├── codex_parser.py
│ │ └── warp_parser.py
│ ├── schemas/
│ │ ├── agent_event_schema.py # AgentEvent, ChatMessage, ToolUsage
│ │ └── system_config_schema.py # SystemConfiguration
│ └── utils/
│ ├── string_utils.py
│ └── timestamp_utils.py
├── tests/
├── examples/
├── CONTRIBUTING.md
├── LICENSE
├── pyproject.toml
└── README.md
License
Apache License 2.0. See LICENSE for details.
Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Especially welcome:
- New parsers for additional AI agents
- Detection rules and analysis patterns
- Documentation improvements
- Bug reports and fixes
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 adr_sensor-1.0.0.tar.gz.
File metadata
- Download URL: adr_sensor-1.0.0.tar.gz
- Upload date:
- Size: 37.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
abc99cefdcd55e5b3dff8c532fdb20dab645f4b26fbbe2b03f2e79c4e6eb37c4
|
|
| MD5 |
a4936c11dfa83af4e0ed12937e58bbe3
|
|
| BLAKE2b-256 |
0f52efe9eca6a22776c83faf2477e6c630eb08fd9ac622fbd4a7d05717ca10f9
|
Provenance
The following attestation bundles were made for adr_sensor-1.0.0.tar.gz:
Publisher:
release-sensor.yml on uber/ADR
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adr_sensor-1.0.0.tar.gz -
Subject digest:
abc99cefdcd55e5b3dff8c532fdb20dab645f4b26fbbe2b03f2e79c4e6eb37c4 - Sigstore transparency entry: 2305357450
- Sigstore integration time:
-
Permalink:
uber/ADR@4e303acf953c85a4f7e18574cef8b730f8734f20 -
Branch / Tag:
refs/tags/sensor-v1.0.0 - Owner: https://github.com/uber
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-sensor.yml@4e303acf953c85a4f7e18574cef8b730f8734f20 -
Trigger Event:
release
-
Statement type:
File details
Details for the file adr_sensor-1.0.0-py3-none-any.whl.
File metadata
- Download URL: adr_sensor-1.0.0-py3-none-any.whl
- Upload date:
- Size: 40.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9f208e7526dba0f9e8304c7087ba69bda8379d08915a384dbe137c37f5c7b39
|
|
| MD5 |
4913acb09e5736364a9088267022b247
|
|
| BLAKE2b-256 |
071d82ebe0865954825a2e236f10c8273a37d53da3e1466f1cc2bf02d5086b93
|
Provenance
The following attestation bundles were made for adr_sensor-1.0.0-py3-none-any.whl:
Publisher:
release-sensor.yml on uber/ADR
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adr_sensor-1.0.0-py3-none-any.whl -
Subject digest:
a9f208e7526dba0f9e8304c7087ba69bda8379d08915a384dbe137c37f5c7b39 - Sigstore transparency entry: 2305357492
- Sigstore integration time:
-
Permalink:
uber/ADR@4e303acf953c85a4f7e18574cef8b730f8734f20 -
Branch / Tag:
refs/tags/sensor-v1.0.0 - Owner: https://github.com/uber
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-sensor.yml@4e303acf953c85a4f7e18574cef8b730f8734f20 -
Trigger Event:
release
-
Statement type: