Skip to content

REST API

Die SocTalk-API ist eine FastAPI-Anwendung. Ihre vollständige Oberfläche wird aus dem Code als OpenAPI-Schema generiert und unter /api/ bereitgestellt (der Ingress leitet /api/* an die API und alles Übrige an die Web-Konsole):

  • 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

Die OpenAPI-Oberfläche ist die maßgebliche Quelle. Ein Snapshot davon wird mit dieser Dokumentation unter /openapi.json ausgeliefert, und der Katalog unten wird aus diesem Schema generiert — er kann nicht vom Code abweichen.

Den Katalog neu generieren

Der Endpunkt-Katalog wird von npm run gen:api erzeugt, das docs/public/openapi.json liest. Aktualisiere das Schema zuerst aus dem API-Code:

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

Alles zwischen den GENERATED-Markern wird überschrieben; die Prosa drumherum wird von Hand gepflegt.

Endpunkt-Katalog

Die Spalte Auth leitet sich aus dem require_role- / require_tenant_role-Guard jeder Route ab. Die Kennzeichnung session cookie bedeutet, dass am Handler jede authentifizierte Session akzeptiert wird — aber mandantengebundene Rollen bleiben durch Row-Level Security auf ihre eigenen Daten beschränkt, sodass ein tenant_admin selbst auf einer ungeschützten MSSP-artigen Route nur die Zeilen seines Mandanten sieht.

97 Operationen über 23 Gruppen, generiert aus dem OpenAPI-Schema (API-Version 0.1.0). Auth leitet sich aus den require_role- / require_tenant_role-Guards der Route ab.

auth

MethodePfadZusammenfassungAuth
POST/api/auth/assume-tenantAssume TenantSession-Cookie (Login) / keine
POST/api/auth/loginLoginSession-Cookie (Login) / keine
POST/api/auth/logoutLogoutSession-Cookie (Login) / keine
GET/api/auth/meMeSession-Cookie (Login) / keine
POST/api/auth/password/changePassword ChangeSession-Cookie (Login) / keine

auth-admin

MethodePfadZusammenfassungAuth
POST/api/mssp/users/{user_id}/password/resetAdmin ResetSession — Rollen: mssp_admin / platform_admin

chat

MethodePfadZusammenfassungAuth
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

MethodePfadZusammenfassungAuth
GET/health/liveLivekeine (öffentlich)
GET/health/readyReadykeine (öffentlich)

internal-adapter

MethodePfadZusammenfassungAuth
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

MethodePfadZusammenfassungAuth
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

MethodePfadZusammenfassungAuth
GET/api/investigationsList InvestigationsSession-Cookie
GET/api/investigations/{investigation_id}Get InvestigationSession-Cookie
POST/api/investigations/{investigation_id}/cancelPost Cancel InvestigationSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/investigations/{investigation_id}/eventsGet EventsSession-Cookie

ir-alerts

MethodePfadZusammenfassungAuth
GET/api/mssp/alertsList AlertsSession — Rollen: analyst / mssp_admin / platform_admin

ir-integrations

MethodePfadZusammenfassungAuth
GET/api/mssp/tenants/{tenant_id}/integrationsGet IntegrationsSession — Rollen: mssp_admin / platform_admin
PATCH/api/mssp/tenants/{tenant_id}/integrationsPatch IntegrationsSession — Rollen: mssp_admin / platform_admin

ir-mssp

MethodePfadZusammenfassungAuth
GET/api/mssp/investigationsList Cases MsspSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/investigations/{investigation_id}Get Case MsspSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/investigations/{investigation_id}/eventsList Case Events MsspSession — Rollen: analyst / mssp_admin / platform_admin
PATCH/api/mssp/investigations/{investigation_id}/factsPatch Case FactsSession — Rollen: analyst / mssp_admin / platform_admin
POST/api/mssp/investigations/{investigation_id}/messagesPost Analyst MessageSession — Rollen: analyst / mssp_admin / platform_admin

ir-proposals

MethodePfadZusammenfassungAuth
GET/api/mssp/proposalsList Pending ProposalsSession — Rollen: analyst / mssp_admin / platform_admin
POST/api/mssp/proposals/{proposal_id}/approveApprove Proposal RouteSession — Rollen: analyst / mssp_admin / platform_admin
POST/api/mssp/proposals/{proposal_id}/rejectReject Proposal RouteSession — Rollen: analyst / mssp_admin / platform_admin

ir-tenant

MethodePfadZusammenfassungAuth
GET/api/tenant/investigationsList Cases TenantMandanten-Session (customer_viewer / tenant_admin)
GET/api/tenant/investigations/{investigation_id}Get Case TenantMandanten-Session (customer_viewer / tenant_admin)

l2-agent

MethodePfadZusammenfassungAuth
POST/api/agent/heartbeatHeartbeatL2-Agent-Installationstoken (Bearer)
POST/api/agent/jobs:claimClaim JobL2-Agent-Installationstoken (Bearer)
POST/api/agent/jobs/{job_id}/completeComplete JobL2-Agent-Installationstoken (Bearer)
POST/api/agent/jobs/{job_id}/eventsPost EventL2-Agent-Installationstoken (Bearer)
POST/api/agent/registerRegisterL2-Agent-Installationstoken (Bearer)

legacy-stubs

MethodePfadZusammenfassungAuth
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

MethodePfadZusammenfassungAuth
GET/api/metrics/hourlyHourlySession-Cookie
GET/api/metrics/overviewOverviewSession-Cookie

mssp-analytics

MethodePfadZusammenfassungAuth
GET/api/mssp/analytics/heatmapHeatmapSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/analytics/rankingRankingSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/analytics/trendsTrendsSession — Rollen: analyst / mssp_admin / platform_admin

mssp-dashboard

MethodePfadZusammenfassungAuth
GET/api/mssp/dashboard/open-by-tenantOpen By TenantSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/pending-reviewsPending ReviewsSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/repeated-iocsRepeated IocsSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/stuck-investigationsStuck InvestigationsSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/dashboard/tenant-healthTenant HealthSession — Rollen: analyst / mssp_admin / platform_admin

mssp-tenant-branding

MethodePfadZusammenfassungAuth
PATCH/api/mssp/tenants/{tenant_id}/brandingUpdate Tenant BrandingSession — Rollen: mssp_admin / platform_admin

mssp-tenant-llm

MethodePfadZusammenfassungAuth
GET/api/mssp/tenants/{tenant_id}/llmGet Tenant LlmSession — Rollen: mssp_admin / platform_admin
PATCH/api/mssp/tenants/{tenant_id}/llmUpdate Tenant LlmSession — Rollen: mssp_admin / platform_admin
DELETE/api/mssp/tenants/{tenant_id}/llm/api-keyClear Tenant Llm Api KeySession — Rollen: mssp_admin / platform_admin

mssp-tenants

MethodePfadZusammenfassungAuth
GET/api/mssp/tenantsList TenantsSession — Rollen: analyst / mssp_admin / platform_admin
POST/api/mssp/tenantsCreate TenantSession — Rollen: mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}Get TenantSession — Rollen: analyst / mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:decommissionDecommission TenantSession — Rollen: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:issue-agentIssue AgentSession — Rollen: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:resumeResume TenantSession — Rollen: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:retryRetry ProvisioningSession — Rollen: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:retry-installRetry InstallSession — Rollen: mssp_admin / platform_admin
POST/api/mssp/tenants/{tenant_id}:suspendSuspend TenantSession — Rollen: mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}/adapter-statusGet Tenant Adapter StatusSession — Rollen: mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}/eventsList EventsSession — Rollen: analyst / mssp_admin / platform_admin
GET/api/mssp/tenants/{tenant_id}/external-siemGet Tenant External SiemSession — Rollen: mssp_admin / platform_admin
PATCH/api/mssp/tenants/{tenant_id}/external-siemUpdate Tenant External SiemSession — Rollen: mssp_admin / platform_admin
POST/api/mssp/tenants/onboardOnboard TenantSession — Rollen: mssp_admin / platform_admin

public-tenant

MethodePfadZusammenfassungAuth
GET/api/public/mssp-by-slug/{slug}Mssp By Slugkeine (öffentlich)
GET/api/public/scope-by-slug/{slug}Scope By Slugkeine (öffentlich)
GET/api/public/tenant-by-slug/{slug}Tenant By Slugkeine (öffentlich)

tenant-branding

MethodePfadZusammenfassungAuth
GET/api/tenant/brandingGet Own BrandingMandanten-Session (customer_viewer / tenant_admin)

tenant-llm

MethodePfadZusammenfassungAuth
GET/api/tenant/llmTenant Get LlmMandanten-Session (tenant_admin)
PUT/api/tenant/llm/api-keyTenant Put Llm KeyMandanten-Session (tenant_admin)
DELETE/api/tenant/llm/api-keyTenant Clear Llm KeyMandanten-Session (tenant_admin)

Auth-Schema

Browser verwenden ein Session-Cookie, das von POST /api/auth/login gesetzt wird. Programmatische Clients können entweder:

  1. Den Login-Flow durchlaufen (bevorzugt für kurzlebige Skripte):
    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. Ein langlebiges API-Token ausstellen (geplant; in der UI noch nicht verfügbar). Heute sind die einzigen Nicht-Cookie-Aufrufer die mandantenspezifischen Adapter- und runs-worker-Pods, die sich mit mandantengebundenen Tokens, die die API ausstellt und rotiert, gegenüber /api/internal/* authentifizieren (siehe Interne Endpunkte).

Im Modus SOCTALK_AUTH_MODE=proxy vertraut die API den vorgelagerten Headern X-Forwarded-User / X-Forwarded-Email / X-Forwarded-Groups, und die gesamte Session-Auth-Oberfläche wird ausgehängt — /api/auth/* (login, logout, me, assume-tenant, password/change) und/api/mssp/users/{id}/password/reset liefern 404 (nicht 405). Deine IdP besitzt die Identitätsoberfläche.

CSRF

CSRF wird global durchgesetzt, nicht pro Präfix: internal_session_middleware validiert den Origin- / Referer-Header bei jeder zustandsändernden Anfrage (POST / PUT / PATCH / DELETE), die das Session-Cookie trägt. Es handelt sich um Header-Validierung, nicht um ein Double-Submit-Cookie-Token (dieses Muster tauchte in früheren Entwürfen auf, aber die Laufzeit verwendet Header-Validierung). Die akzeptierten Origins stammen aus SOCTALK_PUBLIC_ORIGIN (und SOCTALK_PUBLIC_ORIGIN_BASE für Slug-Wildcard-Kundenhosts), die das Chart aus ingress.hostnames ableitet. Anfragen, die kein Session-Cookie tragen (z. B. die Bearer-Token-Aufrufe von Adapter/Worker oder die Login-Anfrage selbst), sind ausgenommen. Browser senden Origin automatisch; Nicht-Browser-Clients können entweder:

  • Origin auf einen der akzeptierten Hostnamen abstimmen oder
  • Host: <accepted-hostname> + Origin: https://<accepted-hostname> unabhängig vom tatsächlichen TCP-Ziel setzen (der Onboarding-Schritt firstboot.sh nutzt diesen Trick).

Übliche Abläufe

Einen Mandanten onboarden

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 wird serverseitig gegen ^(poc|persistent|provided)$ validiert. Siehe Mandanten-Lebenszyklus / Profile für die Semantik jedes Werts. Für provided (BYO-Wazuh) erfordert die Nutzlast zusätzlich ein external_siem-Objekt (Indexer-URL, Manager-API-URL, Basic-Auth-Zugangsdaten) sowie einen mandantenspezifischen llm_api_key; der Server liefert 422 mit feldbezogenen Fehlern, falls etwas fehlt.

Liefert 202 mit der neuen Mandanten-ID zurück. Beobachte GET /api/mssp/tenants/{id} für Zustandsübergänge oder pollten GET /api/mssp/tenants/{id}/events für die Liste der Lebenszyklus-Ereignisse. (/api/events/stream existiert, gibt in diesem Release aber nur Keep-Alive-Pings aus.)

Das Audit-Log abrufen

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'

Der Audit-Router liegt auf oberster Ebene (/api/audit), nicht unter /api/mssp/. Filter: start_date / end_date (ISO 8601), event_type, aggregate_type und investigation_id. Ergebnisse werden per Offset mit page / page_size paginiert.

Eine Entscheidung zur menschlichen Prüfung übermitteln

Der Review-Router stellt einen Endpunkt pro Entscheidung bereit (keinen einzelnen /decision-Pfad). Wähle den passenden:

bash
# Approve — das Nutzlastfeld ist `feedback` (Freitext), nicht `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 — schließt den Fall als auto_closed_fp; `feedback` ist optional
curl -b jar -X POST https://mssp.../api/review/<review-id>/reject \
  -d '{"feedback":"Looks like a known scanner; benign."}'

# Need more info — Nutzlast ist `questions: list[str]` (jede wird als Aufzählungspunkt gerendert)
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 — eine ausstehende Prüfung ohne Verdikt zurückziehen (optionaler Grund)
curl -b jar -X POST https://mssp.../api/review/<review-id>/expire \
  -d '{"reason":"superseded by newer investigation"}'

Alle vier liefern 409, wenn die Prüfung nicht mehr pending ist.

Für IR-Proposals (die Fallmanagement-Oberfläche) sind die entsprechenden Endpunkte /api/mssp/proposals/{id}/approve und /api/mssp/proposals/{id}/reject.

Ereignisse streamen

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

Server-Sent Events. In diesem Release gibt der Stream nur Keep-Alive-Pings aus (ein ping etwa alle 25 s) — das Broadcasten von Domänenereignissen (Untersuchungs-Updates, Mandanten-Lebenszyklus usw.) steht auf der Roadmap. Behandle den Endpunkt heute als Konnektivitätstest auf Wire-Ebene.

Einen Python-Client generieren

Das Schema generiert sauber, daher ist der schnellste Weg, die API aus Python anzusprechen, einen typisierten Client mit openapi-python-client zu generieren, statt Requests von Hand zu bauen. Hier ist es durchgängig, beim Lesen von Untersuchungen.

1. Den Client generieren + installieren

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. Untersuchungen konsumieren

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)

Die Endpunkt-Funktionen sind nach der operationId benannt, die FastAPI aus der Route ableitet (list_investigations_api_investigations_get) — versieh sie beim Import mit Aliassen, wie oben, zur besseren Lesbarkeit. sync() liefert das deserialisierte Modell (InvestigationList, dessen .items vom Typ Investigation sind); sync_detailed() liefert die rohe Response mit dem Statuscode, falls du ihn brauchst.

Eine lauffähige Version — generieren, einloggen, auflisten + lesen — wird als Codegen-Smoke-Test tests/e2e/smoke_openapi_client.py ausgeliefert, den die Deploy-Pipeline gegen die Live-API ausführt, sodass ein Schema, das keinen funktionierenden Client mehr generiert, den Build scheitern lässt.

Interne Endpunkte (/api/internal/*)

Werden vom mandantenspezifischen Adapter und runs-worker genutzt (siehe die Gruppen internal-adapter und internal-worker im Katalog oben). Nicht für den menschlichen Gebrauch — aufgeführt, damit MSSPs sehen können, was diese Pods tun.

Jeder Aufruf trägt ein mandantengebundenes Token, das die API beim Provisioning ausstellt und automatisch erneuert, bevor es abläuft (Adapter-Tokens leben 7 Tage, Worker-Tokens 30 Tage; die Control Plane stellt sie deutlich innerhalb dieses Fensters neu aus). Tokens sind mandantengebunden — ein Adapter kann nur auf den URLs seines eigenen Mandanten agieren.

Rate-Limits

Die API selbst erlegt in diesem Release keine Rate-Limits pro Route auf. Nutze die Ingress-Ebene für globales Rate-Limiting (Traefik-Middleware, ingress-nginx-Annotationen), falls du es brauchst.

Versionierung

Das OpenAPI-Dokument trägt die App-Version. Wir streben additive Änderungen innerhalb einer Minor-Version an; Breaking Changes nur bei einem Major-Sprung. Die Release Notes heben jede API-relevante Änderung hervor.

Quellverweise

Alle Router liegen unter src/soctalk/core/api/.

KonzeptDatei
Auth-Router + Session-Middlewarecore/api/auth.py, core/auth/middleware.py
MSSP-Mandanten-Lebenszykluscore/api/tenants.py
Mandantenspezifische LLM-Konfigurationcore/api/llm_config.py
Untersuchungen / IR / Proposalscore/api/investigations_bridge.py, core/api/ir.py
Audit / Review / Analytics / Settings / Events (Stubs)core/api/legacy_stubs.py
Chatcore/api/chat.py
Worker-Routen (intern)core/api/worker_runs.py
Adapter-Routen (intern)core/api/adapter.py
OpenAPI-Generatorscripts/dump_openapi.py

Veröffentlicht unter der Apache-2.0-Lizenz.