Skip to content

P7b-1: match customer threat-intel lists and rank matched findings - #37

Merged
therandomsecurityguy merged 1 commit into
mainfrom
dac/predictive-p7b-ioc-matching
Oct 26, 2026
Merged

therandomsecurityguy merged 1 commit into
mainfrom
dac/predictive-p7b-ioc-matching

Conversation

@therandomsecurityguy

Copy link
Copy Markdown
Owner

Summary

Predictive security roadmap P7b-1 (IOC matching) under the agreed defaults: AWS-native + customer-supplied lists, DynamoDB store, ranking factor, deferring TTP mapping + emulation (P7b-2). 35 files, +1299/−48.

Store & parsing (packages/risk-engine/src/threat-intel.ts)

  • ThreatIndicators — one row per indicator with a TTL (freshness is the TTL; a dropped indicator expires by itself), batch writes, bounded batch reads
  • List parsing: one indicator per line, # comments, IPs v4/v6 + 12-digit accounts, dedupe, cap with counted invalid lines
  • pathIndicators() — the fact join the runner uses: anomaly source_ip, trusted ExternalAccount account id

Importer — threat-intel-import runtime command, CronJob suspended by default on the rule-runner service account; imports plain S3 lists. No internet: lists are account-owned objects; AWS's managed reputation lists need no import (GuardDuty applies them — RULE-018/029 already consume the findings).

Ranking — a match adds a flat +10 threatIntelContribution (additive like exploitability: a fact, not a proportional strength); issues record threatIntelMatches, the issue page shows a "Threat intelligence" card, refresh clears matches whose indicator is gone, lookup failures score without it and log. No auto-ticketing until /rules/quality shows measured precision (P6 policy); risk:plan is unaffected (no store to read, never claims a match).

Infra — TF creates the table (TTL, deletion protection, CMK), grants the rule-runner role access + s3:GetObject on threat_intel_list_bucket when set; URIs/table/TTL flow through helm_values.config; chart gains threatIntelImport.*, config envs, schema entries, and the threat-intel-import egress component.

Why this is safe

  • Engine stays read-only (the importer writes only its own table); no new outbound network path.
  • Matches are transparent (metadata + card) and cannot ticket; invalid/absent data degrades to "no match".
  • Lockfile updated for the new workspace (P7a's lesson applied up front).

Test plan

  • npx jest --runInBand — 19 projects / 1775 tests passed (new: parsing/validation/join, store TTL/retry/dedupe, importer summary + failure, runner match + tolerant failure, scoring bonus, runtime validation/dispatch, UI card)
  • npm run typecheck; full workspace lint; npm run format:check
  • npm run ci:build; npm run package:lambdas && npm run smoke:lambdas
  • terraform fmt -check; testdata gains threatIntelImport.image; Deployment modules CI validates schema + render

Predictive security roadmap P7b, first slice (IOC matching) under the
agreed defaults: AWS-native + customer-supplied lists, DynamoDB store,
ranking factor, curated mapping and graph-only emulation deferred to
P7b-2.

- ThreatIndicators store (risk-engine): one row per indicator with a
  TTL — freshness is the TTL, so a dropped indicator expires by itself —
  batch writes and batched, bounded reads; list parsing (one indicator
  per line, '#' comments, IP v4/v6 and 12-digit accounts, dedupe, cap
  with counted invalid lines); and pathIndicators(), the fact join the
  runner uses (anomaly source_ip, trusted ExternalAccount account_id).
- threat-intel-import (runtime command; CronJob suspended by default,
  rule-runner service account): imports plain S3 lists into the store.
  No internet: the lists are account-owned objects, and AWS's managed
  reputation lists need no import because GuardDuty applies them (their
  findings already feed RULE-018/RULE-029).
- Ranking: a match adds a flat +10 threatIntelContribution to the risk
  score (additive like exploitability — a fact about the path, not a
  proportional strength), the issue records threatIntelMatches and the
  issue page shows a "Threat intelligence" card; refresh clears matches
  whose indicator is gone; lookup failures score without it and log.
  No auto-ticketing until /rules/quality shows measured precision.
- Infra: Flash (Terraform) creates the ThreatIndicators table (TTL,
  deletion protection, CMK), grants the rule-runner role full access to
  it and s3:GetObject on threat_intel_list_bucket when set; the URIs,
  table name, and TTL flow through helm_values.config; chart gains
  threatIntelImport.*, config envs, schema entries, and the
  threat-intel-import egress component.

Why this is safe: read-only for the engine (the importer only writes its
own indicators table); no new outbound network path; matches are
transparent (metadata + card) and cannot ticket; invalid/absent data
degrades to "no match".
@therandomsecurityguy
therandomsecurityguy merged commit 89a57a2 into main Oct 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant