Kill Switch
The Kill Switch screen lets you compare the desired state of every security kill switch with the state observed on the target, verify a switch again, and lift it through the four eyes recovery: a request, two distinct approvals, then a re-authorization of the target. Portal path: /security/kill-switch, menu Security and governance > Kill Switch. It is used by security officers and tenant administrators after a containment order, and by SOC analysts who follow the convergence.
What the screen shows
The screen (KillSwitch in portal/src/screens/security-kit.tsx) starts with the hint "A switch converges when the observed state matches the desired one. Network isolation and workload termination wait for a signed receipt.", then two tables.
Kill switches, read from GET /v1/soc/kill-switches:
| Column | Content |
|---|---|
| Reaction | Reaction of the containment order, for example SUSPEND_AGENT. |
| Target type, Target | What the switch holds. |
| Desired state | SUSPENDED while the switch holds, RELEASED after the recovery. |
| Observed state | State measured on the target, for example SUSPENDED_VERIFIED or VERIFICATION_FAILED. |
| Converged | Computed by the portal: yes when SUSPENDED meets SUSPENDED_VERIFIED, or RELEASED meets RELEASED. |
| Last receipt | Identifier of the last receipt. |
| Last verified | Date of the last verification. |
Filter State: active (switches still SUSPENDED, the default of the API) or all. Switches appear when a containment order is applied.
Recoveries, read from GET /v1/soc/recoveries: columns Kill switch, Reason, Status (pending, approved, recovered, rejected), Requested by, Approved by (list of the approvers), Reauthorized by. Filter Status. "Request a recovery on an active kill switch: two distinct approvers are required."
A click on a row of either table shows the row in a side panel.
Actions
| Button or action | What it does | API call | Roles |
|---|---|---|---|
| Verify signature (row menu of a switch) | Runs the verification of the switch again and shows the answer in a side panel; audited as soc.kill_switch.verify. | POST /v1/soc/kill-switches/{switch_id}/verify | Menu: security_officer, tenant_admin; server adds soc_analyst |
Request recovery (row menu, switch SUSPENDED) | Opens a form with Reason (required, 3 characters at least), then Request recovery. | POST /v1/soc/recoveries | Menu: security_officer, tenant_admin; server adds soc_analyst |
Approve (row menu, recovery pending) | Opens a form with an optional Reason, then Approve. The recovery becomes approved at the second distinct approver. | POST /v1/soc/recoveries/{recovery_id}/approve | security_officer, tenant_admin |
Reauthorize (row menu, recovery approved) | After a confirmation, releases the switch, re-evaluates the target through the policy decision point and restores it (a suspended agent is resumed); the answer is shown in a side panel. | POST /v1/soc/recoveries/{recovery_id}/reauthorize | security_officer, tenant_admin, and one of the approvers |
| Filter | Applies the State or Status filter. | GET /v1/soc/kill-switches (query state) or GET /v1/soc/recoveries (query status) | security_officer, tenant_admin, auditor, soc_analyst |
| Refresh icon of a table | Reads the list again. | Same routes | Same |
REVOKE_CREDENTIAL stays in force after the recovery: the API key remains revoked and a new key must be issued.
Roles
The portal shows the row actions to ROLES.socLead (security_officer, tenant_admin, portal/src/lib/kit.ts). The Control Plane (services/control-plane/src/eai/domains/soc/__init__.py and services/control-plane/src/eai/domains/soc/recovery.py) requires:
- reading both tables:
security_officer,tenant_admin,auditororsoc_analyst; - verify and request a recovery:
security_officer,soc_analystortenant_admin; - approve and reauthorize:
security_officerortenant_admin.
The recovery is four eyes: the requester cannot approve, the two approvals come from two distinct people, and only one of them can reauthorize. platform_admin passes every role check.
Typical tasks
Check that a containment holds
- List the active switches. Filter State
active, Filter. Expected result: the switches stillSUSPENDED. If it fails:forbidden(HTTP 403) means your roles are not readers of the SOC. - Read the convergence. Converged says whether the target really applied the switch. Look for Converged No. Expected result: every switch converged. If it fails: an
ISOLATE_NETWORKorTERMINATE_WORKLOADswitch waits for a signed receipt from the cluster; check the cluster side. - Verify again. Row menu > Verify signature. Expected result: a side panel with the new Observed state and Last verified. If it fails:
not_foundmeans the switch was removed; refresh the table.
Lift a kill switch after the incident
- Request the recovery. The recovery is the only way back:
RECOVERis not an order. Row menu of the switch > Request recovery, Reason, then Request recovery. Expected result: a new rowpendingin Recoveries. If it fails:recovery_already_open(HTTP 409) means a request is already pending or approved;kill_switch_not_active(HTTP 409) means the switch is no longerSUSPENDED. - Collect two approvals. Two people, both different from the requester, approve. Each one opens the row menu > Approve. Expected result: after the second, the status
approvedand two names in Approved by. If it fails:separation_of_duties(HTTP 409) for the requester;already_approved(HTTP 409) when the same person approves twice. - Reauthorize. One of the approvers releases the switch and lets the policy re-evaluate the target. Row menu > Reauthorize, accept the confirmation. Expected result: the status
recovered, Reauthorized by filled, and the switchRELEASED. If it fails:reauthorization_by_approver(HTTP 403) when you did not approve;reauthorization_denied(HTTP 403) when the policy decision point refuses the target;recovery_not_approved(HTTP 409) before the second approval.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
forbidden (HTTP 403) with required_roles | Your roles are not in the SOC group of the route. | Ask for security_officer or tenant_admin (or soc_analyst for the reads, verify and request). |
invalid_request (HTTP 400) with state | A State other than active or all. | Choose a value from the list. |
kill_switch_not_active (HTTP 409) | This kill switch is no longer active. | Refresh the table. |
recovery_already_open (HTTP 409) | A recovery request is already open for this kill switch. | Approve or follow the open request. |
recovery_not_pending (HTTP 409) | The recovery request is not waiting for an approval. | Refresh the table. |
separation_of_duties (HTTP 409) | The requester cannot approve their own request. | Ask two other people. |
already_approved (HTTP 409) | You already approved this request. | Ask another approver. |
recovery_not_approved (HTTP 409) | The recovery needs two distinct approvers before the re-authorization. | Wait for the second approval. |
reauthorization_by_approver (HTTP 403) | Only one of the approvers can re-authorize the target. | Ask an approver to click Reauthorize. |
reauthorization_denied (HTTP 403) | The policy decision point refused the re-authorization of the target. | Fix the policy or the target, then reauthorize again. |