Audit Events & SOC Metrics
Audit Events & SOC Metrics
Every case action in nano is automatically logged as a searchable audit event with source_type=audit and source=case. This enables building SOC metrics dashboards to track key performance indicators like MTTD (Mean Time to Detect), MTTR (Mean Time to Respond), analyst workload, and disposition trends.
All audit events use source_type=audit with different source values:
source=case- Case management events (this page)source=auth- Authentication events (future)source=detection- Detection rule changes (future)
For auditing of administrative actions in the Settings UI, see Platform Audit Logging.
Overview
Case audit events are stored in the same log storage (ClickHouse) as your security data, making them queryable using the standard nano search interface. This approach allows you to:
- Build dashboards using native nano dashboard capabilities
- Correlate SOC metrics with security events
- Create alerts on operational anomalies (e.g., case backlog growing)
- Export metrics to external systems via API
Audit Event Schema
Source Type
All case audit events have:
source_type = "audit"
source = "case"Event Actions
| Action | Description | When Emitted |
|---|---|---|
created | Case was created | New case created (manual or auto-grouped) |
alert_added | Alert added to case | Alert grouped into case |
alert_removed | Alert removed from case | Alert manually removed |
status_changed | Status changed | Status transition (not resolve/close/reopen) |
assigned | Case assigned | Analyst assigned to case |
unassigned | Case unassigned | Assignment removed |
resolved | Case resolved | Status changed to "resolved" |
closed | Case closed | Status changed to "closed" |
reopened | Case reopened | Closed/resolved case reopened |
comment_added | Comment added | Analyst adds comment to case wall |
ai_analysis | AI analysis generated | AI summary or triage generated |
severity_changed | Severity changed | Case severity modified |
merged | Cases merged | Case merged with another |
entity_added | Entity added | New entity extracted/added |
Event Fields
| Field | Type | Description |
|---|---|---|
case_id | UUID | Unique case identifier |
case_number | Integer | Human-readable case number (CASE-1234) |
case_title | String | Case title |
action | String | Action type (see table above) |
actor_id | UUID | User who performed the action |
actor_name | String | Username of actor |
severity | String | Case severity at time of event |
status | String | Case status at time of event |
previous_status | String | Previous status (for status changes) |
disposition | String | Disposition (for resolved/closed) |
assigned_to | UUID | Assigned analyst ID |
assigned_to_name | String | Assigned analyst name |
alert_count | Integer | Number of alerts in case |
entity_count | Integer | Number of entities in case |
grouping_type | String | How case was grouped (host/user/ip/rule/manual) |
Timing Metrics
These fields enable SOC performance dashboards:
| Field | Type | Description |
|---|---|---|
time_since_creation_seconds | Integer | Seconds since case was created |
time_to_assign_seconds | Integer | Seconds from creation to first assignment |
time_to_resolve_seconds | Integer | Seconds from creation to resolution (MTTR) |
time_to_detect_seconds | Integer | Seconds from first alert to case creation (MTTD) |
time_in_status_seconds | Integer | Seconds case spent in previous status |
Additional Context
| Field | Type | Description |
|---|---|---|
alert_id | UUID | Related alert (for alert_added/removed) |
entity_value | String | Related entity value |
entity_type | String | Related entity type |
related_case_id | UUID | Related case (for merges) |
notes | String | Comment content (truncated to 500 chars) |
Querying Audit Events
Basic Queries
All Case Creations
source_type=audit source=case action=createdAll Resolutions Today
source_type=audit source=case action=resolved
| where timestamp > now() - 24hHigh Severity Case Activity
source_type=audit source=case severity=critical OR severity=highActivity by Specific Analyst
source_type=audit source=case actor_name="jsmith"SOC Metrics Dashboards
Mean Time to Resolve (MTTR)
The most important SOC metric - how long it takes to close cases:
source_type=audit source=case action=resolved
| stats avg(time_to_resolve_seconds) as avg_mttr_seconds
| eval avg_mttr_hours = avg_mttr_seconds / 3600
| eval avg_mttr_minutes = avg_mttr_seconds / 60MTTR by Severity
source_type=audit source=case action=resolved
| stats avg(time_to_resolve_seconds) as avg_mttr by severity
| eval avg_mttr_hours = avg_mttr / 3600
| sort severityMTTR Trend Over Time
source_type=audit source=case action=resolved
| bucket timestamp span=1d
| stats avg(time_to_resolve_seconds) as avg_mttr by timestamp
| eval avg_mttr_hours = avg_mttr / 3600Mean Time to Detect (MTTD)
How quickly threats are identified:
source_type=audit source=case action=created
| where time_to_detect_seconds > 0
| stats avg(time_to_detect_seconds) as avg_mttd
| eval avg_mttd_minutes = avg_mttd / 60Mean Time to Assign (MTTA)
How quickly cases are picked up by analysts:
source_type=audit source=case action=assigned
| stats avg(time_to_assign_seconds) as avg_mtta
| eval avg_mtta_minutes = avg_mtta / 60Analyst Workload
Cases per Analyst
source_type=audit source=case action=assigned
| stats count by assigned_to_name
| sort -countResolutions per Analyst
source_type=audit source=case action=resolved
| stats count by actor_name
| sort -countActive Case Load by Analyst
source_type=audit source=case action=assigned
| stats latest(status) as current_status by case_id, assigned_to_name
| where current_status != "closed" AND current_status != "resolved"
| stats count by assigned_to_nameDisposition Analysis
Disposition Distribution
source_type=audit source=case action=resolved OR action=closed
| where disposition != ""
| stats count by dispositionFalse Positive Rate
source_type=audit source=case action=resolved OR action=closed
| where disposition != ""
| stats
count(eval(disposition="false_positive")) as false_positives,
count as total
| eval fp_rate = (false_positives / total) * 100Dispositions by Detection Rule
source_type=audit source=case action=resolved
| stats count by case_title, disposition
| sort case_title, -countCase Volume Trends
Cases Created per Day
source_type=audit source=case action=created
| bucket timestamp span=1d
| stats count by timestampCases by Severity Over Time
source_type=audit source=case action=created
| bucket timestamp span=1d
| stats count by timestamp, severityCases by Grouping Type
source_type=audit source=case action=created
| stats count by grouping_typeCase Backlog
Open Case Count
source_type=audit source=case
| stats latest(status) as current_status by case_id
| where current_status = "open" OR current_status = "in_progress" OR current_status = "pending"
| stats countAging Cases (Open > 24 hours)
source_type=audit source=case action=created
| stats min(timestamp) as created_at by case_id
| join case_id [
source_type=audit source=case
| stats latest(status) as current_status by case_id
]
| where current_status != "closed" AND current_status != "resolved"
| eval age_hours = (now() - created_at) / 3600
| where age_hours > 24
| stats countAlert Correlation
Alerts per Case Distribution
source_type=audit source=case action=resolved
| stats avg(alert_count) as avg_alerts, max(alert_count) as max_alertsCases with Most Alerts
source_type=audit source=case
| stats max(alert_count) as alerts by case_number, case_title
| sort -alerts
| head 10Dashboard Examples
Executive SOC Dashboard
Create a dashboard with these panels:
| Panel | Query | Visualization |
|---|---|---|
| MTTR (Hours) | MTTR query above | Single value |
| MTTD (Minutes) | MTTD query above | Single value |
| Open Cases | Backlog count | Single value |
| Cases Today | Created today count | Single value |
| MTTR Trend | MTTR by day | Line chart |
| Cases by Severity | Volume by severity | Pie chart |
| Disposition Breakdown | Disposition distribution | Pie chart |
| Analyst Workload | Cases per analyst | Bar chart |
Analyst Performance Dashboard
| Panel | Query | Visualization |
|---|---|---|
| My Open Cases | Filter by current user | Table |
| My Resolutions (Week) | Resolved by me, 7 days | Single value |
| Avg Resolution Time | My MTTR | Single value |
| My Disposition Breakdown | My dispositions | Pie chart |
| Cases Resolved per Day | My resolutions by day | Bar chart |
Detection Tuning Dashboard
| Panel | Query | Visualization |
|---|---|---|
| False Positive Rate | FP rate query | Gauge |
| FP by Rule | Dispositions by rule | Table |
| Most Active Rules | Cases by rule | Bar chart |
| Rules Needing Tuning | High FP rules | Table |
Alerting on Metrics
Create detection rules on audit events to alert on operational issues:
High Case Backlog Alert
name: SOC Case Backlog Alert
query: |
source_type=audit source=case
| stats latest(status) as status by case_id
| where status = "open"
| stats count as open_cases
| where open_cases > 50
schedule: "*/15 * * * *"
severity: mediumStale Cases Alert
name: Stale Case Alert
query: |
source_type=audit source=case action=created
| stats min(timestamp) as created by case_id
| join case_id [
source_type=audit source=case | stats latest(status) as status by case_id
]
| where status = "open"
| eval age_hours = (now() - created) / 3600
| where age_hours > 48
| stats count as stale_cases
| where stale_cases > 0
schedule: "0 */6 * * *"
severity: lowMTTR Degradation Alert
name: MTTR Degradation Alert
query: |
source_type=audit source=case action=resolved
| where timestamp > now() - 24h
| stats avg(time_to_resolve_seconds) as mttr
| where mttr > 14400 -- 4 hours
schedule: "0 * * * *"
severity: mediumBest Practices
1. Baseline Your Metrics
Before setting alerts, establish baselines:
- What is your normal MTTR?
- What is your typical case volume?
- What is your expected false positive rate?
2. Track Trends, Not Absolutes
Single data points can be misleading. Focus on trends:
- Is MTTR improving over time?
- Is case volume seasonal?
- Are certain rules generating more false positives?
3. Segment by Severity
Aggregate metrics hide important details:
- Critical cases should have lower MTTR than low severity
- Track metrics per severity level
4. Review Regularly
Schedule regular reviews of SOC metrics:
- Weekly: Analyst performance, backlog health
- Monthly: MTTR/MTTD trends, false positive rates
- Quarterly: Detection tuning opportunities
5. Export for Reporting
Use the API to export metrics for executive reporting:
# Export MTTR data
curl "/api/search" -d '{
"query": "source_type=audit source=case action=resolved | stats avg(time_to_resolve_seconds) by severity",
"start": "-30d",
"end": "now"
}'API Reference
Query Audit Events
POST /api/search
{
"query": "source_type=audit source=case action=resolved",
"start": "-7d",
"end": "now",
"limit": 1000
}Get Case Audit Trail
GET /api/cases/:id/wallReturns all audit events for a specific case as wall entries.