Skip to main content

SOC and AI-SDR

The SOC and AI-SDR screen lets you follow the detections of the platform, issue typed containment orders and approve or reject them, seal and export the evidence of an incident with its chain of custody, reconcile the side effecting calls whose outcome is unknown, and read the catalog of allowed reactions. Portal path: /security/soc, menu Security and governance > SOC and AI-SDR. It is used by SOC analysts (soc_analyst), security officers and tenant administrators during an incident, and by auditors who read the evidence.

What the screen shows​

The screen (Soc in portal/src/screens/security-kit.tsx) has five tabs.

  • Orders: table Containment orders ("Typed reactions only, never a command."), read from GET /v1/soc/orders (50 rows), columns Reaction, Target type, Target, Mode (manual or automatic), Status (applied, pending_approval, rejected), Blast radius, Requested by, Approved by, Switch state (kill_switch.observed_state). Filters: Status and Incident. A click on a row opens the order loaded from GET /v1/soc/orders/{order_id}, with its kill switch and receipts.
  • Detections: table Detections, read from GET /v1/soc/detections (50 rows), columns Kind, Source, Severity, Confidence, Incident, Time. Filters: Incident and Kind. Detections come from the guards, the DLP, the runtime and the webhooks.
  • Evidence: a picker Incident with Apply, then a badge Chain valid or Chain invalid, the sealed records (Sequence, Kind, Content hash, Sealed by, Sealed at) and the custody log (Sequence, Action, Actor, Hash, At). "Each read is a custody entry." Below, two forms: Seal evidence and Export evidence.
  • Transactions: table read from GET /v1/soc/transactions, columns Transaction, Idempotency key, Run id, Status, Updated. Filters: Status (in_flight, committed, failed, interrupted, reconciled) and Run id.
  • Catalog: the JSON answer of GET /v1/soc/catalog: allowed reactions and their target types, detection kinds and playbooks, limits of the proportionality guard, and the roles of the SOC.

The form New order has these fields: Reaction (one of BLOCK_REQUEST, RATE_LIMIT, REQUIRE_APPROVAL, CANCEL_RUN, CANCEL_SUBAGENTS, SUSPEND_AGENT, SUSPEND_APPLICATION, DISABLE_TOOL, QUARANTINE_CONNECTOR, REVOKE_CREDENTIAL, DISABLE_MODEL_ROUTE, ISOLATE_NETWORK, TERMINATE_WORKLOAD, SUSPEND_IDENTITY, SUSPEND_TENANT, EMERGENCY_LOCKDOWN), Target type (for example agent), Target (for example invoice-assistant), Reason (required), Incident, Max blast radius, Confidence (for example 0.9).

Actions​

Button or actionWhat it doesAPI callRoles
New order (then Create)Sends a typed containment order. The Response Policy Engine answers applied, pending_approval (approval needed) or refuses it.POST /v1/soc/ordersButton: security_officer, tenant_admin; server: security_officer, soc_analyst, tenant_admin
Approve (row menu, order pending_approval)After a confirmation, approves and applies the order.POST /v1/soc/orders/{order_id}/approvesecurity_officer, tenant_admin
Reject (row menu, order pending_approval)Opens a form with an optional Reason, then Reject.POST /v1/soc/orders/{order_id}/rejectsecurity_officer, tenant_admin
Row click (Orders)Opens the order with its kill switch and receipts.GET /v1/soc/orders/{order_id}security_officer, tenant_admin, auditor, soc_analyst
Filter (Orders, Detections, Transactions)Applies the filters of the tab.GET /v1/soc/orders, GET /v1/soc/detections or GET /v1/soc/transactionssecurity_officer, tenant_admin, auditor, soc_analyst
Row click (Detections, Transactions)Shows the row.NoneSame
Apply (Evidence, picker Incident)Loads the sealed records with the state of the chain, and the custody log; each read adds a custody entry.GET /v1/soc/incidents/{incident_id}/evidence, GET /v1/soc/incidents/{incident_id}/custodysecurity_officer, tenant_admin, auditor, soc_analyst
Run (Seal evidence)Adds a sealed record (Incident, Kind, default note, Content JSON) to the evidence chain of the incident.POST /v1/soc/incidents/{incident_id}/evidenceForm: security_officer, tenant_admin; server: security_officer, soc_analyst, tenant_admin
Run (Export evidence)After a confirmation, exports the evidence and the custody chain of the Incident; a bundle holding a credential is refused.POST /v1/soc/incidents/{incident_id}/evidence/exportForm: security_officer, tenant_admin, auditor; server adds soc_analyst
Reconcile (row menu, transaction interrupted, failed or in_flight)Records the real outcome: Outcome committed or not_executed, Provider reference, Note.POST /v1/soc/transactions/{transaction_id}/reconcilesecurity_officer, tenant_admin
Catalog tab, RetryReads the catalog again.GET /v1/soc/catalogEvery user of the tenant

Roles​

The portal follows ROLES.socLead (security_officer, tenant_admin) for New order, Approve, Reject, Reconcile and Seal evidence, and ROLES.evidenceReaders (security_officer, tenant_admin, auditor) for Export evidence, from portal/src/lib/kit.ts; other users see "Requires one of these roles" instead of a form. The Control Plane (services/control-plane/src/eai/domains/soc/__init__.py, roles in services/control-plane/src/eai/domains/soc/catalog.py) decides:

GroupRolesRoutes
SOC_READERSsecurity_officer, tenant_admin, auditor, soc_analystlists, order detail, evidence, custody, export
SOC_ANALYST + SOC_LEADsecurity_officer, soc_analyst, tenant_adminnew order, seal evidence
SOC_LEADsecurity_officer, tenant_adminapprove, reject, reconcile

A soc_analyst (role of migration V161) may create orders and seal evidence through the API even though the portal hides these forms from it. Every refusal is audited as soc.access.deny, every read as soc.access. platform_admin passes every role check.

Typical tasks​

Contain an agent during an incident​

  1. Check the allowed reactions. Each reaction accepts only some target types. Tab Catalog. Expected result: the reactions and their targets, for example SUSPEND_AGENT on agent. If it fails: tenant_required means the account has no tenant.
  2. Issue the order. Tab Orders > New order: Reaction SUSPEND_AGENT, Target type agent, Target the agent name, Reason, Incident, then Create. Expected result: the message Created and a row applied or pending_approval. If it fails: containment_refused (HTTP 409) with the reasons of the Response Policy Engine (for example blast_radius_exceeded); target_not_allowed (HTTP 400) for a wrong target type.
  3. Have it approved when needed. A reaction above the manual limits or always reviewed waits for a second person. Another security_officer or tenant_admin opens the row menu > Approve. Expected result: the status applied and the name in Approved by. If it fails: separation_of_duties (HTTP 409) when the requester approves its own order; order_not_pending (HTTP 409) when it is already decided.
  4. Watch the kill switch. The order creates a kill switch whose observed state must converge. Read Switch state, then open the Kill Switch screen. Expected result: SUSPENDED_VERIFIED. If it fails: see the Kill Switch page.

Seal and export the evidence of an incident​

  1. Seal a note. A sealed record is chained to the previous one by its hash. Tab Evidence, form Seal evidence: Incident, Kind note, Content {"summary": "..."}, then Run. Expected result: the result shows seq, content_sha256 and hash. If it fails: not_found with incident means an unknown incident id.
  2. Check the chain. Enter the incident in Incident and click Apply. Expected result: Chain valid and the new record in the table. If it fails: Chain invalid means a record was altered; keep the export and follow the SOC runbook.
  3. Export. Form Export evidence, Incident, Run, then accept the confirmation. Expected result: the bundle with the items, both chains and the custody log. If it fails: secret_detected (HTTP 422) means a record holds a credential; the export is refused and a secret_leak detection is recorded.

Reconcile an interrupted transaction​

  1. Find it. Tab Transactions, Status interrupted, Filter. Expected result: the side effecting calls whose outcome is unknown. If it fails: an empty table means nothing waits for reconciliation.
  2. Check at the provider. Only the provider knows whether the call ran. Look up the call with its idempotency key at the provider. Expected result: you know whether it was committed.
  3. Record the outcome. Row menu > Reconcile, Outcome committed (with Provider reference) or not_executed, Note, then Reconcile. Expected result: the message Done and the status reconciled. If it fails: transaction_not_reconcilable (HTTP 409) when the transaction no longer waits for a reconciliation.

Troubleshooting​

SymptomCauseFix
forbidden (HTTP 403) with required_rolesYour roles are not in the SOC group of the route; the refusal is audited (soc.access.deny).Ask for soc_analyst, security_officer or tenant_admin.
"Requires one of these roles" instead of a formThe portal hides the form from your roles.Use an account with one of the listed roles.
containment_refused (HTTP 409)The Response Policy Engine refused the order (reaction not allowlisted, target not allowed, blast radius above Max blast radius).Read reasons, then narrow the target or raise the limit.
unknown_reaction (HTTP 400)The reaction is not in the allowlist.Choose a reaction from the list.
recover_requires_workflow (HTTP 422)RECOVER is not an order.Use Request recovery on the Kill Switch screen.
separation_of_duties (HTTP 409)The requester cannot approve their own request.Ask another security_officer or tenant_admin.
order_not_pending (HTTP 409)The order is not waiting for an approval.Refresh the table.
secret_detected (HTTP 422) on exportThe export contains a credential.Remove the credential from the evidence source, then export again.
transaction_not_reconcilable (HTTP 409)The transaction is not waiting for a reconciliation.Refresh the table.
Chain invalidA sealed record or a custody entry no longer matches its hash.Keep the evidence, open an incident and follow the SOC runbook.