soc-ai 1.5.1¶
soc-ai 1.5.1 is a review release. It contains 61 fixes. Each fix has a test that failed before the fix. The review covered the evidence gates, the Oracle redaction, the egress guard, the tools, the store, the installer, the CI and the console. The release ran on a live attack range and on a production grid before it shipped. CHANGELOG.md lists each change under 1.5.1.
Evidence gates¶
- A
resolutionmarker that the model writes no longer stores a real verdict as a pipeline failure. Each synthesis path removes the field. - A short wire string on the alert's own flow no longer grounds a verdict. Examples: an SMB file
named
alert, a four-letter RPC name. A whole word needs 5 characters. A substring needs 8 characters. - A hunt finding cannot cite a tool error, a duplicate-call stop or a prefetch hint as evidence.
- An alert with an attack class that matches a housekeeping template no longer settles as a false positive with zero tool calls. The investigator examines it.
- The origin-chain tool refuses a lookback of zero, a negative lookback, or a lookback over 30 days. It refuses before it can return the "self-originated" result.
Oracle redaction and the egress guard¶
- The web search and the crawler refuse an internal name that has a port. Examples:
dc01.corp.local:443,finance-pc:445. The targeted dispatch uses the same set of discovered hosts as the interactive tools. A model argument cannot disable the guard. - The Oracle sanitizer tokenises Windows computer names, NTLM server names and Kerberos principals.
- The sanitizer re-fangs
10[.]0[.]0[.]5andhxxp://before it matches. The sanitizer tokenises a learned internal host that recurs defanged in a runbook. The residue gate does not refuse it. - An
ORACLE_INTERNAL_SUFFIXESentry without a leading dot, or in upper case, now matches. - The Oracle client rejects a confidence that is NaN or out of range. The old code clamped it to 1.0.
- Each MCP tool call writes an audit row.
Store and migrations¶
- The startup migration chain runs in one transaction. A revision that fails leaves the store unchanged.
- The orphan check runs only when a revision runs. A store that already holds an orphan starts, with a warning.
- Migration 0052 adds three indexes. The bell read and the unread shadow-hit count use them. On a 383 MB production store the bell answers in about 40 ms.
Tools¶
- The pcap tool reports a tcpdump failure as an error. The old code reported "no packets matched". The capture window is at most 60 minutes. The ring-file scan is at most 100 files.
- The blocklist loader does not load a corrupt or empty feed file. The refresh validates a feed body before it replaces the live file. An empty feed does not read as clean.
- The backup archive has mode 0600. It does not contain the bootstrap credential.
- The webhook sender retries only after a connect failure. It does not retry after a read timeout. The receiver can have accepted the first request.
Hunting¶
- Role priors on the process and logon dimensions find the host role. These dimensions key on
host.name. The dossier keyed roles on the IP address. As a result, five of the nine shipped role priors were blind. - A host that sends no documents in the window is a collapsed-rate departure. The observation states that the sweep did not see the host in the window.
- A dimension that no plane on the grid carries reads as blind. It does not read as quiet.
- One lead starts one hunt. A click and a loop wake that arrive together start one agent.
- The auto-hunt loop reads past a page of leads that cite nothing.
- A hunt delete releases the lead and the fired condition that point at the hunt.
- The analyst can promote a reopened lead again.
- A hunt chat recovers after an unclean restart.
- An alert re-triaged as a false positive closes the lead that the alert formed. If other observations remain, the lead keeps them.
Console¶
- Clear on a stored API key or on the webhook URL asks for a confirmation click.
- A failed acknowledge, escalate or assign shows a red toast. The toast stays until you dismiss it.
- A failed group read shows a retry card. It does not show "No events in window".
?view=mineand the palette entry "My queue" open the Alerts screen on the Mine chip.- The Alerts screen stops the background poll when you leave it.
- The fitness chip and the full check do not grade a staged model. Apply the model first.
- Bell rows, investigation rows and sort headers work from the keyboard. A click on any part of a bell row opens the row.
- The lead page shows finished hunts, failed reads and stale hunt rows. The Hunt-again confirmation links the existing hunt.
- The Egress policy page lists MISP and the release check.
- The Data sources page reads "not configured" when a key is blank. The MaxMind row does not ask for a key. No command uses that key.
Installer and build¶
setup.shdoes not copy conf comments into.env. It quotes each value. It reads the port from the conf. It leaves the TLS key readable by the container.pydantic-ai-slim[openai]replaces the full provider set. The image has 80 fewer packages.- The
mcppin stays below version 2. The pins that had advisories move to fixed releases. A dependency audit job runs in CI. - A blank
SOC_AI_TLS_CERT,SOC_AI_TLS_KEYor API key reads as unset. soc-ai validatesLOG_LEVELat load.
Upgrade¶
- Start soc-ai. Migration 0052 runs at the first start. It adds three indexes. It changes no rows.
- Docker: the image rebuilds from the new lock file. Source install: run
uv syncbefore the restart.pip install -e . --no-depsdoes not update the pins. - Set
LOG_LEVELto a Python logging level name:DEBUG,INFO,WARNING,ERRORorCRITICAL. Any other value stops the start. - With
API_AUTH_REQUIRED=false, creating a user or changing a role needs an admin session. A password reset already needed one.
The full test suite runs in about 3 minutes with pytest -n 4 --dist loadfile.
Known limits¶
- Only
soc-ai priorsprints the reason a dimension is blind. The API and the console show the count. - The collapsed-rate analytic keeps firing for a host that left the estate. It stops when the baseline ages out, after 30 days at most.
- A role prior on a
host.namedimension measures only after the next profile rebuild.