Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nicolas344/Sentinel-SoftServe/llms.txt

Use this file to discover all available pages before exploring further.

The Actions API gives human operators control over the remediation actions proposed by Sentinel’s LangGraph agent. Once an incident reaches awaiting_approval status, an engineer can approve the action (executing it atomically), reject it (marking the incident failed), or postpone it (sending it back to analyzed for later review). All three endpoints require a Supabase JWT, and the caller’s identity is recorded in the approved_by field for audit purposes.

Allowed Commands

Sentinel enforces a strict command whitelist at execution time. The backend re-validates the command regardless of what is stored in proposed_action. The following command forms are accepted:
RuntimeAllowed commands
Dockerdocker restart <container>, docker logs <container>
Podmanpodman restart <container>, podman logs <container>
Kuberneteskubectl rollout restart deployment/<name> [-n <ns>]
Kuberneteskubectl delete pod <pod-name> [-n <ns>]
Kuberneteskubectl scale deployment/<name> --replicas=<0-10> [-n <ns>]
PostgreSQLpg_stat_activity <datname>
PostgreSQLpg_cancel_backend <datname>
PostgreSQLpg_terminate_backend <datname>
Shell metacharacters (;, &&, |, `, $(, >, <) are rejected in all kubectl commands.

POST /api/execute-action

Execute the proposed remediation action for an incident. The endpoint enforces atomic single-execution to prevent duplicate runs. Auth required: Yes
incident_id
string
required
UUID of the incident to act on.
command
string
required
The exact command to execute. Must match the incident’s proposed_action field character-for-character. Maximum 200 characters.
The command field must exactly match the proposed_action stored on the incident — no extra spaces, flags, or modifications. The backend validates the command against the whitelist independently, so even a copied proposed_action that somehow bypassed earlier checks will be rejected here.

Execution Flow

1

Verify incident status

Checks that the incident is in awaiting_approval. Returns 409 Conflict if not.
2

Verify command match

Compares command against the stored proposed_action. Returns 400 Bad Request if they differ.
3

Atomic DB claim

Performs a conditional UPDATE SET status = 'executing_solution' that only succeeds if the incident is still in awaiting_approval. Returns 409 Conflict if another process claimed it first. Records approved_by from the JWT.
4

Route and execute

Routes to the correct execution branch based on source_type and container_runtime:
  • PostgreSQL → psycopg2 direct connection
  • Kubernetes → kubectl subprocess (with optional K8S_PROXY_URL)
  • Podman → Docker SDK against the rootless Podman socket (PODMAN_HOST)
  • Docker → subprocess
5

Update and verify

On success: sets status to verifying and launches an async verification background task. On failure: sets status to failed immediately.

Response

incident_id
string
UUID of the incident that was acted on.
status
string
Resulting incident status: verifying on success, failed on execution error.
exit_code
integer
Process exit code. 0 on success. Common failure codes: 124 (timeout), 127 (binary not found).
stdout
string
Standard output from the command. For PostgreSQL commands, this is a JSON string containing query results.
stderr
string
Standard error output or error description.
friendly_message
string
Human-readable error summary, present only when status is failed. Suitable for display in the UI.
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "incident_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "command": "docker restart my-service"
  }' \
  https://sentinel-softserve.onrender.com/api/execute-action

POST /api/incidents//reject

Reject the proposed action, permanently closing the incident as failed. Use this when the proposed action is unsafe, incorrect, or no longer relevant. Auth required: Yes
incident_id
string
required
UUID of the incident.
comment
string
Optional reason for rejection. Maximum 500 characters. If omitted, defaults to "Acción rechazada por el ingeniero." The comment is prefixed with [RECHAZADO] and stored in action_error.
This endpoint is atomic: the UPDATE only proceeds if the incident is still in awaiting_approval. If it has already moved to another status, 409 Conflict is returned. The caller’s identity is recorded in approved_by.
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"comment": "Restart would cause data loss during active transaction"}' \
  https://sentinel-softserve.onrender.com/api/incidents/a1b2c3d4-.../reject

POST /api/incidents//postpone

Postpone the proposed action, returning the incident to analyzed status for later review. The proposed action and agent reasoning are preserved; the incident can be approved, rejected, or re-analyzed later. Auth required: Yes
incident_id
string
required
UUID of the incident.
comment
string
Optional reason for postponement. Maximum 500 characters. If omitted, defaults to "Acción pospuesta por el ingeniero." The comment is prefixed with [POSPUESTO] and stored in action_error.
This endpoint is atomic: the UPDATE only proceeds if the incident is still in awaiting_approval. Returns 409 Conflict if it has already moved. The caller’s identity is recorded in approved_by.
Unlike reject, postpone sets the status back to analyzed rather than failed, leaving the door open for a future approval or re-triage.
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"comment": "Maintenance window scheduled for 02:00 UTC — will action then"}' \
  https://sentinel-softserve.onrender.com/api/incidents/a1b2c3d4-.../postpone

Error Reference

Status CodeScenario
400command does not match proposed_action, or command fails whitelist validation
401Missing or invalid JWT
404Incident UUID does not exist
409Incident is not in awaiting_approval, or action was already claimed by a concurrent request

Build docs developers (and LLMs) love