Anomaly Detection
Behavioral baseline learning and deviation detection for AI agent activity.
Anomaly Detection
Anomaly detection establishes behavioral baselines for your agents and users, then alerts when activity deviates from normal patterns. This catches attacks that don't match known threat signatures but exhibit unusual behavior.
Overview
Bastio learns what "normal" looks like for your agents:
- Which tools are typically used
- How often tools are called
- When activity occurs (time of day)
- What arguments are typical
- Risk scores distribution
When new activity deviates significantly from the baseline, Bastio flags it as anomalous.
How Baselines Work
Baseline Building
Bastio collects statistics over a learning period:
{
"baseline": {
"proxy_id": "proxy_abc",
"sample_size": 1523,
"tool_frequencies": {
"read_file": 45.2,
"write_file": 22.1,
"execute_shell": 8.3,
"http_get": 24.4
},
"avg_tool_calls_per_session": 12.5,
"typical_hours": [9, 10, 11, 12, 13, 14, 15, 16, 17],
"avg_risk_score": 0.15,
"std_dev_risk_score": 0.08,
"last_updated": "2024-01-15T00:00:00Z"
}
}Minimum Samples
Baselines require a minimum number of samples before anomaly detection activates:
| Baseline Type | Minimum Samples | Recommended |
|---|---|---|
| Proxy-level | 30 | 100+ |
| User-level | 10 | 50+ |
| Agent-level | 20 | 75+ |
Until minimum samples are reached, anomaly detection runs in learning mode and won't generate alerts.
Anomaly Types
Tool Usage Anomaly
Unusual tool or tool frequency:
{
"anomaly_type": "tool_usage",
"details": {
"tool": "db_admin",
"baseline_frequency": 0.1,
"current_frequency": 15.3,
"deviation_factor": 153,
"message": "Unusual tool usage: db_admin called 153x more than baseline"
}
}Time-Based Anomaly
Activity outside normal hours:
{
"anomaly_type": "time_based",
"details": {
"current_hour": 3,
"typical_hours": [9, 10, 11, 12, 13, 14, 15, 16, 17],
"message": "Activity at 3:00 AM is outside typical hours (9 AM - 5 PM)"
}
}Risk Score Spike
Sudden increase in risk scores:
{
"anomaly_type": "risk_spike",
"details": {
"current_risk": 0.75,
"baseline_avg": 0.15,
"baseline_std_dev": 0.08,
"z_score": 7.5,
"message": "Risk score 7.5 standard deviations above baseline"
}
}Volume Anomaly
Unusual activity volume:
{
"anomaly_type": "volume",
"details": {
"current_calls_per_minute": 45,
"baseline_calls_per_minute": 5,
"deviation_factor": 9,
"message": "Tool call volume 9x higher than baseline"
}
}Argument Pattern Anomaly
Unusual argument patterns:
{
"anomaly_type": "argument_pattern",
"details": {
"tool": "read_file",
"typical_paths": ["/app/*", "/data/*"],
"current_path": "/etc/shadow",
"message": "File path /etc/shadow outside typical patterns"
}
}API Response
When anomalies are detected, responses include:
{
"action": "warn",
"tool_call_id": "call_xyz",
"risk_score": 0.45,
"anomalies_detected": [
{
"type": "time_based",
"severity": "medium",
"deviation_score": 2.5,
"message": "Activity at unusual hour"
},
{
"type": "tool_usage",
"severity": "low",
"deviation_score": 1.8,
"message": "Infrequent tool usage"
}
],
"baseline_status": "established",
"message": "Tool allowed with anomaly warnings"
}Anomaly Severity
| Severity | Deviation Score | Typical Action |
|---|---|---|
low | 1.5 - 2.5 | Log, no action |
medium | 2.5 - 4.0 | Warn, increase monitoring |
high | 4.0 - 6.0 | Require approval |
critical | 6.0+ | Block |
Configuration
Enable Anomaly Detection
curl -X PUT https://api.bastio.com/v1/guard/{proxyId}/settings \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"anomaly_detection_enabled": true,
"anomaly_sensitivity": "medium",
"baseline_learning_days": 7,
"minimum_baseline_samples": 50
}'Settings
| Setting | Default | Description |
|---|---|---|
anomaly_detection_enabled | true | Enable anomaly detection |
anomaly_sensitivity | medium | low, medium, high |
baseline_learning_days | 7 | Days to learn baseline |
minimum_baseline_samples | 30 | Minimum samples before detection |
anomaly_action_threshold | 4.0 | Deviation score to trigger action |
Sensitivity Levels
| Level | Detection Threshold | Use Case |
|---|---|---|
low | 4.0+ deviation | Production with varied usage |
medium | 2.5+ deviation | Standard production |
high | 1.5+ deviation | High-security environments |
Baseline Types
Proxy Baseline
Global baseline for all activity through a proxy:
curl https://api.bastio.com/v1/guard/{proxyId}/baseline \
-H "Authorization: Bearer YOUR_API_KEY"User Baseline
Per-user behavioral patterns:
curl https://api.bastio.com/v1/guard/{proxyId}/baseline/user/{userId} \
-H "Authorization: Bearer YOUR_API_KEY"Agent Baseline
Per-agent identity patterns:
curl https://api.bastio.com/v1/guard/{proxyId}/baseline/agent/{agentId} \
-H "Authorization: Bearer YOUR_API_KEY"Managing Baselines
View Baseline
curl https://api.bastio.com/v1/guard/{proxyId}/baseline \
-H "Authorization: Bearer YOUR_API_KEY"{
"baseline": {
"status": "established",
"sample_size": 1523,
"learning_started": "2024-01-01T00:00:00Z",
"last_updated": "2024-01-15T00:00:00Z",
"metrics": {
"tool_frequencies": { ... },
"risk_distribution": { ... },
"temporal_patterns": { ... }
}
}
}Reset Baseline
After significant changes to your application:
curl -X POST https://api.bastio.com/v1/guard/{proxyId}/baseline/reset \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "Application update with new tools"
}'Exclude from Baseline
Mark certain sessions as non-representative:
{
"session_id": "session_testing_123",
"exclude_from_baseline": true,
"reason": "Load testing session"
}Alerts
Configure alerts for anomaly events:
curl -X POST https://api.bastio.com/v1/guard/{proxyId}/alerts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Critical Anomaly Alert",
"condition": {
"anomaly_severity": "critical"
},
"channels": ["email", "slack"],
"rate_limit_minutes": 15
}'Code Examples
Handling Anomaly Warnings
async def validate_with_anomaly_handling(
proxy_id: str,
tool_call: dict,
session_id: str
) -> dict:
"""Validate tool call and handle anomalies."""
result = await validate_tool_call(proxy_id, tool_call, session_id)
if result.get("anomalies_detected"):
for anomaly in result["anomalies_detected"]:
# Log all anomalies
logger.info(
"Anomaly detected",
type=anomaly["type"],
severity=anomaly["severity"],
message=anomaly["message"]
)
# Escalate high severity
if anomaly["severity"] in ["high", "critical"]:
await notify_security_team({
"type": "anomaly",
"session_id": session_id,
"anomaly": anomaly
})
return result
# Check baseline status
async def check_baseline_status(proxy_id: str) -> dict:
"""Check if baseline is established."""
async with httpx.AsyncClient() as client:
response = await client.get(
f"https://api.bastio.com/v1/guard/{proxy_id}/baseline",
headers={"Authorization": f"Bearer {API_KEY}"}
)
baseline = response.json()["baseline"]
if baseline["status"] == "learning":
print(f"Baseline learning: {baseline['sample_size']} samples collected")
else:
print(f"Baseline established with {baseline['sample_size']} samples")
return baselineinterface AnomalyResult {
action: string;
anomalies_detected?: Array<{
type: string;
severity: string;
deviation_score: number;
message: string;
}>;
}
async function validateWithAnomalyHandling(
proxyId: string,
toolCall: object,
sessionId: string
): Promise<AnomalyResult> {
const result = await validateToolCall(proxyId, toolCall, sessionId);
if (result.anomalies_detected) {
for (const anomaly of result.anomalies_detected) {
console.log('Anomaly detected:', {
type: anomaly.type,
severity: anomaly.severity,
message: anomaly.message,
});
if (['high', 'critical'].includes(anomaly.severity)) {
await notifySecurityTeam({
type: 'anomaly',
sessionId,
anomaly,
});
}
}
}
return result;
}Viewing Anomaly History
Query past anomaly events:
curl https://api.bastio.com/v1/guard/{proxyId}/anomalies \
-H "Authorization: Bearer YOUR_API_KEY" \
-G \
-d "start_time=2024-01-01T00:00:00Z" \
-d "severity=high,critical"{
"anomalies": [
{
"event_id": "anom_001",
"timestamp": "2024-01-15T03:30:00Z",
"session_id": "session_abc",
"type": "time_based",
"severity": "high",
"deviation_score": 4.5,
"tool_call": {
"name": "execute_shell",
"arguments": { ... }
}
}
]
}Best Practices
Next Steps
- Chain Analysis - Multi-tool attack detection
- Policies - Configure anomaly-based policies
- Tool Validation - Real-time threat scanning