Skip to content

REST API

L'API SocTalk est une application FastAPI. Sa surface complète est générée depuis le code sous forme de schéma OpenAPI et servie sous /api/ (l'ingress route /api/* vers l'API et tout le reste vers 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 surface OpenAPI fait foi. Un instantané de celle-ci est livré avec cette documentation à l'adresse /openapi.json, et le catalogue ci-dessous est généré à partir de ce schéma — il ne peut pas diverger du code.

Régénérer le catalogue

Le catalogue des endpoints est produit par npm run gen:api, qui lit docs/public/openapi.json. Rafraîchissez d'abord le schéma depuis le code de l'API :

bash
# dans le dépôt soctalk
python scripts/dump_openapi.py <soctalk-docs>/docs/public/openapi.json
# dans soctalk-docs
npm run gen:api

Tout ce qui se trouve entre les marqueurs GENERATED est écrasé ; la prose qui l'entoure est rédigée à la main.

Catalogue des endpoints

La colonne Auth est dérivée du garde require_role / require_tenant_role de chaque route. Une étiquette session cookie signifie que toute session authentifiée est acceptée au niveau du handler — mais les rôles à portée tenant restent confinés à leurs propres données par la sécurité au niveau des lignes (RLS), de sorte qu'un tenant_admin ne voit que les lignes de son tenant, même sur une route non gardée de type MSSP.

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)

Schéma d'authentification

Les navigateurs utilisent un cookie de session défini par POST /api/auth/login. Les clients programmatiques peuvent au choix :

  1. Piloter le flux de connexion (préférable pour les scripts éphémères) :
    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. Émettre un token API à longue durée de vie (prévu ; pas encore exposé dans l'UI). Aujourd'hui, les seuls appelants sans cookie sont les pods adapter et runs-worker propres à chaque tenant, qui s'authentifient auprès de /api/internal/* avec des tokens à portée tenant que l'API émet et fait tourner (voir Endpoints internes).

En mode SOCTALK_AUTH_MODE=proxy, l'API fait confiance aux en-têtes amont X-Forwarded-User / X-Forwarded-Email / X-Forwarded-Groups et toute la surface d'authentification par session est démontée — /api/auth/* (login, logout, me, assume-tenant, password/change) et/api/mssp/users/{id}/password/reset renvoient 404 (et non 405). Votre IdP est propriétaire de la surface d'identité.

CSRF

La protection CSRF est appliquée globalement, pas par préfixe : internal_session_middleware valide l'en-tête Origin / Referer sur chaque requête modifiant l'état (POST / PUT / PATCH / DELETE) qui porte le cookie de session. Il s'agit d'une validation d'en-tête, et non d'un token de cookie en double soumission (ce motif figurait dans des versions antérieures, mais le runtime utilise la validation d'en-tête). Les origines acceptées proviennent de SOCTALK_PUBLIC_ORIGIN (et de SOCTALK_PUBLIC_ORIGIN_BASE pour les hôtes clients à slug générique), que le chart dérive de ingress.hostnames. Les requêtes qui ne portent aucun cookie de session (par exemple les appels par token bearer de l'adapter/worker, ou la requête de connexion elle-même) sont exemptées. Les navigateurs envoient Origin automatiquement ; les clients non navigateurs peuvent au choix :

  • Faire correspondre Origin à l'un des noms d'hôtes acceptés, ou
  • Définir Host: <accepted-hostname> + Origin: https://<accepted-hostname> indépendamment de la cible TCP réelle (l'étape d'onboarding firstboot.sh utilise cette astuce).

Flux courants

Intégrer 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 est validé côté serveur contre ^(poc|persistent|provided)$. Voir cycle de vie / profils du tenant pour la sémantique de chaque valeur. Pour provided (BYO-Wazuh), la charge utile nécessite en plus un objet external_siem (URL de l'indexer, URL de l'API Manager, identifiants basic-auth) ainsi qu'une llm_api_key propre au tenant ; le serveur renvoie 422 avec des erreurs au niveau des champs si l'un d'eux manque.

Renvoie 202 avec l'ID du nouveau tenant. Surveillez GET /api/mssp/tenants/{id} pour les transitions d'état, ou interrogez GET /api/mssp/tenants/{id}/events pour la liste des événements du cycle de vie. (/api/events/stream existe mais n'émet que des pings de maintien de connexion dans cette version.)

Obtenir le journal d'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'

Le routeur d'audit est au niveau supérieur (/api/audit), pas sous /api/mssp/. Filtres : start_date / end_date (ISO 8601), event_type, aggregate_type et investigation_id. Les résultats sont paginés par décalage avec page / page_size.

Soumettre une décision de revue humaine

Le routeur de revue expose un endpoint par décision (pas de chemin /decision unique). Choisissez celui qui correspond :

bash
# Approuver — le champ de la charge utile est `feedback` (texte libre), pas `rationale`
curl -b jar -X POST https://mssp.../api/review/<review-id>/approve \
  -H 'Content-Type: application/json' \
  -d '{"feedback":"Confirmed brute-force pattern."}'

# Rejeter — clôture le cas en auto_closed_fp ; `feedback` est optionnel
curl -b jar -X POST https://mssp.../api/review/<review-id>/reject \
  -d '{"feedback":"Looks like a known scanner; benign."}'

# Besoin de plus d'informations — la charge utile est `questions: list[str]` (chacune s'affiche en puce)
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?"]}'

# Expirer — retire une revue en attente sans verdict (motif optionnel)
curl -b jar -X POST https://mssp.../api/review/<review-id>/expire \
  -d '{"reason":"superseded by newer investigation"}'

Les quatre renvoient 409 si la revue n'est plus pending.

Pour les propositions IR (la surface de gestion des cas), les endpoints équivalents sont sous /api/mssp/proposals/{id}/approve et /api/mssp/proposals/{id}/reject.

Diffuser les événements

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

Server-Sent Events. Dans cette version, le flux n'émet que des pings de maintien de connexion (un ping environ toutes les 25 s) — la diffusion des événements de domaine (mises à jour d'enquêtes, cycle de vie des tenants, etc.) figure sur la feuille de route. Considérez cet endpoint comme un test de connectivité au niveau du fil aujourd'hui.

Générer un client Python

Le schéma se génère proprement, donc le moyen le plus rapide d'appeler l'API depuis Python est de générer un client typé avec openapi-python-client plutôt que d'écrire des requêtes à la main. Voici le processus de bout en bout, qui lit les enquêtes.

1. Générer + installer le 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. Consommer les enquêtes

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)

Les fonctions d'endpoint sont nommées d'après l'operationId que FastAPI dérive de la route (list_investigations_api_investigations_get) — donnez-leur un alias à l'import, comme ci-dessus, pour plus de lisibilité. sync() renvoie le modèle désérialisé (InvestigationList, dont les .items sont des Investigation) ; sync_detailed() renvoie la Response brute avec le code de statut si vous en avez besoin.

Une version exécutable — générer, se connecter, lister + lire — est livrée en tant que test de fumée du codegen tests/e2e/smoke_openapi_client.py, que le pipeline de déploiement exécute contre l'API en direct, de sorte qu'un schéma qui cesse de générer un client fonctionnel fait échouer le build.

Endpoints internes (/api/internal/*)

Utilisés par l'adapter et le runs-worker propres à chaque tenant (voir les groupes internal-adapter et internal-worker dans le catalogue ci-dessus). Pas destinés à une consommation humaine — listés pour que les MSSP puissent voir ce que font ces pods.

Chaque appel porte un token à portée tenant que l'API émet au provisionnement et renouvelle automatiquement avant son expiration (les tokens de l'adapter vivent 7 jours, ceux du worker 30 jours ; le plan de contrôle les ré-émet bien avant cette échéance). Les tokens sont liés au tenant — un adapter ne peut agir que sur les URLs de son propre tenant.

Limites de débit

L'API elle-même n'impose pas de limites de débit par route dans cette version. Utilisez la couche ingress pour une limitation de débit globale (middleware Traefik, annotations ingress-nginx) si vous en avez besoin.

Gestion des versions

Le document OpenAPI porte la version de l'application. Nous visons des changements additifs au sein d'une version mineure ; les changements incompatibles n'ont lieu que lors d'un bump majeur. Les notes de version signalent chaque changement affectant l'API.

Points d'entrée dans le code source

Tous les routeurs se trouvent sous src/soctalk/core/api/.

ConceptFichier
Routeur d'authentification + middleware de sessioncore/api/auth.py, core/auth/middleware.py
Cycle de vie des tenants MSSPcore/api/tenants.py
Configuration LLM par tenantcore/api/llm_config.py
Enquêtes / IR / propositionscore/api/investigations_bridge.py, core/api/ir.py
Audit / revue / analytics / paramètres / événements (stubs)core/api/legacy_stubs.py
Chatcore/api/chat.py
Routes worker (internes)core/api/worker_runs.py
Routes adapter (internes)core/api/adapter.py
Générateur OpenAPIscripts/dump_openapi.py

Publié sous la licence Apache 2.0.