Skip to content

REST API

A API do SocTalk é uma aplicação FastAPI. Toda a sua superfície é gerada a partir do código como um schema OpenAPI e servida em /api/ (o ingress roteia /api/* para a API e todo o resto para o 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

A superfície OpenAPI é a fonte da verdade. Um snapshot dela é distribuído junto com esta documentação em /openapi.json, e o catálogo abaixo é gerado a partir desse schema — ele não pode divergir do código.

Regenerando o catálogo

O catálogo de endpoints é produzido por npm run gen:api, que lê docs/public/openapi.json. Atualize o schema a partir do código da API primeiro:

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

Tudo entre os marcadores GENERATED é sobrescrito; a prosa ao redor é curada manualmente.

Catálogo de endpoints

A coluna Auth é derivada do guard require_role / require_tenant_role de cada rota. Um rótulo session cookie significa que qualquer sessão autenticada é aceita no handler — mas os perfis com escopo de tenant permanecem confinados aos seus próprios dados por row-level security, de modo que um tenant_admin vê apenas as linhas do seu tenant, mesmo em uma rota sem proteção no estilo 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)

Esquema de autenticação

Navegadores usam um cookie de sessão definido por POST /api/auth/login. Clientes programáticos podem:

  1. Conduzir o fluxo de login (preferível para scripts de vida curta):
    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. Emitir um token de API de vida longa (planejado; ainda não exposto na UI). Hoje, os únicos chamadores sem cookie são os pods adapter e runs-worker por tenant, que se autenticam em /api/internal/* com tokens com escopo de tenant que a API gera e rotaciona (veja Endpoints internos).

Com SOCTALK_AUTH_MODE=proxy, a API confia nos cabeçalhos upstream X-Forwarded-User / X-Forwarded-Email / X-Forwarded-Groups e toda a superfície de autenticação por sessão é desmontada — /api/auth/* (login, logout, me, assume-tenant, password/change) e/api/mssp/users/{id}/password/reset retornam 404 (não 405). Seu IdP é dono da superfície de identidade.

CSRF

O CSRF é aplicado globalmente, não por prefixo: o internal_session_middleware valida o cabeçalho Origin / Referer em toda requisição que altera estado (POST / PUT / PATCH / DELETE) que carrega o cookie de sessão. É validação de cabeçalho, não um token de cookie double-submit (esse padrão apareceu em rascunhos anteriores, mas o runtime usa validação de cabeçalho). As origens aceitas vêm de SOCTALK_PUBLIC_ORIGIN (e SOCTALK_PUBLIC_ORIGIN_BASE para hosts de clientes com curinga de slug), que o chart deriva de ingress.hostnames. Requisições que não carregam cookie de sessão (por exemplo, as chamadas com token bearer do adapter/worker, ou a própria requisição de login) são isentas. Navegadores enviam Origin automaticamente; clientes que não são navegadores podem:

  • Igualar o Origin a um dos hostnames aceitos, ou
  • Definir Host: <accepted-hostname> + Origin: https://<accepted-hostname> independentemente do alvo TCP real (o passo de onboarding do firstboot.sh usa esse truque).

Fluxos comuns

Onboarding de um 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 é validado no servidor contra ^(poc|persistent|provided)$. Veja ciclo de vida / profiles do tenant para a semântica de cada valor. Para provided (BYO-Wazuh), o payload exige adicionalmente um objeto external_siem (URL do indexer, URL da Manager API, credenciais basic-auth) mais um llm_api_key por tenant; o servidor retorna 422 com erros por campo se algum estiver faltando.

Retorna 202 com o ID do novo tenant. Acompanhe GET /api/mssp/tenants/{id} para as transições de estado, ou faça polling em GET /api/mssp/tenants/{id}/events para a lista de eventos do ciclo de vida. (/api/events/stream existe, mas emite apenas pings de keep-alive nesta versão.)

Obter o log de auditoria

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'

O router de auditoria é de nível superior (/api/audit), não fica sob /api/mssp/. Filtros: start_date / end_date (ISO 8601), event_type, aggregate_type e investigation_id. Os resultados são paginados por offset com page / page_size.

Enviar uma decisão de revisão humana

O router de revisão expõe um endpoint por decisão (não há um único caminho /decision). Escolha o correspondente:

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"}'

Todos os quatro retornam 409 se a revisão não estiver mais pending.

Para propostas de IR (a superfície de gestão de casos), os endpoints equivalentes ficam em /api/mssp/proposals/{id}/approve e /api/mssp/proposals/{id}/reject.

Transmitir eventos

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

Server-Sent Events. Nesta versão o stream emite apenas pings de keep-alive (um ping aproximadamente a cada 25 s) — a transmissão de eventos de domínio (atualizações de investigação, ciclo de vida do tenant, etc.) está no roadmap. Trate o endpoint hoje como um teste de conectividade de baixo nível.

Gerar um cliente Python

O schema é gerado de forma limpa, então a maneira mais rápida de chamar a API a partir do Python é gerar um cliente tipado com openapi-python-client em vez de escrever requisições à mão. Aqui está o fluxo completo, lendo investigações.

1. Gerar + instalar o cliente

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. Consumir investigações

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)

As funções de endpoint recebem o nome do operationId que o FastAPI deriva da rota (list_investigations_api_investigations_get) — crie apelidos (alias) para elas no import, como acima, para melhor legibilidade. sync() retorna o modelo desserializado (InvestigationList, cujos .items são Investigation); sync_detailed() retorna o Response bruto com o código de status, se você precisar.

Uma versão executável — gerar, fazer login, listar + ler — é distribuída como o smoke test de codegen tests/e2e/smoke_openapi_client.py, que o pipeline de deploy executa contra a API ativa, de modo que um schema que deixe de gerar um cliente funcional quebra o build.

Endpoints internos (/api/internal/*)

Usados pelo adapter e pelo runs-worker por tenant (veja os grupos internal-adapter e internal-worker no catálogo acima). Não se destinam a consumo humano — estão listados para que MSSPs possam ver o que esses pods estão fazendo.

Cada chamada carrega um token com escopo de tenant que a API gera no provisionamento e renova automaticamente antes de expirar (tokens de adapter duram 7 dias, tokens de worker 30 dias; o control plane os regenera bem dentro dessa janela). Os tokens são vinculados ao tenant — um adapter só pode atuar nas URLs do seu próprio tenant.

Limites de taxa

A API em si não impõe limites de taxa por rota nesta versão. Use a camada de ingress para limitação de taxa global (middleware do Traefik, anotações do ingress-nginx) se precisar.

Versionamento

O documento OpenAPI carrega a versão do aplicativo. Buscamos mudanças aditivas dentro de uma minor; mudanças incompatíveis apenas em um incremento major. As notas de versão destacam toda alteração que afeta a API.

Ponteiros para o código-fonte

Todos os routers ficam sob src/soctalk/core/api/.

ConceitoArquivo
Router de auth + middleware de sessãocore/api/auth.py, core/auth/middleware.py
Ciclo de vida do tenant MSSPcore/api/tenants.py
Configuração de LLM por tenantcore/api/llm_config.py
Investigações / IR / propostascore/api/investigations_bridge.py, core/api/ir.py
Auditoria / revisão / analytics / configurações / eventos (stubs)core/api/legacy_stubs.py
Chatcore/api/chat.py
Rotas do worker (internas)core/api/worker_runs.py
Rotas do adapter (internas)core/api/adapter.py
Gerador de OpenAPIscripts/dump_openapi.py

Publicado sob a Licença Apache 2.0.