secopsctl:~$ docs

Catalog & status

The source of truth for what exists and how mature it is. Every surface carries a status; update it in the same commit that moves the surface forward. Design in ARCHITECTURE.md; product specifics in SOAR-DESIGN.md / SIEM-DESIGN.md.

Where the code is: surfaces register in internal/mirror/registry_{soar,siem}.go (playbooks: soar_playbooks.go; data_tables: datatables_surface.go); the product-neutral engine is internal/mirror/reconcile; live write-smokes are gated by SECOPS_SOAR_SMOKE/_WRITE (reconcile_smoke_test.go) for SOAR and SECOPS_SIEM_SMOKE/_WRITE (reconcile_smoke_siem_test.go) for SIEM.

Status legend

  Status Meaning
📐 designed spec’d, code not landed
🔨 built code lands
live-validated reads round-trip clean / a write smoke ran
🔒 read-only by choice write deliberately not run — RBAC/SSO/high-blast/routing
blocked Google API down
n/a

SOAR · control plane (reconcile) — auth: AppKey (reliable)

Surface Lane Identity Read Write Notes
webhooks reconcile identifier 🔨 full CUD; create is license-capped (engine surfaces it, smoke skips)
environments reconcile id 🔒 NoDelete (segregation unit — high blast); writes guarded, not run
networks reconcile id write smoke (RFC5737 throwaway)
tracking-lists reconcile id first write-loop proof (clone throwaway)
soc-roles reconcile id 🔒 RBAC — read-only
idp reconcile id(uuid) 🔒 SSO; id-from-body update closure — read-only
visual-families reconcile id write smoke; validates the wrapKey envelope
sla-definitions reconcile id 🔒 affects alert routing — read-only
case-stages reconcile id 🔒 wrapped list; UI-pollution — read-only
case-tags reconcile id 🔨 wrapped list; write smoke skips (no tag to clone)
close-root-causes reconcile id non-unique names → exercises the slug-collision fix
blacklists reconcile id model block-list; write smoke
playbook-categories reconcile id write smoke
playbooks reconcile (bespoke) name uuid rotates → key on name; whole-body save; SavePlaybook update-by-name verified

SOAR · imperative + raw

Surface Lane Status Notes
soar case list / get <id> operational read the reliable operational read path (AppKey), live read-validated. list (ListCaseCards; --status/--limit/--json) + get <id> (GetCaseFullDetails → case and its alerts, each with its --alert identifier for the mutate verbs); table or --json
soar case <verb> (assign/rename/stage/tag/untag/describe/importance/close/merge) imperative 🔨 the reliable operational case path (AppKey). 9 mutate verbs; swagger-verified bodies + unit test; dry-run validated, live mutation not exercised
soar push bulk-close imperative 🔨 queue bulk-close (ExecuteBulkCloseCase, AppKey) — pre-existing
soar legacy call <op> raw passthrough for integrations · jobs · ontology-mapping · permissions · settings · … (batch/bundle/selector)
soar pull/push connectors\|jobs\|grouping (modern) 🔨 pre-existing v1alpha pull + patch — not full reconcile

SIEM · control plane (reconcile) — auth: ADC/OAuth token

Surface Lane Read Write Notes
rules bespoke 🔨 🔨 YARA-L source + deployment state machine (two resources) — push rules-create/disable; not a single canonical body
reference_lists reconcile 🔨 typed, .txt+.yaml; NoDelete; engine = product-neutral
data_tables reconcile .csv+.yaml on the engine; push data_tables (create/update). Columns immutable after create; rows are wholesale destroy-and-replace (ReplaceDataTableRows). Not prune-eligible (whole-table delete is high-blast). Write smoke TestLiveReconcileDataTableWriteSmoke passed (create→update desc→replace rows→delete)
feeds reconcile 🔨(pull) 📐 secrets in settings; resolve assetNamespace(read) vs namespace(write) with a live smoke first
parsers reconcile 🔨(pull) 📐 versioned/immutable → Create + Delete only
dashboards reconcile 🔨(pull) 📐 native dashboards, charts as JSON; full CUD
curated / curated_rules read+toggle 🔨(pull) 📐 Google-managed → read + enable/disable/alerting + exclusions, not CUD
watchlists, rule_exclusions, forwarders, log_pipelines reconcile 📐 SDK present; wire where per-object CUD fits

SIEM · operational plane (query → act)

Domain Query Act Status Notes
events (UDM) query udm · search nl · stats 🔨 query udm · 📐 rest immutable telemetry — read-only
alerts alerts list/get alerts update/bulk (verdict/priority/status/comment) 📐 SIEM-native SDK built (GetAlerts/UpdateAlert/BulkUpdateAlerts). In practice operators read alerts as a field of the SOAR case (GetCaseFullDetails.alerts) — the reliable view
cases (SIEM-native, UUID) cases list/search/get (planned) 🔨 read · ⛔ API the SIEM-native v1beta/v1alpha collection returns intermittent 5xx/404 — a secondary unified view, not the working path. Operational case work runs on the reliable SOAR AppKey lane (next row) — same case, bridged by soarPlatformInfo.caseId. See SOAR-DESIGN
entities / IoCs entity summarize · iocs list 📐 enrichment — read-only

How to keep this current

When a surface advances: edit its row here and the relevant design doc in the same commit. A surface reaches only after a live read round-trips clean and (for writes) a gated smoke passed on an inert throwaway — see the build discipline in ARCHITECTURE.md §5. A row records what is blocked and why (which API, which error) so it can be retried, not silently forgotten.