Run Extension API

Status

The Kubernetes aggregated API serves Run logs and CLI Session operations. Console’s Runtime Gateway remains available for SDK and browser Session access and Function operations.

Problem

A Run is a logical execution, while several Runs can share one Runtime Pod. The runtimed container emits structured records keyed by Run UID. Giving every user direct pods/log access would expose unrelated executions and requires Pod discovery. Dashboard and krt logs therefore need a Run-scoped API.

API and authorization

The chart installs an APIService for logs.kruntimes.io/v1alpha1 and the following namespaced subresource:

GET /apis/logs.kruntimes.io/v1alpha1/namespaces/{namespace}/runs/{name}/log

Kubernetes authenticates the caller using the normal kubeconfig mechanisms: bearer tokens, exec credentials, and client certificates. Before proxying to the backend, the API server authorizes:

apiGroups: ["logs.kruntimes.io"]
resources: ["runs/log"]
verbs: ["get"]
resourceNames: ["<run-name>"]

The backend accepts identity headers only over the API aggregation layer’s verified request-header mTLS connection. It does not repeat a runs get SubjectAccessReview: authorization of runs/log is the API contract.

Its ServiceAccount has the minimal get pods/log permission needed to open the assigned Runtime Pod’s runtimed log, filters records to the target Run UID, and never exposes the Pod log stream directly to the caller.

Response and streaming

Snapshots return JSON:

{"items":[{"stream":"stdout","message":"..."}],"cursor":"..."}

tailLines defaults to 100 and is bounded to 500. Snapshot payloads are bounded to 1 MiB. follow=true returns application/x-ndjson; each line is a record with an opaque cursor. A reconnect passes cursor to resume after the last delivered record. The backend opens the Pod log stream before writing response headers, so an unavailable log service remains a regular HTTP error. Every non-success response uses the Kubernetes metav1.Status shape, preserving its HTTP code, reason, and actionable message for krt and Dashboard. In particular, a 409 Conflict means the Run’s assigned Runtime Pod no longer exists, so its ephemeral container logs cannot be recovered.

Go callers use internal/logapi.Client in the same shape as client-go log requests:

request := logs.GetLogs(namespace, runName, &logapi.RunLogOptions{Follow: true})
stream, err := request.Stream(ctx)

raw, err := logs.GetLogs(namespace, runName, options).Do(ctx).Raw()

Consumers

krt logs always uses the current kubeconfig’s Kubernetes API endpoint; it has no Gateway URL, Gateway CA, or TLS-skip flags. Dashboard keeps the login token in an HttpOnly cookie and forwards it server-side to the aggregated API. Neither client needs runs get, Pod discovery, pods/log, or Pod port-forward access to retrieve logs.

Runtime Gateway has no Run-log route and no pods/log RBAC. This keeps its Session and Function authorization boundary separate from the Kubernetes aggregation boundary.

Session operations

The same run-extension-api Deployment also serves a second APIService:

GET /apis/sessions.kruntimes.io/v1alpha1/namespaces/{namespace}/runs/{name}/session

This is a WebSocket endpoint for Session operations. The API server authenticates the kubeconfig caller and authorizes get on sessions.kruntimes.io/runs/session. The backend accepts the forwarded identity only over verified aggregation mTLS, loads the named ready Session Run, and streams its operations to the assigned Runtime. krt also reads the Run, so its caller needs get on kruntimes.io/runs. The existing logs.kruntimes.io path remains available. The Runtime controller’s NetworkPolicy permits run-extension-api Pods to reach the Runtime Service’s Session gRPC port.

Installation

runExtensionAPI.enabled defaults to true and is independent of gateway.enabled. Both APIService objects are cluster-scoped, so exactly one platform release in a cluster must own each group/version. Set runExtensionAPI.enabled: false for other releases.

Verification

E2E coverage proves that a credential with only get on the named logs.kruntimes.io/runs/log resource can retrieve a snapshot through krt and can follow a still-running one-shot Run. A credential lacking that subresource permission is denied by the API server.