API Contract
Purpose
Abschnitt betitelt „Purpose“This specification defines the API contract: endpoint inventory, authentication model, scope matrix, error semantics, pagination, rate limiting, and the relationship between /events and /threats.
Audience: API engineers, integration architects.
Contract Philosophy
Abschnitt betitelt „Contract Philosophy“The OpenAPI specification is intended to be the canonical, machine-readable API contract. In the current workspace, however, API docs, OpenAPI, and server implementation are still being reconciled.
The current OpenAPI 3.1 specification is a draft contract under review.
Environments
Abschnitt betitelt „Environments“| Environment | Base URL | Status |
|---|---|---|
| Current workspace runtime | Loopback-only local bind on 127.0.0.1:8080 by default | Implemented for local development |
| Production target | https://api.superheld.app/ | Under review |
| Sandbox target | https://sandbox.superheld.app/ | Under review |
Path versioning and public environment naming are still under reconciliation.
Versioning
Abschnitt betitelt „Versioning“- Current workspace server: unversioned resource paths such as
/devices,/events,/threats - Target design: URL path versioning remains under review
- Deprecation policy: not yet a reliable implementation guarantee in the current workspace
- Backward compatibility: not yet guaranteed until the API contract is reconciled with the running server
Endpoint Inventory
Abschnitt betitelt „Endpoint Inventory“Current Workspace Implementation
Abschnitt betitelt „Current Workspace Implementation“| Method | Path | Description | Auth Required | Status |
|---|---|---|---|---|
| POST | /account/register | Register end-user account and mint portal session token | Public endpoint | Implemented |
| POST | /account/login | Authenticate end-user account and mint portal session token | Public endpoint | Implemented |
| GET | /devices | List registered devices | Optional or devices:read in secure mux | Implemented |
| POST | /devices | Register device | Optional or devices:write in secure mux | Implemented |
| GET | /threats | List derived threats | Optional or threats:read in secure mux | Implemented |
| GET | /events | List events | Optional or events:read in secure mux | Implemented |
| POST | /events | Ingest signed device event | Device signature, or events:write in secure mux | Implemented |
| GET | /alerts | List alerts | Optional or alerts:read in secure mux | Implemented |
| GET | /incidents | List tenant-scoped security incidents | incidents:read in secure mux | Implemented, prototype/internal |
| GET | /incidents/{id} | Read one tenant-scoped security incident | incidents:read in secure mux | Implemented, prototype/internal |
| PATCH | /incidents/{id} | Transition one tenant-scoped security incident | incidents:write in secure mux | Implemented, prototype/internal |
| GET | /jobs | List asynchronous job records | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| POST | /jobs | Create asynchronous job record | Optional or jobs:write in secure mux | Implemented, prototype/internal |
| GET | /jobs/{id} | Read one asynchronous job record | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| POST | /jobs/{id}/cancel | Cancel one queued, running, or waiting-review job | Optional or jobs:write in secure mux | Implemented, prototype/internal |
| POST | /jobs/{id}/review | Review one waiting-review job | Optional or jobs:review in secure mux; jobs:write remains accepted for compatibility | Implemented, prototype/internal |
| GET | /jobs/audit | List tenant-scoped audit entries across reviewed jobs | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| GET | /jobs/{id}/audit | Read audit entries for one reviewed job | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| GET | /jobs/{id}/steps | List steps for one asynchronous job | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| GET | /jobs/{id}/artifacts | List artifacts produced by one job | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| GET | /artifacts/{id} | Read one artifact | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| GET | /traces/{id} | Read one trace | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| GET | /traces/{id}/steps | List steps for one trace | Optional or jobs:read in secure mux | Implemented, prototype/internal |
| GET | /tokens | List tenant-bound secure-mux token metadata | tokens:read in secure mux | Implemented, prototype/internal |
| POST | /tokens | Mint tenant-bound secure-mux token | tokens:write in secure mux | Implemented, prototype/internal |
| GET | /tokens/audit | Read tenant-scoped audit entries across secure-mux tokens | tokens:read in secure mux | Implemented, prototype/internal |
| GET | /tokens/{id} | Read one tenant-bound secure-mux token metadata record | tokens:read in secure mux | Implemented, prototype/internal |
| GET | /tokens/{id}/audit | Read audit entries for one tenant-bound secure-mux token | tokens:read in secure mux | Implemented, prototype/internal |
| DELETE | /tokens/{id} | Revoke one tenant-bound secure-mux token | tokens:write in secure mux | Implemented, prototype/internal |
| POST | /scan | Submit URL or hash for analysis | Optional or scan:write in secure mux | Implemented |
| GET | /status | Protection status | Optional or status:read in secure mux | Implemented |
| GET | /webhooks | List registered webhooks | Optional or webhooks:read in secure mux | Implemented |
| POST | /webhooks | Register webhook | Optional or webhooks:write in secure mux | Implemented |
| GET | /webhooks/dlq | List retained webhook DLQ items | Optional or webhooks:read in secure mux | Implemented |
| POST | /webhooks/dlq | Replay retained webhook DLQ item by entry_id or latest by webhook_id | Optional or webhooks:write in secure mux | Implemented |
| DELETE | /webhooks/dlq | Delete retained webhook DLQ item by entry_id | Optional or webhooks:write in secure mux | Implemented |
| GET | /guidance | Return guidance cards | Optional or guidance:read in secure mux | Implemented, prototype/internal |
Documented Earlier, Not Implemented In This Workspace
Abschnitt betitelt „Documented Earlier, Not Implemented In This Workspace“| Method | Path | Notes |
|---|---|---|
| GET | /devices/{id} | Not implemented |
| GET | /threats/{id} | Not implemented |
| GET | /events/{id} | Not implemented |
| POST | /events/{id}/acknowledge | Not implemented |
| GET | /policies | Not implemented |
| PUT | /policies/{id} | Not implemented |
| POST | /rules | Not implemented |
| GET | /family | Not implemented |
| POST | /whitelist | Not implemented |
| POST | /report | Not implemented |
Canonical Integration Model: /events vs /threats
Abschnitt betitelt „Canonical Integration Model: /events vs /threats“The API exposes both /events and /threats. Their relationship:
| Endpoint | Model | Description |
|---|---|---|
/events | Append-only event stream | Every detection decision (allow, warn, block) as an immutable event. Canonical feed for SIEM, webhooks, polling. |
/threats | Derived entity view | Latest state per threat (active, resolved, dismissed). Deduplicated. Derived from events. |
Integrators should poll /events as their primary feed. /threats is a convenience view for dashboards and status queries.
The current workspace implementation already follows this split in broad strokes: /events is the append-oriented feed, while /threats is derived from events.
Current runtime notes:
POST /devicescurrently validatesdevice_id,tenant_id,platform,status, andpublic_key_b64.POST /devicescurrently also requiresX-Device-Signatureand verifies proof-of-possession against the submittedpublic_key_b64.- Device
statusis currently restricted toactiveorrevoked. public_key_b64must be a valid base64-encoded PKIX RSA public key because/eventssignature verification depends on it.- Re-registering an existing
device_idwith a different tenant or public key is rejected as a conflict. GET /incidentsandGET /incidents/{id}currently expose read-only, tenant-scoped security incidents derived from accepted high-severity alerting events and high-severity security-monitor observations and backed by the configured runtime store (in-memory, local JSON, or SQLite).PATCH /incidents/{id}currently acceptsstatustransitions and enforces the current runtime state machine (open -> investigating/resolved,investigating -> contained/resolved,contained -> resolved).POST /jobscurrently supportsincident_triage_v1as the first deterministic workflow and creates a queued record that is processed into an internal artifact.POST /jobs/{id}/cancelcurrently accepts queued, running, and waiting-review jobs and returns409for invalid state transitions.POST /jobs/{id}/reviewcurrently acceptsapprove,amend,reject, andcancelfor jobs inwaiting_review; current runtime amendments supportinput_refsandmax_runs, invalid review state returns422, reviewed jobs surfacereviewed_bywhen the request runs through the secure mux with a bound API token, and secure review requests now acceptjobs:reviewwithjobs:writeretained as a compatibility fallback.GET /jobs/auditandGET /jobs/{id}/auditcurrently expose the tenant-scoped internal job review audit trail backed by the configured runtime persistence layer and use the standard cursor/limit pagination contract.GET /jobs/auditcurrently also acceptsactionandreviewed_byfilters, and current runtime responses expose parsed auditfieldsalongside rawdetailwhen available.GET /jobs/{id}/stepsandGET /traces/{id}/stepscan now includereview_decisionsteps emitted by the review path.GET /jobs/{id},GET /jobs/audit,GET /jobs/{id}/audit,GET /jobs/{id}/steps,GET /jobs/{id}/artifacts,GET /artifacts/{id},GET /traces/{id}, andGET /traces/{id}/stepsare implemented in the current runtime.POST /account/registercurrently requiresemail,tenant_id, and a password with at least 12 characters, stores a bcrypt-backed account record, and returns a tenant-scoped session token for portal use.POST /account/logincurrently authenticates the stored account record and returns a fresh tenant-scoped session token carryingstatus:read,devices:read,alerts:read,incidents:read,tokens:read, andtokens:write.
Authentication
Abschnitt betitelt „Authentication“Current Workspace Authentication
Abschnitt betitelt „Current Workspace Authentication“| Surface | Current Behavior |
|---|---|
| Public API protection | Optional in NewMux; in-memory Bearer token + scope checks in NewSecureMux |
| Account auth | Public POST /account/register and POST /account/login endpoints issue tenant-scoped opaque bearer tokens from email/password credentials |
| Device registration | X-Device-Signature proof-of-possession over the registration body, validated against public_key_b64 |
| Device event ingestion | X-Device-Signature header with RSA-PSS + SHA-256 over request body |
| Token lifecycle | Tenant-bound secure-mux prototype via GET /tokens, POST /tokens, GET /tokens/audit, GET /tokens/{id}, GET /tokens/{id}/audit, DELETE /tokens/{id}; raw token returned once on creation, metadata and audit only afterwards, with token hashes/metadata and token-audit entries persisted in the configured runtime backend |
| OAuth2 | Not implemented in the current workspace server |
Current runtime note: GET /tokens/audit uses the standard cursor/limit pagination contract, currently also accepts action and token_id filters, and current runtime responses expose parsed audit fields alongside raw detail when available.
Target Product Authentication
Abschnitt betitelt „Target Product Authentication“API key prefixes, OAuth2 flows, token rotation, and public auth endpoints remain under review until the public API contract is aligned with the running server.
Scope Matrix In Current Secure Mux
Abschnitt betitelt „Scope Matrix In Current Secure Mux“| Scope | Permission | Status |
|---|---|---|
devices:read | List devices | Implemented |
devices:write | Register devices | Implemented |
threats:read | List threats | Implemented |
alerts:read | List alerts | Implemented |
alerts:write | Reserved only; no alert-create route currently exists | Reserved |
incidents:read | List tenant-scoped security incidents | Implemented, prototype/internal |
incidents:write | Transition tenant-scoped security incidents | Implemented, prototype/internal |
scan:write | Submit scan requests | Implemented |
events:read | List events | Implemented |
events:write | Access POST /events through secure mux | Implemented |
jobs:read | List and inspect asynchronous jobs, traces, steps, and artifacts | Implemented, prototype/internal |
jobs:write | Create and cancel asynchronous jobs; still accepted by review as compatibility fallback | Implemented, prototype/internal |
jobs:review | Review waiting asynchronous jobs | Implemented, prototype/internal |
tokens:read | List and inspect tenant-bound secure-mux token metadata and audit entries | Implemented, prototype/internal |
tokens:write | Mint and revoke tenant-bound secure-mux tokens | Implemented, prototype/internal |
webhooks:read | List webhooks and DLQ items | Implemented |
webhooks:write | Create webhooks and trigger DLQ replay | Implemented |
status:read | Read protection status | Implemented |
guidance:read | Read guidance cards | Implemented, internal/prototype |
Pagination
Abschnitt betitelt „Pagination“| Property | Value |
|---|---|
| Type | Cursor-based |
| Query parameters | cursor, limit |
| Response fields | has_more (boolean), cursor (string for next page) |
| Default limit | 20 |
| Maximum limit | 100 (500 for /events) |
Rate Limiting
Abschnitt betitelt „Rate Limiting“| Property | Value |
|---|---|
| Limit | 120 requests/minute in current middleware configuration |
| Status code | 429 Too Many Requests |
| Headers | X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (Unix timestamp), Retry-After on 429 |
| Keying | Current workspace uses tenant context after successful secure auth, otherwise credential fingerprint (Authorization/X-API-Key), otherwise remote address |
| Proxy awareness | X-Forwarded-For and X-Real-IP are only trusted when SUPERHELD_RATE_LIMIT_TRUST_PROXY=true is set |
| Retry-After | Emitted on rate-limited responses |
| Insecure mode | Restricted to loopback binds; external insecure binds are rejected |
| CORS | Disabled by default; optional allowlist via SUPERHELD_CORS_ALLOW_ORIGINS |
Baseline Response Security Headers
Abschnitt betitelt „Baseline Response Security Headers“| Header | Current Runtime Behavior |
|---|---|
X-Content-Type-Options | Always nosniff |
X-Frame-Options | Always DENY |
Referrer-Policy | Always no-referrer |
Cache-Control | Always no-store |
Strict-Transport-Security | Emitted only on TLS responses |
Error Model
Abschnitt betitelt „Error Model“Error Response Schema
Abschnitt betitelt „Error Response Schema“{ "error": { "code": "string", "message": "string", "status": 400 }}Status Codes
Abschnitt betitelt „Status Codes“| Code | Meaning |
|---|---|
| 400 | Invalid request (missing/bad parameters) |
| 413 | Request body exceeded the current runtime limit |
| 401 | Authentication failed (invalid/expired key) |
| 403 | Missing scope or insufficient permission |
| 404 | Resource not found |
| 429 | Rate limit exceeded |
| 500 | Server error (retry with backoff) |
Insufficient Scope Example
Abschnitt betitelt „Insufficient Scope Example“{ "error": { "code": "insufficient_scope", "message": "Scope 'threats:read' required for this endpoint.", "status": 403 }}Multi-Tenant Isolation
Abschnitt betitelt „Multi-Tenant Isolation“| Property | Description |
|---|---|
| Tenant fields | Device and event payloads carry tenant-related fields |
| Server enforcement | Tenant-scoped reads and secure-mux tenant checks are implemented; insecure mode remains local-only development mode |
| Public guarantee | Not yet safe to describe as fully enforced by design |
Related Specifications
Abschnitt betitelt „Related Specifications“- Event Pipeline — Event lifecycle and schema contracts
- Telemetry Schema — PII classification in API responses
- API Overview — Public API documentation
- Authentication — Public auth guide