Service Proxy¶
The service proxy is a routing feature of headlamp-server (activated by --enable-helm) that allows the browser and plugins to reach any Kubernetes Service by name, without the browser having direct cluster network access.
How it works¶
Plugin fetch('/serviceproxy/default/my-helm-repo/api/charts')
│
▼
headlamp-server
├── authenticate request (token or OIDC session)
├── validate: does service "my-helm-repo" exist in namespace "default"?
└── forward to http://my-helm-repo.default.svc.cluster.local/api/charts
│
▼
Response returns to plugin via headlamp-server
The cluster network sees the request as coming from the Headlamp pod — not from the user's browser. This is essential for in-cluster deployments where the browser can't reach *.svc.cluster.local addresses.
URL structure¶
| Segment | Example | Description |
|---|---|---|
namespace |
default |
Kubernetes namespace of the target service |
service-name |
my-chartmuseum |
Name of the Kubernetes Service |
path |
api/charts |
Path forwarded to the service |
If Headlamp has a --base-url set (e.g. /headlamp), the full path becomes:
Using the service proxy from a plugin¶
// Direct fetch — works when base URL is /
const resp = await fetch('/serviceproxy/default/my-helm-repo/api/charts');
const charts = await resp.json();
// With base URL awareness (safer)
const base = window.__headlampBaseURL__ ?? '';
const resp = await fetch(`${base}/serviceproxy/default/my-helm-repo/api/charts`);
For App Catalog, the proxy URL is configured in the plugin's settings UI — you don't need to hardcode it in plugin code.
Authentication¶
The service proxy inherits the logged-in user's session. Every request forwarded through the proxy carries the user's token (or OIDC access token) in the Authorization header.
Known issue with service account token auth
With non-OIDC (service account token) authentication, the Authorization header is not correctly forwarded to the backend service. This causes Helm release listing to fail with 403 Forbidden. Track issue #4788. Workaround: use OIDC authentication.
RBAC requirements¶
For the proxy to forward requests, the Headlamp service account needs:
rules:
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get", "post", "put", "delete", "patch"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list"]
The target service also needs to accept requests from the Headlamp pod's IP or service account, depending on its own access controls.
Example: forwarding to ChartMuseum¶
- ChartMuseum service in namespace
default, service namemy-catalog-chartmuseum - Plugin or browser fetches:
/serviceproxy/default/my-catalog-chartmuseum/api/charts headlamp-serverforwards to:http://my-catalog-chartmuseum.default.svc.cluster.local/api/charts- ChartMuseum returns the chart list JSON
No firewall rules, no Ingress, no direct network path needed from the developer's laptop to the cluster's service network.