REST API
- 1. Authentication
- 2. Errors
- 3. Clusters
- 4. Navigation and counts
- 5. Resources and objects
- 6. YAML, apply and patch
- 7. Actions
- 8. Logs
- 9. Exec and port-forward
- 10. Helm
- 11. Health, diagnosis and remediation
- 12. Metrics
- 13. Pod files
- 14. Instance endpoints
- 15. Streaming endpoints
- 16. Actuator
- 17. Related
Everything the SPA does, it does over this API. There is no private back channel, so anything on
this page is equally available to curl, a script or another service.
The base is /api/v1. Almost everything is addressed by cluster id.
|
Never assume a cluster called Resolve ids from |
1. Authentication
Two modes, set by kweblens.security.open-mode (default true). See
Security and identity.
| Mode | Rule |
|---|---|
|
Every |
|
Everything except |
Three path families are authenticated even in open-mode, because what they return is itself a secret:
-
/ws/**— pod exec over WebSocket. -
/api/v1/clusters//pods///filesand/…/files/*— the whole pod file browser, reads included. Letting those GETs ride the public read path would make secret exfiltration an unauthenticated operation. -
GET /api/v1/helm/values,/api/v1/helm/values/*and/api/v1/clusters//helm/releases///values— a release’s stored config and the saved values library commonly carry plaintext secrets and are returned raw.
Authenticate with HTTP Basic per request, or POST /api/v1/auth/session once to establish a
JSESSIONID (the SPA does this because a browser cannot attach Basic auth to a WebSocket
handshake). DELETE the same path to end that session. /api/ and /mcp/ are exempt from
CSRF; a failed Basic auth answers a bare 401 with no WWW-Authenticate header.
2. Errors
Failures come back as RFC 9457 ProblemDetail JSON with a code property, mapped by
ApiExceptionHandler:
| Condition | Status | code |
Notes |
|---|---|---|---|
Unknown cluster id |
404 |
|
|
Unusable cluster definition |
400 |
|
Rejected before anything is registered or persisted. |
Duplicate id, or editing a statically declared cluster |
409 |
|
|
Port-forward failure |
400 |
|
|
Analysis requested with no LLM configured |
409 |
|
Nothing broke and nothing was spent. |
Helm action failure |
400 |
|
|
The API server refused the request |
its own status |
|
A 403 from RBAC stays a 403, a 422 from a validating webhook stays a 422. fabric8 reports |
Bad input |
400 |
|
The cluster-refused mapping is load-bearing for the dry-run paths: their whole purpose is to
surface an admission-webhook rejection before the write lands, and without it the operator got
"500 kweblens broke" with the webhook’s message discarded. The detail carries the server’s own
human-readable reason, not fabric8’s framing.
The pod file browser has its own handler for its own failure modes.
3. Clusters
| Endpoint | Returns |
|---|---|
|
Every connected cluster: |
|
Add a cluster at runtime. Body is a |
|
Edit a runtime-managed cluster. Editing a statically declared one is a 409. |
|
Remove a runtime-managed cluster. |
|
Everything the editor needs — id, name, origin, master URL, selected context, available
contexts, where runtime clusters are stored, whether that storage is persistent, and
|
|
Given a kubeconfig in the body, list the contexts in it — so the UI can offer them before the cluster is added. |
The kubeconfig is a credential throughout: never returned, never logged, and ClusterDefinition
overrides toString() to redact it so an interpolated exception message cannot dump a working
credential into the log stream.
4. Navigation and counts
| Endpoint | Returns |
|---|---|
|
The left-nav registry for this cluster: categories → kinds → resource ids, including CRDs discovered from the cluster and a Gateway category promoted when the Gateway API CRDs exist. |
|
One badge number per kind. |
|
The CRD-declared printer columns for a kind; empty for built-in kinds. |
|
Ranked hits, plus |
|
The per-cluster capability report — see Health and diagnostics. |
counts computes its numbers with one limit=1 request per kind plus metadata.remainingItemCount,
not by listing everything. Listing was 22.1 MB of API-server traffic per call on a real cluster,
re-fetched on every namespace switch.
5. Resources and objects
| Endpoint | Returns |
|---|---|
|
Kind-agnostic summary rows: kind, namespace, name, status, age. |
|
Namespaces, as summary rows. |
|
Pods, as summary rows. |
|
The raw objects as a JSON array, matching the cluster’s own representation. |
|
One raw object, in full. |
|
The pods scheduled on a node, field-selected server-side. |
|
Per-kind detail for the drawer, including the resolved relation sections. |
|
Health summaries for |
|
Events, newest first, optionally scoped to one object. |
|
The cluster’s own OpenAPI v3 schema for a kind, which drives editor completion and validation. |
|
A list row is not the whole object. Both A This is not redaction. Per ADR-001 the drawer still shows every value. Redaction is the MCP boundary’s rule, not this one. |
The objects collection is fetched in server-side chunks and serialised a chunk at a time — the
response is unchanged, but listing 3,000 Secrets as one collection cost 1.33 GB of transient
heap. There is no client-visible limit: a substring filter over a truncated page would report
"no matches" for an object that exists.
6. YAML, apply and patch
| Endpoint | Returns |
|---|---|
|
The object as |
|
Apply a manifest ( |
|
The same request with |
|
A JSON merge patch ( |
The dry run and the apply share the same normalisation, because a preview made of different bytes describes a different request. Note that nothing forces a caller to run the dry run first — it is a separate request the operator chooses to make.
7. Actions
All of these are POST, all require auth, all are audited.
| Endpoint | Effect |
|---|---|
|
Delete the object. |
|
Scale a workload. |
|
Rollout restart. |
|
Suspend or resume (CronJob). |
|
Trigger a Job from a CronJob. |
|
Roll back to the previous revision. |
|
Mark the node unschedulable. |
|
Reverse it. |
|
Evict the node’s pods. |
(Prefix the first six with /api/v1/clusters/{clusterId}.)
8. Logs
| Endpoint | Returns |
|---|---|
|
A plain-text tail. |
|
The previous run’s log — the crashloop diagnostic, since after a restart the current log begins at the new process. |
|
SSE. One container, followed live. |
|
SSE. Multi-source, interleaved. Pass |
|
What the multi-source stream would follow, given the same |
All paths are under /api/v1/clusters/{clusterId}.
9. Exec and port-forward
Exec is WebSocket, not HTTP:
/ws/exec?cluster=…&namespace=…&pod=…&container=…[&mode=attach]
Text frames are written to the container’s stdin; output comes back as frames. mode=attach
attaches to the container’s existing process instead of starting a shell. Authenticated in both
security modes, and audited on connect. A WebSocket close frame arrives in under a second, so
there is deliberately no heartbeat here.
Port-forwards are HTTP-managed and are meant to outlive the tab that started one:
| Endpoint | Effect |
|---|---|
|
List active forwards. |
|
Start one. Body: |
|
Stop it. Auth required. |
The listening socket is bound by kweblens, not by the cluster, so forwards are released when their cluster is removed or re-pointed — not merely when its client closes.
10. Helm
kweblens’s own release surface, per cluster, built on jhelm — never the helm binary. Each
mutating call takes a real dryRun.
| Endpoint | Returns |
|---|---|
|
Releases with status and chart version. |
|
One release. |
|
Its revisions. |
|
The objects it owns. |
|
Its stored values as YAML. Auth required even in open-mode. |
|
The chart catalogue from the configured repositories. |
|
Install. Auth required. |
|
Upgrade. Auth required. |
|
Roll back to a revision. Auth required. |
|
Uninstall. Auth required. |
All under /api/v1/clusters/{clusterId}. Install, upgrade and rollback bodies all carry a
dryRun flag.
Cluster-agnostic Helm endpoints live under /api/v1/helm and are served by the jhelm-rest
library: /api/v1/helm/repos (repositories), /api/v1/helm/charts (chart show/values/readme/CRDs),
/api/v1/helm/hub (Artifact Hub search). kweblens adds two of its own there:
-
POST /api/v1/helm/repos/{name}/refresh— re-index one repository and evict its cached charts. -
GET|PUT|DELETE /api/v1/helm/values[/{name}]— the reusable values-file library. Every method requires auth, including the GETs.
11. Health, diagnosis and remediation
| Endpoint | Returns |
|---|---|
|
Deterministic findings, plus a cached LLM summary only if one was already bought for exactly these findings. Never calls a model. |
|
Runs the analysis and caches it. The only caller of the LLM. Auth required in both modes, and
audited. 409 |
|
Proposed fixes. Read-only. |
|
What the cluster says the action would do. A |
|
Carry it out. Without |
All under /api/v1/clusters/{clusterId}. Full behaviour, and which previews are real, in
Health and diagnostics.
12. Metrics
| Endpoint | Returns |
|---|---|
|
Per-node CPU/memory from metrics-server. |
|
Per-pod CPU/memory. |
|
Per-node disk usage from node-exporter. |
|
Whether a backend was found, and which. |
|
A time series for a fixed target. |
All under /api/v1/clusters/{clusterId}. See Metrics — in particular, the
absence of a source is an empty result, never an error.
13. Pod files
/api/v1/clusters/{clusterId}/pods/{namespace}/{pod}/files
GET lists a directory (?path=/), GET /content reads a file, GET /download fetches bytes,
PUT /content writes, DELETE removes. All take an optional container.
Two gates apply: the feature is off unless kweblens.files.enabled=true, and writes need
kweblens.files.writable=true. Every method here requires the admin login, GETs included — the
browser can read a projected Secret volume or the service-account token straight off a container’s
disk. The caps and the allowed roots are reported by /api/v1/about so a client can refuse an
oversized upload without a round trip.
14. Instance endpoints
| Endpoint | Returns |
|---|---|
|
Version, build time, cluster count, cluster-store backend and persistence, security mode, AI enabled, pod-file gates, simulator state. Never a secret — only whether one is set. In open-mode the operationally sensitive fields (admin username, store path, allowed roots) are withheld until you sign in. |
|
The audit trail of mutating actions, newest first. This is the in-memory 500-entry ring; every
entry is also written to the |
|
Authenticate once with Basic and get a |
|
Sign out: invalidates the session and clears the cookie. |
15. Streaming endpoints
Four endpoints return text/event-stream:
-
…/resources/{resourceId}/objects/watch[?namespace=…]— raw objects, each event namedADDED/MODIFIED/DELETED, projected exactly as the initial list is. -
…/resources/{resourceId}/watch[?namespace=…]— the same as summary rows. -
…/pods/{namespace}/{pod}/log/stream -
…/logs/stream
|
Every one of them writes a Treat a stream that goes silent for more than ~15 seconds as a dead connection. |
Consume them with any SSE client; each event’s data is JSON.
16. Actuator
/actuator/health, /actuator/info, /actuator/metrics and /actuator/prometheus are exposed.
/actuator/health/* and /actuator/info are public in *both security modes — that is what
makes them usable as Kubernetes probes. metrics and prometheus are ordinary GETs: public in
open-mode, authenticated when open-mode: false. Liveness and readiness probe groups are enabled.
17. Related
-
Connecting clusters — the cluster endpoints in workflow order
-
Editing and applying — the YAML and dry-run path
-
MCP server — the same cluster view for AI assistants
-
Security and identity — what open-mode actually permits