Core Concepts
Risks
The Risk Ops Board turns each company attack path into a tracked risk with a state machine, priority score, and lifecycle audit trail. Hunt, accept residual, escalate, or schedule a re-hunt — the loop closes back into coverage.
Overview
A risk in CraftedSignal is a company attack path with state. The threat model declares what the attacker could do; the Risk Ops Board tracks what you are doing about each one.
Every accepted attack path becomes a risk. Each risk carries a priority score, a coverage percentage, a state, and a full audit trail of every transition. The Risks page is where analysts triage, hunt, and close out exposure — and where the threat feed surfaces new candidates as briefs land.
Risks live at /dashboard/threat-model/risks. The drawer opens on row click.
The state machine
Every risk moves through a deterministic lifecycle. Each transition is recorded in the lifecycle timeline with the actor, timestamp, and reason.
| State | Meaning |
|---|---|
suggested | Generated by the threat model or feed bridge, awaiting review |
accepted | An analyst has approved the risk for investigation |
hunting | A hunt anchored to this risk is running |
evidence_gathered | Hunt completed; an evidence summary is attached |
mitigated | A detection rule was promoted from the hunt; the risk is covered |
active_threat | Evidence indicates ongoing exploitation — escalate to IR |
residual_accepted | Risk acknowledged with no further action |
rejected | Terminal — the risk does not apply |
Legal transitions
suggested→acceptedorrejectedaccepted→hunting,residual_accepted, orrejectedhunting→evidence_gathered(or back toacceptedto pause)evidence_gathered→mitigated,active_threat, orresidual_acceptedmitigated→hunting(when a scheduled re-hunt fires)active_threat→huntingorresidual_acceptedresidual_accepted→hunting(analyst reopens)rejectedis terminal
State pills in the drawer use a fixed color scheme: blue (hunting), amber (evidence_gathered), emerald (mitigated), red (active_threat), zinc (residual_accepted), slate (default).
Priority
Each risk carries a 0–100 priority score. The board sorts by priority descending so the most urgent risks surface first.
priority = severity × likelihood × (1 − coverage) × staleness × scale
- Severity and likelihood are declared on the risk (low = 0.25, medium = 0.5, high = 0.75, critical = 1.0).
- Coverage is the fraction of attack-path steps detected by at least one rule. A risk with no rules pinned to any step has coverage 0; a risk with full per-step coverage has coverage 1.
- Staleness boosts risks that haven’t been hunted recently. Capped at 3× — a risk that has never been hunted always sits at the maximum boost.
- The scale factor normalizes the worst case (critical × critical × fully uncovered × never hunted) to 100.
Priority recomputes:
- On every load of the Risks page (rate-limited to once per minute per company).
- Whenever a detection’s MITRE techniques change (auto-rebinds coverage edges).
- Whenever a hunt is promoted to a rule (the new edge re-anchors the risk).
Coverage
Coverage links detection rules to risks via the detection_threats edge table. Every edge carries a source so you can tell automated coverage from analyst-driven coverage:
| Source | When it’s written |
|---|---|
promoted_from_hunt | A hunt query graduated into a detection. Confidence = 100. |
auto_technique_match | A detection’s MITRE techniques overlap with steps on the risk. Confidence = matched-steps ÷ total-steps × 100. |
manual | Reserved for analyst-driven linking. |
Auto-matched edges refresh whenever a detection’s technique list changes. Hunt-promoted and manual edges are preserved across recomputes — analyst intent always wins over the heuristic.
Candidates
The threat feed turns into risks via the Candidates tab at /dashboard/threat-model/candidates. When a brief is highly relevant to your tenant — a relevance score of 75+ or a watchlist match — the platform creates a risk_candidate with proposed severity, likelihood, and a list of MITRE techniques pulled from the brief.
Each candidate shows:
- The brief title, threat actor (when resolved), and rationale (relevance score, watchlist match, technique overlap).
- The proposed severity and likelihood, derived from brief severity plus relevance.
- An existing risk match, when the candidate’s techniques overlap ≥50% with a path you already have.
Three actions:
- Accept — creates a new risk in
acceptedstate with the proposed fields. - Dismiss — drops the candidate without creating a risk.
- Merge into existing — when an existing risk match is offered, the brief is linked to the existing risk and the candidate is closed.
The bridge runs as a child workflow of the threat-feed sync. Candidates land in the Candidates tab as briefs are ingested; nothing happens to your live risks until an analyst accepts.
The drawer
Click any row on the Risks page to open the drawer. It shows:
- State pill (color-coded as above) and priority badge (0–100).
- Severity / likelihood and hunts run count.
- Evidence summary — populated automatically when a hunt completes against this risk.
- Lifecycle timeline — every state transition with who fired it and why.
- Actions (only the ones legal from the current state are shown):
- Hunt this risk — creates a new hunt anchored to the risk and transitions to
hunting. - Accept residual — prompts for a note, then transitions to
residual_accepted. - Mark as active threat — for risks in
evidence_gathered, captures escalation context and transitions toactive_threat. - Schedule re-hunt now — for risks in
mitigated, immediately fires a fresh hunt.
- Hunt this risk — creates a new hunt anchored to the risk and transitions to
Hunting from a risk
When you click Hunt this risk, the platform creates a new hunt with:
- Title
"Hunt: <risk name>"and a hypothesis pointing back to the risk. CompanyAttackPathIDset to the risk ID — the hunt is anchored.- All active SIEMs selected by default (override on the new-hunt form if needed).
The hunt detail page renders a Covers kill chain card showing every step on the risk, with crosshairs on the steps the hunt is investigating and shields on steps already covered by production rules.
The hunt proposer also sources from accepted risks. Risk-anchored hypotheses are ranked by the underlying risk’s priority, so the suggested hunts at the top of /dashboard/hunts are the ones the model says you should run next.
Re-hunt
When a risk is promoted to mitigated (a hunt graduated into a rule), the platform schedules a re-hunt 90 days out. The clock is stored as cap_next_review_at on the risk; a Temporal cron transitions the risk back to hunting and creates a fresh hunt at the scheduled time.
You can also re-hunt manually from the drawer’s Schedule re-hunt now action — useful when threat intel surfaces a new variant of the same TTP.
Auto-accept
Risks generated with severity critical — or severity high with likelihood high or critical — are auto-accepted on creation. They land in the accepted state with reviewed_by = "auto-accept:severity" so they flow straight into the hunt queue. Less severe risks stay in suggested for analyst review.
This is intentional and not configurable per-tenant: the model already weighs severity heavily, so paths the model considers extreme need to be visible to hunters immediately.
Routes
| Route | Purpose |
|---|---|
GET /dashboard/threat-model/risks | Risks list, filterable by state and coverage view |
GET /dashboard/threat-model/risks/{id}/drawer | Drawer partial (HTMX) |
POST /dashboard/threat-model/risks/{id}/hunt | Create hunt + transition to hunting |
POST /dashboard/threat-model/risks/{id}/accept-residual | Transition to residual_accepted |
POST /dashboard/threat-model/risks/{id}/mark-active-threat | Transition to active_threat |
POST /dashboard/threat-model/risks/{id}/schedule-rehunt | Re-hunt a mitigated risk |
GET /dashboard/threat-model/candidates | Pending risk candidates from the feed |
POST /dashboard/threat-model/candidates/{id}/accept | Promote candidate to risk |
POST /dashboard/threat-model/candidates/{id}/dismiss | Dismiss candidate |
Related
- Threat Model — how attack paths are declared and weighted.
- Hunts
— the action arm for risks in
accepted,hunting, ormitigated. - Threat Feed — where candidates originate.
- Threat Actors — the catalog the bridge enriches briefs against.