What Is SOAR?
HuntRule Team · · 10 min read

On this page
POST /devices/entities/devices-actions/v2?action_name=contain takes a CrowdStrike host off
the network. action_name=lift_containment puts it back. Both are one HTTP call against the
same endpoint, and that symmetry is the entire reason network containment is the easiest
response action to automate.
SOAR means security orchestration, automation and response. Vendors sell it as one product, which hides the fact that the three words carry very different amounts of risk. Orchestration is plumbing. Automation is a scheduling decision. Response is the part that can take a payroll run offline at 3am.
Splitting the acronym
Orchestration is calling other systems. Your platform holds credentials for the EDR, the IdP, the SIEM, the ticketing system and the CMDB, and it knows each one's schema and rate limits. This is unglamorous and it is where most of the value sits. An analyst who no longer opens six consoles to answer "is this host a domain controller" gets that time back on every alert.
Automation is doing the orchestrated thing without a human in the loop. It is a separate decision from orchestration. You can orchestrate everything and automate nothing, and plenty of working SOCs do exactly that for the first year.
Response is the subset of actions that change state outside the security stack. Isolating a host, disabling an account, blocking an IP at the perimeter, purging a message from every mailbox. A rollback does not undo these, because the user already missed the meeting.
Automating a broken triage process does not fix it. It runs the same wrong answers at a higher volume and a lower latency.
What automates cleanly
The safe list has a property in common: every action is read-only or trivially reversible.
Enrichment. Hash reputation, domain age, ASN ownership, asset owner, patch level. Watch the quotas. The VirusTotal public API is capped at 4 requests per minute and 500 per day, and it is explicitly not licensed for commercial workflows, so a naive per-alert lookup either throttles or breaches terms. Cache by hash for 24 hours.
Deduplication. Group by a stable key before anything else runs. Host plus source image plus calendar day kills most of the duplicate volume for endpoint rules.
Case creation and ticketing. Deterministic, and idempotent if you key on the dedupe hash.
Notification. Paging the on-call rota from the CMDB owner field, not a hardcoded channel that was correct in 2023.
Reversible containment. Defender for Endpoint isolation is
POST https://api.security.microsoft.com/api/machines/{id}/isolatewith a body of{"Comment": "...", "IsolationType": "Full"}, and the undo is the same URL with/unisolateand only aComment. Both are limited to 100 calls per minute and 1,500 per hour, a ceiling worth knowing before a noisy rule tries to isolate a subnet.
Enrichment carries almost no blast radius. Enrich thirty alerts wrongly and you have thirty alerts with bad context. Contain thirty hosts wrongly and you have an outage.
What should not be fully automatic
Disabling an account is the standard worked example, and it deserves the detail.
At 3am a credential access rule fires on a host. The account that triggered it is
svc-backup-prod. A playbook with no gate calls
PATCH https://graph.microsoft.com/v1.0/users/{id} with {"accountEnabled": false}, the
backup fleet loses its identity, and the failure surfaces four hours later as a restore that
cannot authenticate. Nobody is awake to correlate the two. The security team has performed
T1531 on its own estate.
The reversible cousin is worth reaching for first.
POST /users/{id}/revokeSignInSessions invalidates refresh tokens and browser session cookies
by resetting signInSessionsValidFromDateTime to now. It does not delete the account. It
forces a re-authentication. Two caveats from the Microsoft documentation change how you write
the playbook around it: there is a delay of a few minutes before tokens are actually revoked,
and it does not revoke sessions for external users, because those sign in through their home
tenant.
The on-premises equivalent has its own gap. Disabling an account in Active Directory does not claw back a Kerberos TGT that was already issued, and the default maximum user ticket lifetime is 10 hours. A playbook that disables an account and reports "contained" is overstating what happened.
Same reasoning applies to perimeter IP blocks (the address is often your own egress NAT), mailbox purges (discovery obligations), and process termination on a domain controller.
Playbooks are code, and nobody treats them like it
This is the part vendor material skips. A playbook is a program with network I/O, branching, credentials and side effects. It needs everything code needs.
Version control, so you can answer "what changed on Tuesday" when case volume halves overnight. Tests, including a dry-run mode that walks every branch against recorded API responses and asserts on the actions it would have taken. Error handling, because a 429 from VirusTotal and a 500 from the EDR need different behaviour. Timeouts on every call, because a playbook that hangs on enrichment never reaches its containment step.
Integrations break quietly. A vendor renames a JSON field from verdict to classification
in a minor API version. Your if result["verdict"] == "malicious" branch raises a KeyError,
or worse, your defensive .get("verdict", "clean") returns clean forever. The playbook
keeps running. The dashboard stays green. Every malicious hash scores benign, and you find out
during the incident the automation was supposed to prevent.
The test is not "does the playbook run". It is "when did this branch last execute". Instrument branch counters and alert when a branch that normally fires daily goes quiet.

A worked playbook
Reconstructed pseudo-code for an LSASS handle alert (T1003.001), the kind fired by Sysmon
Event ID 10 with TargetImage of lsass.exe and a GrantedAccess value such as 0x1010 or
0x1410. Note where it stops on its own and where it stops for a person.
playbook: credential-access-lsass-handle
trigger: rule HR-WIN-LSASS-HANDLE (Sysmon EID 10, TargetImage endswith lsass.exe)
1. dedupe
key = sha256(host_id + SourceImage + calendar_day)
if open case with same key -> append event, exit.
2. enrich (read-only, parallel, 30s timeout each, failures are non-fatal)
EDR process tree for SourceProcessId, signer, first-seen-in-org
VT hash reputation, 24h cache, skip on 429 and record skipped=true
IdP accounts with sessions on this host in the last 8h
CMDB host role, owner, criticality, account_type for each account
3. decide
signer in org_allowlist AND SourceImage in approved_tooling
-> close as expected, tag, exit.
VT skipped OR CMDB unreachable
-> queue for tier 1 with a partial-enrichment banner, exit.
signer unsigned OR first_seen_in_org < 7d OR host.role == "domain_controller"
-> continue to 4.
otherwise
-> queue for tier 1, exit.
4. automatic, reversible only
EDR POST /api/machines/{id}/isolate {"Comment":"<case>","IsolationType":"Full"}
IdP POST /users/{upn}/revokeSignInSessions for each account from 2
collect volatile data: process list, netstat, autoruns, scheduled tasks
open Sev 2 case, page IR on-call
record every call: endpoint, status code, response id
5. HUMAN GATE (no timeout, no auto-approve on expiry)
proposed: disable {upn}, force password reset
shows: account_type (human | service | managed_identity),
CMDB owner, hosts this account authenticated to in 24h,
blast radius if disabled
requires: one approval from IR on-call
if account_type != "human": two approvals, one from the service owner
6. on approval
PATCH /users/{id} {"accountEnabled": false}
write action, actor, approver, timestamp and raw response to the caseStep 3's second branch is the one people leave out. A playbook that treats a failed enrichment as a clean result is worse than one with no enrichment at all, because the analyst trusts the banner-free case.
Step 5 has no timeout escalation on purpose. "Auto-approve if nobody responds in 15 minutes" is a human gate on paper and full automation in practice, because the 3am case is exactly the one nobody responds to. What belongs above that gate and what belongs below it is decided in the detection playbook the automation implements.
Detect your own automation
Your SOAR service account is a privileged identity that performs destructive actions on a schedule. Monitor it like one. A burst of Windows event 4725 from the automation account means either a real campaign or a playbook stuck in a loop, and both need waking someone.
title: Account disabled by SOAR service account
name: account_disabled_by_soar
status: experimental
description: Records account disable actions performed by the automation service account.
logsource:
product: windows
service: security
detection:
selection:
EventID: 4725
SubjectUserName|startswith: 'svc-soar'
condition: selection
falsepositives:
- Scheduled joiner-mover-leaver automation sharing the same service account
level: informational
tags:
- attack.impact
- attack.t1531That rule alone is noise. Pair it with a correlation so only the burst pages anyone.
title: Burst of automated account disables
status: experimental
correlation:
type: event_count
rules:
- account_disabled_by_soar
group-by:
- SubjectUserName
timespan: 10m
condition:
gte: 5
level: highWhat it catches: a runaway playbook, a compromised SOAR credential, and an approval gate that somebody removed to clear a backlog. What it misses: the single wrong disable, which is the common case and which no threshold finds. It also misses anything the SOAR does through a different identity, so pin the service account naming convention before deploying this. Known false positive: HR offboarding batches, which look identical. Apply the same pattern to isolation actions, with the threshold set below the platform's own rate limit.
Automation amplifies detection quality in both directions
A rule that fires 40 times a day at a 90 percent false positive rate is a nuisance in a queue. Somebody closes 36 cases and grumbles. Wire that rule to automatic host isolation and it is 36 wrongful isolations a day, which is a service desk incident, an executive question, and a lasting loss of trust in the security team's ability to touch production.
The prerequisite for SOAR is not the platform. It is detection content with a known false positive rate, measured per rule, over weeks of production data. Until you have that number for a rule, that rule gets enrichment and case creation and nothing else.
Summary
SOAR is three capabilities sold as one. Orchestration and enrichment automate cleanly and carry almost no blast radius. Response actions split into reversible ones you can automate behind a rate limit and irreversible ones that need a human approval gate with no timeout escape hatch. Playbooks are code and rot like code, silently, so version them, test every branch and alert when a branch stops firing. A noisy rule with an automated response is worse than a noisy rule alone.
Technique | ID | Where it appears |
|---|---|---|
OS Credential Dumping: LSASS Memory | T1003.001 | The alert the worked playbook responds to |
Valid Accounts | T1078 | The service account the playbook nearly disables |
Account Manipulation | T1098 | Changes to the SOAR service account's own privileges |
Account Access Removal | T1531 | What an ungated disable action does to your own estate |
Events to collect before you automate anything that touches identity:
Windows Security 4624 Successful logon (which accounts were live on the host)
Windows Security 4672 Special privileges assigned to new logon
Windows Security 4720 User account created
Windows Security 4725 User account disabled
Windows Security 4728 Member added to security-enabled global group
Sysmon 10 ProcessAccess, TargetImage lsass.exe
Entra ID SignInLogs + AuditLogs (Disable account, Revoke sessions)
EDR audit trail isolate / unisolate actions with actor and case referenceIdentity is where ungated automation does the most damage, so it is where the detection content has to be strongest first. Browse the identity rules at /rules?domain=identity, or work through the whole catalog at /rules.
Related articles

What Is Event Correlation in SIEM?
Windows Security event 4625 on its own is a typo. Thirty of them against thirty different account names from one source address in fifteen minutes, followed by a 4624 from that same address, is a…
2026-04-06 · 10 min read

What Is Log Normalization in SIEMs?
Sysmon calls it Image. Windows Security event 4688 calls it NewProcessName. Microsoft Defender for Endpoint splits the same thing into FolderPath and FileName. All three describe one executable…
2026-02-26 · 8 min read

What Is UEBA?
Microsoft Sentinel's BehaviorAnalytics table stores an integer called InvestigationPriority, scored 0 to 10, where 0 is benign and 10 is highly anomalous. That integer is the whole promise and the…
2025-08-06 · 9 min read