Skip to content

REST API

L'API di SocTalk è un'app FastAPI. La sua superficie completa è generata dal codice come schema OpenAPI ed è servita sotto /api/ (l'ingress instrada /api/* verso l'API e tutto il resto verso la console web):

  • OpenAPI JSON: https://mssp.your-mssp.example/api/openapi.json
  • Swagger UI: https://mssp.your-mssp.example/api/docs
  • ReDoc: https://mssp.your-mssp.example/api/redoc

La superficie OpenAPI è la fonte di verità. Uno snapshot di essa è distribuito con questa documentazione all'indirizzo /openapi.json, e il catalogo sottostante è generato da quello schema — non può divergere dal codice.

Rigenerare il catalogo

Il catalogo degli endpoint è prodotto da npm run gen:api, che legge docs/public/openapi.json. Aggiorna prima lo schema dal codice dell'API:

bash
# in the soctalk repo
python scripts/dump_openapi.py <soctalk-docs>/docs/public/openapi.json
# in soctalk-docs
npm run gen:api

Tutto ciò che si trova tra i marcatori GENERATED viene sovrascritto; la prosa attorno ad esso è curata manualmente.

Catalogo degli endpoint

La colonna Auth è derivata dal guard require_role / require_tenant_role di ciascuna route. Un'etichetta session cookie significa che al handler è accettata qualsiasi sessione autenticata — ma i ruoli con ambito tenant sono comunque confinati ai propri dati tramite row-level security, quindi un tenant_admin vede solo le righe del proprio tenant anche su una route di tipo MSSP senza gating.

97 operations across 23 groups, generated from the OpenAPI schema (API version 0.1.0). Auth is derived from the route's require_role / require_tenant_role guards.

auth

MethodPathSummaryAuth
POST/api/auth/assume-tenantAssume Tenantsession cookie (login) / none
POST/api/auth/loginLoginsession cookie (login) / none
POST/api/auth/logoutLogoutsession cookie (login) / none
GET/api/auth/meMesession cookie (login) / none
POST/api/auth/password/changePassword Changesession cookie (login) / none

auth-admin

MethodPathSummaryAuth
POST/api/mssp/users/{user_id}/password/resetAdmin Resetsession — roles: mssp_admin / platform_admin

chat

MethodPathSummaryAuth
GET/api/chat/conversationsList Conversationssession cookie
POST/api/chat/conversationsCreate Conversationsession cookie
GET/api/chat/conversations/{conv_id}Get Conversationsession cookie
DELETE/api/chat/conversations/{conv_id}Delete Conversationsession cookie
POST/api/chat/conversations/{conv_id}/messagesPost Messagesession cookie
POST/api/chat/conversations/{conv_id}/messages/{msg_id}/confirmConfirm Actionsession cookie
POST/api/chat/conversations/{conv_id}/stopStop Conversationsession cookie

health

MethodPathSummaryAuth
GET/health/liveLivenone (public)
GET/health/readyReadynone (public)

internal-adapter

MethodPathSummaryAuth
GET/api/internal/adapter/checkpointGet Checkpointservice JWT (adapter token)
PUT/api/internal/adapter/checkpointPut Checkpointservice JWT (adapter token)
GET/api/internal/adapter/configFetch Configservice JWT (adapter token)
POST/api/internal/adapter/eventsIngest Eventsservice JWT (adapter token)
POST/api/internal/adapter/heartbeatHeartbeatservice JWT (adapter token)

internal-worker

MethodPathSummaryAuth
POST/api/internal/worker/runs/{run_id}/completeComplete Runservice JWT (worker token)
POST/api/internal/worker/runs/{run_id}/heartbeatHeartbeat Runservice JWT (worker token)
POST/api/internal/worker/runs/claimClaim Runservice JWT (worker token)

investigations-bridge

MethodPathSummaryAuth
GET/api/investigationsList Investigationssession cookie
GET/api/investigations/{investigation_id}Get Investigationsession cookie
POST/api/investigations/{investigation_id}/cancelPost Cancel Investigationsession — roles: analyst / mssp_admin / platform_admin
GET/api/investigations/{investigation_id}/eventsGet Eventssession cookie

ir-alerts

MethodPathSummaryAuth
GET/api/mssp/alertsList Alertssession — roles: analyst / mssp_admin / platform_admin

ir-integrations

MethodPathSummaryAuth
GET/api/mssp/tenants/{tenant_id}/integrationsGet Integrationssession — roles: mssp_admin / platform_admin
PATCH/api/mssp/tenants/{tenant_id}/integrationsPatch Integrationssession — roles: mssp_admin / platform_admin

ir-mssp

MethodPathSummaryAuth
GET/api/mssp/investigationsList Cases Msspsession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/investigations/{investigation_id}Get Case Msspsession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/investigations/{investigation_id}/eventsList Case Events Msspsession — roles: analyst / mssp_admin / platform_admin
PATCH/api/mssp/investigations/{investigation_id}/factsPatch Case Factssession — roles: analyst / mssp_admin / platform_admin
POST/api/mssp/investigations/{investigation_id}/messagesPost Analyst Messagesession — roles: analyst / mssp_admin / platform_admin

ir-proposals

MethodPathSummaryAuth
GET/api/mssp/proposalsList Pending Proposalssession — roles: analyst / mssp_admin / platform_admin
POST/api/mssp/proposals/{proposal_id}/approveApprove Proposal Routesession — roles: analyst / mssp_admin / platform_admin
POST/api/mssp/proposals/{proposal_id}/rejectReject Proposal Routesession — roles: analyst / mssp_admin / platform_admin

ir-tenant

MethodPathSummaryAuth
GET/api/tenant/investigationsList Cases Tenanttenant session (customer_viewer / tenant_admin)
GET/api/tenant/investigations/{investigation_id}Get Case Tenanttenant session (customer_viewer / tenant_admin)

l2-agent

MethodPathSummaryAuth
POST/api/agent/heartbeatHeartbeatL2 agent install token (bearer)
POST/api/agent/jobs:claimClaim JobL2 agent install token (bearer)
POST/api/agent/jobs/{job_id}/completeComplete JobL2 agent install token (bearer)
POST/api/agent/jobs/{job_id}/eventsPost EventL2 agent install token (bearer)
POST/api/agent/registerRegisterL2 agent install token (bearer)

legacy-stubs

MethodPathSummaryAuth
GET/api/analytics/ai-behaviorAnalytics Ai Behaviorsession cookie
GET/api/analytics/human-reviewAnalytics Human Reviewsession cookie
GET/api/analytics/kpisAnalytics Kpissession cookie
GET/api/analytics/outcomesAnalytics Outcomessession cookie
GET/api/analytics/summaryAnalytics Summarysession cookie
GET/api/auditAudit Listsession cookie
GET/api/audit/event-typesAudit Event Typessession cookie
GET/api/audit/investigation/{investigation_id}Audit Investigationsession cookie
GET/api/audit/statsAudit Statssession cookie
GET/api/events/streamEvents Streamsession cookie
GET/api/review/{review_id}Review Detailsession cookie
POST/api/review/{review_id}/approveReview Approvesession cookie
POST/api/review/{review_id}/expireReview Expiresession cookie
POST/api/review/{review_id}/rejectReview Rejectsession cookie
POST/api/review/{review_id}/request-infoReview Request Infosession cookie
GET/api/review/pendingReview Pendingsession cookie
GET/api/settingsSettings Getsession cookie

metrics-bridge

MethodPathSummaryAuth
GET/api/metrics/hourlyHourlysession cookie
GET/api/metrics/overviewOverviewsession cookie

mssp-analytics

MethodPathSummaryAuth
GET/api/mssp/analytics/heatmapHeatmapsession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/analytics/rankingRankingsession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/analytics/trendsTrendssession — roles: analyst / mssp_admin / platform_admin

mssp-dashboard

MethodPathSummaryAuth
GET/api/mssp/dashboard/open-by-tenantOpen By Tenantsession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/pending-reviewsPending Reviewssession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/repeated-iocsRepeated Iocssession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/stuck-investigationsStuck Investigationssession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/tenant-healthTenant Healthsession — roles: analyst / mssp_admin / platform_admin

mssp-tenant-branding

MethodPathSummaryAuth
PATCH/api/mssp/tenants/{tenant_id}/brandingUpdate Tenant Brandingsession — roles: mssp_admin / platform_admin

mssp-tenant-llm

MethodPathSummaryAuth
GET/api/mssp/tenants/{tenant_id}/llmGet Tenant Llmsession — roles: mssp_admin / platform_admin
PATCH/api/mssp/tenants/{tenant_id}/llmUpdate Tenant Llmsession — roles: mssp_admin / platform_admin
DELETE/api/mssp/tenants/{tenant_id}/llm/api-keyClear Tenant Llm Api Keysession — roles: mssp_admin / platform_admin

mssp-tenants

MethodPathSummaryAuth
GET/api/mssp/tenantsList Tenantssession — roles: analyst / mssp_admin / platform_admin
POST/api/mssp/tenantsCreate Tenantsession — roles: mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}Get Tenantsession — roles: analyst / mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:decommissionDecommission Tenantsession — roles: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:issue-agentIssue Agentsession — roles: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:resumeResume Tenantsession — roles: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:retryRetry Provisioningsession — roles: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:retry-installRetry Installsession — roles: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:suspendSuspend Tenantsession — roles: mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}/adapter-statusGet Tenant Adapter Statussession — roles: mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}/eventsList Eventssession — roles: analyst / mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}/external-siemGet Tenant External Siemsession — roles: mssp_admin / platform_admin
PATCH/api/mssp/tenants/{tenant_id}/external-siemUpdate Tenant External Siemsession — roles: mssp_admin / platform_admin
POST/api/mssp/tenants/onboardOnboard Tenantsession — roles: mssp_admin / platform_admin

public-tenant

MethodPathSummaryAuth
GET/api/public/mssp-by-slug/{slug}Mssp By Slugnone (public)
GET/api/public/scope-by-slug/{slug}Scope By Slugnone (public)
GET/api/public/tenant-by-slug/{slug}Tenant By Slugnone (public)

tenant-branding

MethodPathSummaryAuth
GET/api/tenant/brandingGet Own Brandingtenant session (customer_viewer / tenant_admin)

tenant-llm

MethodPathSummaryAuth
GET/api/tenant/llmTenant Get Llmtenant session (tenant_admin)
PUT/api/tenant/llm/api-keyTenant Put Llm Keytenant session (tenant_admin)
DELETE/api/tenant/llm/api-keyTenant Clear Llm Keytenant session (tenant_admin)

Schema di autenticazione

I browser usano un session cookie impostato da POST /api/auth/login. I client programmatici possono, in alternativa:

  1. Guidare il flusso di login (preferito per script di breve durata):
    bash
    curl -c jar -X POST https://mssp.../api/auth/login \
      -H 'Content-Type: application/json' \
      -d '{"email":"admin@example","password":"..."}'
    curl -b jar https://mssp.../api/mssp/tenants
  2. Emettere un token API a lunga durata (pianificato; non ancora esposto nella UI). Oggi gli unici chiamanti non basati su cookie sono i pod adapter e runs-worker per tenant, che si autenticano su /api/internal/* con token con ambito tenant che l'API conia e ruota (vedi Endpoint interni).

In SOCTALK_AUTH_MODE=proxy, l'API si fida degli header upstream X-Forwarded-User / X-Forwarded-Email / X-Forwarded-Groups e l'intera superficie di autenticazione della sessione viene smontata — /api/auth/* (login, logout, me, assume-tenant, password/change) e/api/mssp/users/{id}/password/reset restituiscono 404 (non 405). Il tuo IdP possiede la superficie dell'identità.

CSRF

Il CSRF è applicato globalmente, non per prefisso: internal_session_middleware valida l'header Origin / Referer su ogni richiesta che modifica lo stato (POST / PUT / PATCH / DELETE) che porta con sé il session cookie. Si tratta di validazione dell'header, non di un token cookie double-submit (quel pattern è comparso in bozze precedenti, ma il runtime usa la validazione dell'header). Le origini accettate provengono da SOCTALK_PUBLIC_ORIGIN (e SOCTALK_PUBLIC_ORIGIN_BASE per gli host cliente con wildcard sullo slug), che il chart deriva da ingress.hostnames. Le richieste che non portano alcun session cookie (ad esempio le chiamate bearer-token di adapter/worker, o la richiesta di login stessa) sono esenti. I browser inviano Origin automaticamente; i client non browser possono, in alternativa:

  • Far corrispondere Origin a uno degli hostname accettati, oppure
  • Impostare Host: <accepted-hostname> + Origin: https://<accepted-hostname> indipendentemente dall'effettivo target TCP (lo step di onboarding firstboot.sh usa questo trucco).

Flussi comuni

Onboarding di un tenant

bash
curl -b jar -X POST https://mssp.../api/mssp/tenants/onboard \
  -H 'Content-Type: application/json' \
  -d '{
    "slug": "acme-corp",
    "display_name": "Acme Corp",
    "profile": "persistent"
  }'

profile è validato lato server rispetto a ^(poc|persistent|provided)$. Vedi ciclo di vita del tenant / profili per la semantica di ciascun valore. Per provided (BYO-Wazuh), il payload richiede in aggiunta un oggetto external_siem (URL dell'indexer, URL dell'API del Manager, credenziali basic-auth) più un llm_api_key per tenant; il server restituisce 422 con errori a livello di campo se qualcuno di questi manca.

Restituisce 202 con l'ID del nuovo tenant. Osserva GET /api/mssp/tenants/{id} per le transizioni di stato, oppure interroga GET /api/mssp/tenants/{id}/events per l'elenco degli eventi del ciclo di vita. (/api/events/stream esiste ma in questa release emette solo ping keep-alive.)

Ottenere il log di audit

bash
curl -b jar 'https://mssp.../api/audit?start_date=2026-01-01T00:00:00Z&end_date=2026-02-01T00:00:00Z&event_type=review.completed&page=1&page_size=50'

Il router di audit è di livello superiore (/api/audit), non sotto /api/mssp/. Filtri: start_date / end_date (ISO 8601), event_type, aggregate_type e investigation_id. I risultati sono paginati per offset con page / page_size.

Inviare una decisione di revisione umana

Il router di revisione espone un endpoint per ciascuna decisione (nessun singolo percorso /decision). Scegli quello corrispondente:

bash
# Approve — payload field is `feedback` (free-text), not `rationale`
curl -b jar -X POST https://mssp.../api/review/<review-id>/approve \
  -H 'Content-Type: application/json' \
  -d '{"feedback":"Confirmed brute-force pattern."}'

# Reject — closes the case as auto_closed_fp; `feedback` is optional
curl -b jar -X POST https://mssp.../api/review/<review-id>/reject \
  -d '{"feedback":"Looks like a known scanner; benign."}'

# Need more info — payload is `questions: list[str]` (each renders as a bullet)
curl -b jar -X POST https://mssp.../api/review/<review-id>/request-info \
  -d '{"questions":["What is the source IP geo?","Any prior alerts on this user?"]}'

# Expire — retire a pending review without a verdict (optional reason)
curl -b jar -X POST https://mssp.../api/review/<review-id>/expire \
  -d '{"reason":"superseded by newer investigation"}'

Tutti e quattro restituiscono 409 se la Revisione non è più pending.

Per le proposte IR (la superficie di gestione dei casi), gli endpoint equivalenti sono sotto /api/mssp/proposals/{id}/approve e /api/mssp/proposals/{id}/reject.

Streaming degli eventi

bash
curl -N -b jar 'https://mssp.../api/events/stream'

Server-Sent Events. In questa release lo stream emette solo ping keep-alive (un ping all'incirca ogni 25 s) — il broadcast di eventi di dominio (aggiornamenti delle indagini, ciclo di vita del tenant, ecc.) è in roadmap. Oggi tratta l'endpoint come un test di connettività a livello di rete.

Generare un client Python

Lo schema si genera in modo pulito, quindi il modo più rapido per chiamare l'API da Python è generare un client tipizzato con openapi-python-client invece di scrivere richieste a mano. Eccolo end-to-end, leggendo le indagini.

1. Generare + installare il client

bash
pip install openapi-python-client
openapi-python-client generate \
  --url https://mssp.your-mssp.example/api/openapi.json --meta setup
pip install ./soc-talk-v1-client   # package name derives from the schema title

2. Consumare le indagini

python
import httpx
from soc_talk_v1_client import Client
from soc_talk_v1_client.api.investigations_bridge import (
    list_investigations_api_investigations_get as list_investigations,
    get_investigation_api_investigations_investigation_id_get as get_investigation,
)

BASE = "https://mssp.your-mssp.example"

# 1. Log in for a session cookie (the investigations routes take a session).
with httpx.Client(base_url=BASE) as h:
    h.post("/api/auth/login",
           json={"email": "admin@example", "password": "..."}).raise_for_status()
    session = h.cookies["soctalk_session"]

# 2. Drive the generated, typed client with that cookie.
client = Client(base_url=BASE, cookies={"soctalk_session": session})

page = list_investigations.sync(client=client, page=1, page_size=5)  # -> InvestigationList
print(f"{page.total} investigations")
for inv in page.items:                                               # -> Investigation
    print(inv.id, inv.status, inv.max_severity, inv.title)

detail = get_investigation.sync(client=client, investigation_id=str(page.items[0].id))
print(detail.phase, detail.alert_count, detail.verdict_decision)

Le funzioni degli endpoint prendono il nome dall'operationId che FastAPI deriva dalla route (list_investigations_api_investigations_get) — assegna loro un alias all'import, come sopra, per leggibilità. sync() restituisce il modello deserializzato (InvestigationList, i cui .items sono Investigation); sync_detailed() restituisce la Response grezza con il codice di stato se ti serve.

Una versione eseguibile — genera, effettua il login, elenca + legge — è distribuita come smoke test di codegen tests/e2e/smoke_openapi_client.py, che la pipeline di deploy esegue contro l'API live, così uno schema che smette di generare un client funzionante fa fallire la build.

Endpoint interni (/api/internal/*)

Usati dall'adapter e dal runs-worker per tenant (vedi i gruppi internal-adapter e internal-worker nel catalogo qui sopra). Non destinati al consumo umano — elencati affinché gli MSSP possano vedere cosa fanno quei pod.

Ogni chiamata porta con sé un token con ambito tenant che l'API conia al provisioning e rinnova automaticamente prima della scadenza (i token dell'adapter durano 7 giorni, i token del worker 30 giorni; il control plane li riconia ben dentro quella finestra). I token sono vincolati al tenant — un adapter può agire solo sugli URL del proprio tenant.

Limiti di velocità

L'API di per sé non impone limiti di velocità per route in questa release. Usa il livello di ingress per il rate limiting globale (middleware Traefik, annotazioni ingress-nginx) se ti serve.

Versionamento

Il documento OpenAPI riporta la versione dell'app. Puntiamo a modifiche additive all'interno di una minor; le modifiche che rompono la compatibilità solo con un salto di major. Le note di rilascio segnalano ogni modifica che riguarda l'API.

Riferimenti al codice sorgente

Tutti i router si trovano sotto src/soctalk/core/api/.

ConcettoFile
Router di autenticazione + middleware di sessionecore/api/auth.py, core/auth/middleware.py
Ciclo di vita del tenant MSSPcore/api/tenants.py
Configurazione LLM per tenantcore/api/llm_config.py
Indagini / IR / propostecore/api/investigations_bridge.py, core/api/ir.py
Audit / revisione / analytics / impostazioni / eventi (stub)core/api/legacy_stubs.py
Chatcore/api/chat.py
Route del worker (interne)core/api/worker_runs.py
Route dell'adapter (interne)core/api/adapter.py
Generatore OpenAPIscripts/dump_openapi.py

Rilasciato sotto la Licenza Apache 2.0.