risk
risk
Assign risk scores to events for risk-based alerting. Build cumulative risk profiles for entities.
Description
The risk command assigns risk scores to events and entities, enabling risk-based alerting where multiple low-severity events can trigger alerts when combined. This is part of nano's risk-based alerting framework.
Risk scores accumulate over time per entity, allowing detection of suspicious patterns that wouldn't trigger individual alerts.
Dynamic Risk Scores: The score can be a literal value (e.g., 50) or a dynamic expression using field references, arithmetic, or conditional logic.
Syntax
... | risk score=<expr> [entity=<field>] [factor="<description>"] [weight=<float>]Required Arguments
score
Syntax: score=<expr>
Description: Risk score to assign (0-100). Can be:
- A literal integer:
score=50 - A field reference:
score=severity_level - An arithmetic expression:
score=count*5 - A conditional expression:
score=if(is_admin, 80, 40)
Optional Arguments
entity
Syntax: entity=<field>
Description: Field containing the entity to score (e.g., user, src_ip, src_host)
factor
Syntax: factor="<description>"
Description: Human-readable description of the risk factor
weight
Syntax: weight=<float>
Description: Override the global risk weight for this specific risk assignment (0.0-1.0). If not specified, uses the system's global weight setting.
Examples
Basic: Assign static risk to failed logins
action=login status=failure
| risk score=10 entity=src_ip factor="Failed login attempt"Dynamic: Score based on event count
action=login status=failure
| stats count() as attempts by src_ip
| risk score=attempts*5 entity=src_ip factor="Multiple failed logins"Dynamic: Score based on field value
* | risk score=severity_level entity=user factor="Severity-based score"Conditional: Different scores based on conditions
action=login
| risk score=if(is_admin, 80, 40) entity=user factor="Admin access"Conditional: Complex scoring logic
*
| eval risk_points = if(failed_attempts > 10, 50, 0) +
if(hour < 6 OR hour > 22, 20, 0) +
if(is_admin=true, 15, 0)
| risk score=risk_points entity=user factor="Suspicious login pattern"Weight override: Reduce impact of specific rule
action=file_access
| risk score=30 entity=user factor="File access" weight=0.5High-risk file execution
file_hash=* hash_prevalence < 5
| risk score=50 entity=src_host factor="Rare file execution"Suspicious network activity
bytes_out > 100000000
| risk score=30 entity=src_ip factor="Large data transfer"After-hours access
* | eval hour = strftime(timestamp, "%H")
| where hour < 6 OR hour > 22
| risk score=20 entity=user factor="After-hours activity"Privilege escalation
action=privilege_escalation
| risk score=60 entity=user factor="Privilege escalation attempt"Lateral movement
action=login src_host!=dest_host
| risk score=40 entity=user factor="Lateral movement"Malware indicators with lookup
* | lookup threat_intel file_hash OUTPUT threat_level
| where threat_level="high"
| risk score=80 entity=src_host factor="Known malware execution"Anomaly-based scoring
* | eventstats avg(bytes) as avg_bytes by user
| where bytes > avg_bytes * 5
| risk score=25 entity=user factor="Anomalous data volume"Aggregate count with dynamic score
source_type=firewall action=blocked
| stats count() as blocked_count by src_ip
| where blocked_count > 100
| risk score=blocked_count/10 entity=src_ip factor="High block rate"Dynamic Score Expressions
The score parameter accepts full eval expressions:
| Expression Type | Example | Description |
|---|---|---|
| Literal | score=50 | Static integer value |
| Field reference | score=severity_level | Use field value as score |
| Arithmetic | score=count*5 | Math operations |
| Conditional | score=if(x>10, 80, 40) | If/else logic |
| Functions | score=min(count*10, 100) | Eval functions |
Clamping: Dynamic scores are automatically clamped to 0-100 range.
Weight Override
The optional weight parameter overrides the global risk weight for this specific risk assignment:
| risk score=50 entity=user weight=0.5 // Applies 50% weight
| risk score=80 entity=user weight=1.0 // Full weight
| risk score=30 entity=user // Uses global weight from settingsUse this to:
- Reduce impact of noisy rules during tuning
- Increase weight for high-confidence detections
- Fine-tune risk scoring per detection rule
Usage Notes
Cumulative scoring: Risk scores accumulate over time per entity.
Score range: Use 0-100 scale. Higher scores indicate greater risk.
Entity tracking: Specify entity field to track risk per user, host, or IP.
Risk decay: Scores decay over time based on system configuration.
Alerting threshold: Configure alert thresholds in Settings > Risk Scoring.
Factor descriptions: Provide clear descriptions for investigation context.
Global weight: The system-wide risk weight (configured in Settings) is applied to all scores unless overridden with weight=.
Risk Score Guidelines
0-20: Low risk - Informational 21-40: Medium risk - Suspicious activity 41-60: High risk - Likely malicious 61-80: Critical risk - Confirmed threat indicators 81-100: Severe risk - Active compromise
Migration from YAML risk_score
Previously, risk scores were set in YAML frontmatter:
# OLD (deprecated)
---
risk_score: 50
risk_entity: user
---Now, use the | risk command in your query:
# NEW
| risk score=50 entity=userThis approach is more flexible:
- Dynamic scores based on event data
- Conditional logic for context-aware scoring
- Weight overrides per rule