Files
privilegedescalation-ceo[bot] 2e2713fd3f docs: replace hardcoded namespace with <your-namespace> placeholder
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>
2026-05-10 21:34:56 +00:00

244 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-plugin` for identification
- Created only in the namespace the user explicitly selects
- Automatically deleted when the benchmark completes or is stopped
- Using the `yasker/kbench:latest` image (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
```yaml
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
```yaml
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["create", "delete"]
```
### Binding Example
```yaml
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
1. **Principle of Least Privilege**: Grant benchmark write permissions (`jobs create/delete`, `persistentvolumeclaims create/delete`) only to users who need them
2. **Namespace Scoping for Benchmarks**: If possible, restrict benchmark Job/PVC permissions to a dedicated benchmark namespace using a namespaced Role rather than ClusterRole
3. **Pod Proxy Scoping**: Scope `pods/proxy` access to `kube-system` only, or to pods matching the tns-csi controller label
4. **Audit Logging**: Enable Kubernetes audit logging to track all API requests made through the plugin
5. **Image Pinning**: Consider pinning `yasker/kbench:latest` to 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`:
```yaml
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:
1. **GitHub Security Advisories**: [Report a vulnerability](https://github.com/privilegedescalation/headlamp-tns-csi-plugin/security/advisories/new)
2. **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: 12 weeks; High: 24 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 audit` shows 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:
```json
{
"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](https://github.com/privilegedescalation/headlamp-tns-csi-plugin/security/advisories)
- **General Questions**: [GitHub Discussions](https://github.com/privilegedescalation/headlamp-tns-csi-plugin/discussions)
- **Bug Reports**: [GitHub Issues](https://github.com/privilegedescalation/headlamp-tns-csi-plugin/issues)
## License
This plugin is provided under the Apache-2.0 License. See [LICENSE](LICENSE) for details.