Skip to content

feat(soc-optimization-unified): soc-block-domain containment action - #1200

Merged
scottbrumley merged 2 commits into
mainfrom
feat/soc-block-domain
Oct 21, 2026
Merged

scottbrumley merged 2 commits into
mainfrom
feat/soc-block-domain

Conversation

@scottbrumley

@scottbrumley scottbrumley commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

New containment action soc-block-domain: blocks every domain on the issue at DNS (ThreatStop) and the web proxy (Zscaler) in one run. Ships shadowed for every actor. Appears under the issue Contain button via SOCFWPhaseActions, with no layout or playbook change.

Registry row (SOCFrameworkActions_V3) + indicator class + 15-min time-map entry. dispatch: all_applicable: both vendors, once per domain; target SOCFramework.Artifacts.Network.DNS.Query. The row carries no customer values and never needs editing.

Customer values: SOCFrameworkTenantConfig_V3 (tenant-only, never shipped in a pack, so upgrades can't overwrite it):

{ "ThreatStopv2": { "list_id": "<block list GUID>" },
  "Zscaler":      { "category-id": "<custom category>", "using": "<instance, optional>" } }

Missing list or value → that vendor skips: "not configured: set list_id for ThreatStopv2 in SOCFrameworkTenantConfig_V3".

SOCCommandWrapper (all opt-in per row; other actions unchanged):

Testing

Unit: suite reads the shipped row from the repo list, 9/9. 6 fail on main's wrapper; 3 pin the shipped row, the no-domain skip, and "config never overrides issue evidence". Existing suites: failure set identical to main (9 pre-existing detonate-file failures).

Gate: green; uploaded to deathstar (soc-optimization-unified 3.25.0).

Live on deathstar, executing the installed scripts against the real installed registry row on issue 1494850 with injected domains [evil-a, evil-b, evil-a(dup), ""]:

Case Result
No tenant config list 2 × skipped, not configured (each naming its value and the list)
Config list created, row as shipped (shadow) 4 simulated (2 domains × 2 vendors), nothing called
Shadow-off copy of the row + config 4 dispatched → integration_unavailable (no vendors on deathstar)
Config values reached the vendor calls list_id, category-id, using all present in the dispatched args
Contain button (SOCFWPhaseActions) listed: "block domain at DNS and web proxy", not available, no reachable vendor
Dataset rows one per vendor × domain, action_target = the domain

Regression (live, same method): 13-case wrapper matrix 13/13; all 11 real containment actions as analyst unchanged.

Not proven here: a real ThreatStop/Zscaler call. deathstar has neither integration.

Known v1 limits: target is Network.DNS.Query only (email-issue URLs aren't domain-extracted yet); no ThreatStop expires.

🤖 Generated with Claude Code

https://claude.ai/code/session_01X6z5STKWCdm3aN5XwxWpgz

New registry action that blocks domains at DNS (ThreatStop) and the web
proxy (Zscaler) in one run: dispatch all_applicable fans out to both
vendors, once per domain on the issue. Ships shadowed for every actor.
Surfaces under the issue Contain button via SOCFWPhaseActions.

Tenant facts (ThreatStop list_id, Zscaler category-id, optional
instance) are set on the action row, the same list PS edits to flip
shadow. Until set, each vendor skips with a reason naming the value.

SOCCommandWrapper:
- response branches may carry their own target_arg (ioc_domain vs url)
- required_args: skip a branch whose tenant config is empty, with reason
- action_target now reaches the dataset row; enrich_payload dropped it,
  so fanned-out rows could not say which target they acted on

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6z5STKWCdm3aN5XwxWpgz
@scottbrumley scottbrumley added the version:minor New content or playbook → x.N.0 label Oct 19, 2026
…ntConfig_V3

Customer-specific vendor values (ThreatStop list_id, Zscaler category-id
and instance) move out of the registry row into a tenant-only list,
SOCFrameworkTenantConfig_V3, keyed by vendor then arg. The list is never
shipped in a pack, so upgrades cannot overwrite it and the registry no
longer has to be edited (and detached) to configure an action.

The wrapper reads it only for actions that declare required_args, and
fills only args the registry ships as empty literals; an arg bound to
issue evidence is never overridden. Missing list or value: the vendor
skips with a reason naming the value and the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6z5STKWCdm3aN5XwxWpgz
@scottbrumley
scottbrumley merged commit a04f346 into main Oct 21, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

version:minor New content or playbook → x.N.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant