Users choose their own namespace for Headlamp. Replace all hardcoded kube-system references that indicate Headlamp's install namespace with <your-namespace> so users substitute their own value. Upstream workload references left untouched: - tns-csi controller pods in kube-system (upstream CSI driver) - NetworkPolicy selectors targeting kube-system - API server proxy paths to kube-system pods Refs: PRI-434 Co-authored-by: Chris Farhood <chris@farhood.org> Co-authored-by: Paperclip <noreply@paperclip.ing>
8.5 KiB
Security Policy
Overview
The Headlamp TNS-CSI Plugin is a visibility and benchmarking tool for the tns-csi Kubernetes CSI driver. Security considerations center on Kubernetes RBAC, network policies, and the limited write operations performed by the Benchmark page.
Security Model
Primarily Read-Only
The plugin is read-only for all pages except Benchmark:
- No secrets access: The plugin does not read or store Kubernetes Secrets
- No CRD installation: No custom resource definitions or cluster-level modifications
- No PII: CSI resource metadata (names, namespaces, parameters) does not contain personally identifiable information
- No external egress: All API calls go through the Kubernetes API server proxy; no external network calls
The Benchmark Exception
The Benchmark page creates and deletes a Kubernetes Job and PVC to run storage benchmarks. These resources are:
- Labeled
app.kubernetes.io/managed-by=headlamp-tns-csi-pluginfor identification - Created only in the namespace the user explicitly selects
- Automatically deleted when the benchmark completes or is stopped
- Using the
yasker/kbench:latestimage (a public, well-known benchmark tool)
Grant benchmark write permissions only to users who should be able to initiate storage tests.
Data Flow
User Browser
↓ (HTTPS)
Headlamp Pod
↓ (in-cluster service account or user token)
Kubernetes API Server
↓ (list/watch StorageClasses, PVs, PVCs, pods, snapshots)
↓ (pod proxy: controller pod port 8080 → Prometheus metrics)
↓ (pod proxy: kbench pod → FIO log for benchmark results)
Plugin Frontend (React)
All communication uses Kubernetes authentication and authorization mechanisms. The plugin never stores credentials or bypasses RBAC.
RBAC Requirements
Minimal Read-Only Permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: headlamp-tns-csi-reader
rules:
- apiGroups: [""]
resources: ["persistentvolumes", "pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses", "csidrivers"]
verbs: ["get", "list", "watch"]
- apiGroups: ["snapshot.storage.k8s.io"]
resources: ["volumesnapshots", "volumesnapshotclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log", "pods/proxy"]
verbs: ["get"]
# pods/proxy is used to fetch Prometheus metrics from the controller pod
Additional Permissions for Benchmark Page
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["create", "delete"]
Binding Example
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: headlamp-tns-csi
subjects:
- kind: ServiceAccount
name: headlamp
namespace: <your-namespace>
roleRef:
kind: ClusterRole
name: headlamp-tns-csi-reader
apiGroup: rbac.authorization.k8s.io
⚠️ Security Best Practices
- Principle of Least Privilege: Grant benchmark write permissions (
jobs create/delete,persistentvolumeclaims create/delete) only to users who need them - Namespace Scoping for Benchmarks: If possible, restrict benchmark Job/PVC permissions to a dedicated benchmark namespace using a namespaced Role rather than ClusterRole
- Pod Proxy Scoping: Scope
pods/proxyaccess tokube-systemonly, or to pods matching the tns-csi controller label - Audit Logging: Enable Kubernetes audit logging to track all API requests made through the plugin
- Image Pinning: Consider pinning
yasker/kbench:latestto a specific digest in your environment for supply chain security
Network Security
Network Policies
If your cluster uses NetworkPolicies, ensure the Kubernetes API server can proxy requests to the tns-csi controller pod on port 8080:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-server-to-tns-csi-controller
namespace: kube-system
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: tns-csi-driver
app.kubernetes.io/component: controller
policyTypes:
- Ingress
ingress:
- ports:
- protocol: TCP
port: 8080
The Kubernetes API server performs the pod proxy hop, so policies should permit the API server (not Headlamp directly) to reach the controller pod.
TLS/HTTPS
- External Access: Always access Headlamp over HTTPS
- Internal Communication: Headlamp to API server uses the service account token over the cluster's internal network
- Pod Proxy: API server → tns-csi controller happens over HTTP within the cluster (port 8080)
Authentication Methods
Service Account (Default)
Headlamp runs with a dedicated service account (headlamp in the namespace where Headlamp is installed). All users share the same RBAC permissions.
Security Considerations:
- All users have identical access to plugin functionality including Benchmark
- Suitable for trusted internal environments
- Simpler RBAC management
OIDC Token Authentication
Headlamp can use per-user OIDC tokens. RBAC is enforced per-user, enabling fine-grained access control:
- Read-only users: bind only the reader ClusterRole
- Benchmark users: bind the additional write permissions
- Users without permissions see appropriate 403 errors
Vulnerability Reporting
Supported Versions
Security updates are applied to the latest release only.
| Version | Supported |
|---|---|
| latest | ✅ |
| < latest | ❌ |
Reporting a Vulnerability
Report security vulnerabilities via:
- GitHub Security Advisories: Report a vulnerability
- GitHub Issues: Open an issue and mark it "security" if advisories are unavailable
Please do not open public GitHub issues for security vulnerabilities before a fix is available.
Response Timeline:
- Acknowledgment: Within 48 hours
- Initial Assessment: Within 1 week
- Fix Timeline: Critical: 1–2 weeks; High: 2–4 weeks; Medium/Low: next release cycle
Dependency Security
The project uses:
- npm audit: Runs automatically during
npm install - Renovate: Automated dependency updates via Mend Renovate (org-wide configured)
Headlamp itself (@kinvolk/headlamp-plugin) is a peer dependency. Security updates to Headlamp should be applied by upgrading your Headlamp installation.
Minimum supported Headlamp version: v0.20.0
Deployment Security Checklist
Before deploying to production:
- RBAC configured: ClusterRole and ClusterRoleBinding exist for Headlamp service account
- Benchmark permissions scoped: Write permissions granted only to appropriate users/groups
- Network policies: Allow API server → tns-csi controller traffic on port 8080
- TLS enabled: Headlamp accessible only via HTTPS
- Audit logging enabled: Kubernetes API audit logs capture requests
- Plugin version: Running latest release
- Dependencies audited:
npm auditshows no critical vulnerabilities
Compliance
Data Residency
All data remains within your Kubernetes cluster. The plugin does not:
- Send data to external services
- Store data in browser localStorage (except any future settings)
- Use third-party analytics or tracking
Audit Trail
All API requests are logged in Kubernetes API audit logs (if enabled). Pod proxy requests to the controller pod's metrics endpoint appear as:
{
"verb": "get",
"requestURI": "/api/v1/namespaces/kube-system/pods/<controller-pod>/proxy/metrics",
"user": {
"username": "system:serviceaccount:<your-namespace>:headlamp"
}
}
Privacy
The plugin processes only technical metadata (resource names, namespaces, CSI parameters, metrics values). No personal data is collected, stored, or transmitted.
Contact
- Security Issues: GitHub Security Advisories
- General Questions: GitHub Discussions
- Bug Reports: GitHub Issues
License
This plugin is provided under the Apache-2.0 License. See LICENSE for details.