Skip to content

API Frontend API

This page is under active development for v1.5 GA

The API Frontend (AF) is the unified external gateway introduced in v1.5. It exposes MCP Streamable HTTP and A2A JSON-RPC protocols for operators, AI agents, and the Backstage console.

Base URL

https://kubernaut-apifrontend.kubernaut-system.svc.cluster.local:8443

External clients connect via the cluster ingress or OpenShift Route configured for the API Frontend.

Authentication

All protocol endpoints require a valid OIDC/OAuth2 bearer token:

Authorization: Bearer <jwt-token>

The AF validates tokens via JWKS from the configured OIDC provider and extracts user identity from JWT claims. Tool invocations are authorized via Kubernetes SubjectAccessReview — see Security & RBAC: Tool Authorization for the SAR model and per-persona ClusterRoles.

Protocol Endpoints

The AF exposes two protocol endpoints that proxy to backend services:

MCP Streamable HTTP

POST /mcp

Model Context Protocol endpoint using Streamable HTTP transport (spec 2025-03-26). Accepts JSON-RPC 2.0 requests for initialize, tools/list, tools/call, and other MCP methods. The Accept header determines the response format:

  • application/json — synchronous JSON response
  • text/event-stream — SSE streaming response (for long-running tool calls)

Returns 501 when MCP is disabled in the AF configuration.

Example — list available tools:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

Example — invoke a tool:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "kubernaut_investigate",
    "arguments": {
      "rr_id": "rr-b83e19d4a7f1-5c2d09ae",
      "action": "start"
    }
  }
}

The AF runs its own MCP server with 23 kubernaut_* MCP tools exposed on the MCP bridge (see MCP Tool Reference for the full list). Each tool dispatches to its backend: K8s API (CRD operations), KA MCP (workflow selection/discovery and interactive session lifecycle), DataStorage (analytics), or local (presentation). Five additional internal tools (kubectl_get, kubectl_list, kubectl_list_events, kubernaut_check_existing_remediation, kubernaut_remediate) are used only inside the A2A agent loop and are not exposed on the MCP bridge.

A2A JSON-RPC 2.0

POST /a2a/invoke
POST /                  # root alias — same handler

Agent-to-Agent protocol endpoint accepting JSON-RPC 2.0 messages. Supported methods include message/send. Requires Bearer JWT authentication. POST / is an alias for POST /a2a/invoke, providing A2A spec conformance for clients that expect the root path.

The A2A agent uses 23 SAR-gated kubernaut_* MCP tools exposed on the MCP bridge, plus 5 internal tools, organized in seven domains:

Domain Tools Backend
CRD operations kubernaut_list_remediations, kubernaut_get_remediation, kubernaut_approve, kubernaut_cancel_remediation, kubernaut_watch, kubernaut_list_approval_requests, kubernaut_get_approval_request, kubernaut_await_session K8s API (AF SA)
Investigation & session lifecycle kubernaut_investigate, kubernaut_message, kubernaut_complete, kubernaut_complete_no_action, kubernaut_cancel, kubernaut_status, kubernaut_reconnect KA MCP
Workflow kubernaut_discover_workflows, kubernaut_select_workflow KA MCP
Alerts kubernaut_list_alerts (conditional on Prometheus) Prometheus
Data & history kubernaut_list_workflows, kubernaut_get_remediation_history, kubernaut_get_effectiveness, kubernaut_get_audit_trail DataStorage REST
Presentation kubernaut_present_decision Local

Upstream Helm gap (#1239)

kubernaut_list_approval_requests and kubernaut_get_approval_request are not yet in the Helm values.yaml persona definitions. They belong in the remediation-approver persona per #1235. The documentation reflects the intended design. See per-persona ClusterRoles.

kubernaut_investigate dispatches to the Kubernaut Agent's MCP server (maps to KA's kubernaut_investigate with action=start). The AF decomposes the remaining KA actions (message, complete, cancel, status, reconnect, discover_workflows) into individual MCP tools. CRD tools operate on RemediationRequest and RemediationApprovalRequest resources via the Kubernetes API using the AF ServiceAccount (unified SA model). Data tools query DataStorage. kubernaut_present_decision is handled locally by the AF.

The AF's A2A agent also uses 5 internal tools that are SAR-gated but not exposed on the MCP bridge:

Tool Purpose
kubectl_get Get any namespaced K8s resource by kind/name/namespace (Secret .data redacted)
kubectl_list List namespaced K8s resources with optional label selector (Secret .data redacted)
kubectl_list_events List K8s events with reason/object filters
kubernaut_check_existing_remediation Check for duplicate RemediationRequest before creation
kubernaut_remediate Create a new RemediationRequest CRD

All internal tools use the AF ServiceAccount (unified SA model) and are SAR-gated on the A2A path via newRBACGuard().

When severityTriage.enabled: true and a Prometheus URL is configured, 3 additional alert tools are registered: list_alerts, get_alert_details, kubernaut_investigate_alert. See MCP Tool Reference — Alert tools.

Status SSE (v1.5.1)

POST /a2a/status

Real-time remediation status streaming endpoint (DD-AF-008). Clients subscribe to phase transitions for a specific RemediationRequest via a JSON-RPC 2.0 request body.

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "status/subscribe",
  "params": { "rr_id": "rr-abc-123" }
}

Response: Content-Type: text/event-stream with Cache-Control: no-cache, Connection: keep-alive, X-Accel-Buffering: no.

SSE event types:

Event Purpose Payload
status/update Emitted on subscribe (current state) and on each RR phase transition rr_id, phase, timestamp, final (bool), metadata (optional)
status/closing Emitted 5 seconds before token expiry reason (e.g. token_expiry), reconnect (bool, always true)

Wire format example:

event: status/update
data: {"jsonrpc":"2.0","method":"status/update","params":{"rr_id":"rr-abc-123","phase":"Verifying","timestamp":"2026-06-18T15:10:00Z","final":false}}

: heartbeat (every 15s)

event: status/closing
data: {"jsonrpc":"2.0","method":"status/closing","params":{"reason":"token_expiry","reconnect":true}}

Authentication: Same OIDC bearer token chain as /mcp and /a2a/invoke. No per-resource SAR — all authenticated users can subscribe.

Keepalive: ": " comment line every 15 seconds to keep TCP alive.

Auto-reconnect: The handler automatically reconnects the underlying controller-runtime watch if the watch channel closes (server-side timeout). Clients should reconnect with a fresh token when they receive status/closing with reconnect: true.

Error codes:

Code Meaning
-32600 Invalid request (bad JSON / unparseable body)
-32601 Method not found (method is not status/subscribe)
-32602 Invalid params (rr_id is empty)
-32001 RR not found in the cluster
-32002 Access denied (reserved)

A2A Streaming Events

A2A streaming responses use TaskStatusUpdateEvent messages, each tagged with metadata.type to classify the event:

metadata.type Purpose status.message
reasoning LLM inner thoughts / investigation deltas Set
status Orchestration progress (tool starts, phase transitions) Set
output Final LLM answer Set
investigation Investigation-specific events from KA Set
keepalive Proxy idle-timeout prevention Not set (metadata-only)

Keepalive events — emitted every 5 s during long-running KA tool executions. Metadata: {"type":"keepalive", "dot":"."}. No status.message is set, so clients that render only status.message will not display keepalive noise.

Agent Card Discovery

GET /.well-known/agent-card.json

Returns the A2A agent card for protocol discovery. Unauthenticated callers receive a shell card (metadata only, empty skills array). Authenticated callers receive the full card including available skills scoped to their RBAC role.

Operational Endpoints

Health Probes

Method Port Path Description
GET 8081 /healthz Liveness — returns ok when the process is alive
GET 8081 /readyz Readiness — checks JWKS loaded and dependencies reachable; returns 503 during drain
GET 9090 /metrics Prometheus metrics in OpenMetrics format

Metrics

All AF metrics use the af_ namespace. See Monitoring: API Frontend Metrics for the full reference.

Audit Events

The AF emits 14 audit events to DataStorage (PR #1191 shared AuditStore normalization, PR #1192 production wiring). All events use the apifrontend.* prefix.

Category Events
Remediation rr.created, rr.deduplicated
KA delegation ka.delegated, ka.result_received
User decisions user.decision
Severity triage severity_triage.completed, severity_triage.failed
Session lifecycle session.completed (includes duration_ms)
Auth jwt.delegation
MCP mcp.session_init (deduplicated per Mcp-Session-Id)
Resilience circuitbreaker.trip
Triage triage.started, triage.completed

See Audit Pipeline: Emitting Services for the full cross-service audit reference.

Error Responses

All error responses use RFC 7807 Problem Details format with Content-Type: application/problem+json.

Example (service not ready):

{
  "type": "https://kubernaut.ai/problems/service-unavailable",
  "title": "Service Unavailable",
  "detail": "Service is draining — not accepting new requests",
  "status": 503
}

Next Steps