Security alert disposition
Decide what an alert deserves before an analyst spends a minute on it.
SOC queues are mostly noise. The expensive part is the analyst minutes spent deciding that. Give the model the alert plus context and get a disposition, a severity and two yes/no facts you can act on.
Calibration matters here: 'contain 0.52 / investigate 0.37' is a different situation from 'contain 0.95', and the distribution tells you which one you are in.
The questions
What should happen to this alert?
How severe is this incident if the alert is real?
This alert represents genuine malicious activity.
The evidence indicates a credential or account has been compromised.
How quickly must someone act?
Acting on the answers
- true_positive below 0.25 and disposition close_benign: auto-close with the reasoning attached.
- credential_compromise above 0.7: force a password reset before anyone reads the ticket.
- Anything with confidence below 0.45: send to a human, and log it as a hard case for the next training round.
request
{
"state": {
"alert": {
"rule": "impossible_travel",
"description": "two interactive logins from distant locations within 20 minutes",
"evidence": "User j.okafor authenticated from Lagos at 08:02 UTC and from Frankfurt at 08:19 UTC. Both sessions used the corporate SSO with MFA. The Frankfurt session originated from a known corporate VPN egress IP. No privilege changes, no unusual data access in either session."
},
"context": {
"user_role": "sales engineer",
"travel_registered": false,
"vpn_in_use": true,
"prior_alerts_30d": 0
}
},
"questions": {
"disposition": {
"type": "choice",
"instructions": "What should happen to this alert?",
"criteria": {
"close_benign": "Expected, explainable activity; close without analyst time.",
"monitor": "Keep an eye on it; no action now.",
"investigate": "Warrants an analyst opening an investigation.",
"contain": "Contain the host or account immediately; do not wait for triage."
}
},
"severity": {
"type": "score",
"instructions": "How severe is this incident if the alert is real?",
"criteria": [
"Informational.",
"Low: limited scope, no sensitive data.",
"Medium: one account or host at risk.",
"High: privileged access or sensitive data exposed.",
"Critical: active, spreading, or business-critical systems."
]
},
"true_positive": {
"type": "noul",
"instructions": "This alert represents genuine malicious activity."
},
"credential_compromise": {
"type": "noul",
"instructions": "The evidence indicates a credential or account has been compromised."
},
"urgency": {
"type": "score",
"instructions": "How quickly must someone act?",
"criteria": [
"Whenever.",
"Within the shift.",
"Within the hour.",
"Right now."
]
}
}
}call it
import { loadEngine } from "nirnaya"; // the same call this site makes
const engine = await loadEngine(); // loads once, then cached by the browser
const answers = await engine.decide(
"{\"alert\":{\"rule\":\"impossible_travel\",\"description\":\"two interactive logins from distant locations within 20 minutes\",\"evidence\":\"User j.okafor authenticated from Lagos at 08:02 UTC and from Frankfurt at 08:19 UTC. Both sessions used the corporate SSO with MFA. The Frankfurt session originated from a known corporate VPN egress IP. No privilege changes, no unusual data access in either session.\"},\"context\":{\"user_role\":\"sales engineer\",\"travel_registered\":false,\"vpn_in_use\":true,\"prior_alerts_30d\":0}}",
{
"disposition": {
"type": "choice",
"instructions": "What should happen to this alert?",
"criteria": {
"close_benign": "Expected, explainable activity; close without analyst time.",
"monitor": "Keep an eye on it; no action now.",
"investigate": "Warrants an analyst opening an investigation.",
"contain": "Contain the host or account immediately; do not wait for triage."
}
},
"severity": {
"type": "score",
"instructions": "How severe is this incident if the alert is real?",
"criteria": [
"Informational.",
"Low: limited scope, no sensitive data.",
"Medium: one account or host at risk.",
"High: privileged access or sensitive data exposed.",
"Critical: active, spreading, or business-critical systems."
]
},
"true_positive": {
"type": "noul",
"instructions": "This alert represents genuine malicious activity."
},
"credential_compromise": {
"type": "noul",
"instructions": "The evidence indicates a credential or account has been compromised."
},
"urgency": {
"type": "score",
"instructions": "How quickly must someone act?",
"criteria": [
"Whenever.",
"Within the shift.",
"Within the hour.",
"Right now."
]
}
}
);
for (const a of answers) console.log(a.qid, a.answer, a.p);curl and Python target nirnaya_serve, the Jev-compatible server in the release; the browser snippet is exactly what this site does.