Session Records (CDR-style Capture)¶
ELIDA captures detailed session records similar to Call Detail Records (CDRs) in telecommunications. When a session ends, all relevant data is persisted to SQLite for forensic analysis, compliance auditing, and operational visibility.
Overview¶
Session records capture: - Session metadata: ID, state, timing, request counts - Traffic metrics: bytes in/out, backend used - Captured content: full request/response bodies (when enabled) - Policy violations: rule name, severity, matched text, action
This enables security teams to: - Investigate suspicious agent behavior - Audit session activity for compliance - Review blocked requests with full context - Analyze patterns across historical sessions
Configuration¶
Enable Session Storage¶
storage:
enabled: true
path: "data/elida.db"
retention_days: 30
capture_mode: "all" # "all" or "flagged_only"
Environment Variables¶
| Variable | Default | Description |
|---|---|---|
ELIDA_STORAGE_ENABLED |
false |
Enable SQLite storage |
ELIDA_STORAGE_PATH |
data/elida.db |
Database file path |
ELIDA_STORAGE_CAPTURE_MODE |
all |
Capture mode |
Capture Modes¶
| Mode | Description | Use Case |
|---|---|---|
all |
Capture all session content (default) | Agentic workloads, fewer sessions, full audit trail |
flagged_only |
Only capture flagged sessions | High-volume web traffic, storage optimization |
Recommendation: Use all for AI agent traffic where sessions are fewer but higher-value. Use flagged_only for high-volume web traffic to reduce storage overhead.
Session Record Schema¶
CREATE TABLE sessions (
id TEXT PRIMARY KEY,
state TEXT NOT NULL, -- Active, Killed, Completed, TimedOut
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
duration_ms INTEGER NOT NULL,
request_count INTEGER NOT NULL,
bytes_in INTEGER NOT NULL,
bytes_out INTEGER NOT NULL,
backend TEXT NOT NULL,
client_addr TEXT NOT NULL,
metadata TEXT, -- JSON: custom key-value pairs
captured_content TEXT, -- JSON: array of requests/responses
violations TEXT, -- JSON: array of policy violations
created_at DATETIME
);
Data Structures¶
CapturedRequest¶
Each captured request/response pair:
{
"timestamp": "2026-01-18T22:44:18.059Z",
"method": "POST",
"path": "/v1/chat/completions",
"request_body": "{\"messages\":[...]}",
"response_body": "{\"choices\":[...]}",
"status_code": 200
}
Violation¶
Each policy violation includes source attribution and SIEM classification:
{
"rule_name": "prompt_injection_ignore_request",
"description": "LLM01: Prompt injection pattern in request",
"severity": "critical",
"effective_severity": "warning",
"matched_text": "ignore all previous instructions",
"matched_pattern": "ignore\\s+(all\\s+)?(previous|prior|above|your)\\s+(instructions|prompts|rules)",
"action": "flag",
"timestamp": "2026-03-14T20:46:08Z",
"source_role": "assistant",
"message_index": 63,
"source_content": "...full message content (truncated to max_capture_size)...",
"event_category": "prompt_injection",
"framework_ref": "OWASP-LLM01"
}
| Field | Type | Description |
|---|---|---|
rule_name |
string | Rule identifier |
severity |
string | Raw rule severity: info, warning, critical |
effective_severity |
string | Severity after source-role weighting |
source_role |
string | Message role that triggered the violation: user, assistant, system, tool |
message_index |
int | Position in the messages array (-1 for Anthropic top-level system) |
source_content |
string | Full message content, truncated to max_capture_size |
event_category |
string | SIEM category: prompt_injection, data_exfil, rate_limit, dangerous_command, sensitive_data, resource_abuse, data_volume, denial_of_service, model_abuse |
framework_ref |
string | Framework reference: OWASP-LLM01 through OWASP-LLM10, ELIDA-FIREWALL |
API Endpoints¶
List Session History¶
Response:
{
"count": 42,
"sessions": [
{
"id": "session-123",
"state": "killed",
"start_time": "2026-01-18T22:44:18Z",
"end_time": "2026-01-18T22:45:00Z",
"duration_ms": 42000,
"request_count": 5,
"bytes_in": 1024,
"bytes_out": 8192,
"backend": "anthropic",
"client_addr": "10.0.0.5",
"captured_content": [...],
"violations": [...]
}
]
}
Get Session by ID¶
Query Parameters¶
| Parameter | Description | Example |
|---|---|---|
limit |
Max results | ?limit=100 |
offset |
Pagination offset | ?offset=50 |
state |
Filter by state | ?state=killed |
backend |
Filter by backend | ?backend=anthropic |
since |
Start time filter | ?since=2026-01-18T00:00:00Z |
until |
End time filter | ?until=2026-01-19T00:00:00Z |
Statistics¶
Storage Overhead¶
Estimated bytes per session:
| Component | Size | Notes |
|---|---|---|
| Base session | ~250 bytes | ID, timestamps, metrics |
| Per captured request | ~2,500 bytes | With 2KB body capture |
| Per violation | ~300 bytes | Rule, description, match |
For a typical agentic session (10 requests, 2 violations): - ~250 + (10 × 2,500) + (2 × 300) = ~25.85 KB
Retention¶
Configure retention_days to automatically clean up old records:
The cleanup runs periodically when ELIDA is running.
When Sessions Are Captured¶
Session records are saved when:
- Session killed via API (
POST /control/sessions/{id}/kill) - Session terminated via API (
POST /control/sessions/{id}/terminate) - Session timed out (idle timeout or max duration)
- Policy auto-terminate (rule with
action: terminate)
Records are not saved for: - Active sessions (still in progress) - Sessions that haven't had any requests blocked
Dashboard Integration¶
The web dashboard at http://localhost:9090/ displays:
- History tab: Browse historical sessions with filtering
- Session details modal: Click any row to see:
- Session metrics (duration, requests, bytes)
- Captured requests with expandable bodies
- Policy violations with matched patterns
Best Practices¶
For Agentic Workloads¶
storage:
enabled: true
capture_mode: "all" # Full audit trail
retention_days: 90 # 90 days for compliance
For High-Volume API Traffic¶
For Development/Testing¶
Security Considerations¶
- Session records may contain sensitive data (API keys, PII)
- Secure the SQLite database file with appropriate permissions
- Consider encryption at rest for production deployments
- Implement access controls for the
/control/historyendpoint - Be mindful of storage growth with
capture_mode: all
Comparison to Telecom CDRs¶
| Telecom CDR | ELIDA Session Record |
|---|---|
| Caller/Callee | Client/Backend |
| Call duration | Session duration |
| Call status | Session state |
| Media type | Request method/path |
| Billing info | Bytes in/out |
| N/A | Policy violations |
| N/A | Request/response content |
ELIDA extends the CDR concept with: - Full request/response capture (optional) - Policy violation tracking - Backend routing information - Metadata for custom attributes