Security Guide
Security best practices for Tenant Operator.
Credentials Management
Database Credentials
Always use Kubernetes Secrets for sensitive data:
yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-credentials
namespace: default
type: Opaque
stringData:
password: your-secure-passwordReference in TenantRegistry:
yaml
spec:
source:
mysql:
passwordRef:
name: mysql-credentials
key: passwordCredential safety
Never hardcode credentials in CRDs or templates. Always reference Kubernetes Secrets.
Rotating Credentials
- Update Secret:
bash
kubectl create secret generic mysql-credentials \
--from-literal=password=new-password \
--dry-run=client -o yaml | kubectl apply -f -- Operator automatically detects change and reconnects.
RBAC
Operator Permissions
The operator requires:
CRD Management:
tenantregistries,tenanttemplates,tenants: All verbs
Resource Management:
- Managed resources (Deployments, Services, etc.): All verbs in target namespaces
namespaces: Create, list, watch, get (cluster-scoped)
Supporting Resources:
events: Create, patchleases: Get, create, update (for leader election)secrets: Get, list, watch (for credentials, namespace-scoped)
Least Privilege
Scope RBAC to specific namespaces when possible:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role # Not ClusterRole
metadata:
name: tenant-operator-role
namespace: production # Specific namespace
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["*"]Service Account
Default service account: tenant-operator-controller-manager
Custom service account:
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: custom-sa
namespace: tenant-operator-system
---
apiVersion: v1
kind: Pod
spec:
serviceAccountName: custom-saMulti-Tenancy Isolation
Work in progress
Document recommended namespace isolation models and network policies.
Data Security
Sensitive Data in Templates
Avoid storing sensitive data in database columns. Instead:
- Store only references:
sql
-- Good
api_key_ref = "secret-acme-api-key"
-- Bad
api_key = "sk-abc123..."- Reference Secrets in templates:
yaml
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: "{{ .uid }}-secrets"
key: api-keyAudit Logging
Enable Audit Logs
Configure Kubernetes audit policy:
yaml
# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
resources:
- group: "operator.kubernetes-tenants.org"
resources: ["tenantregistries", "tenanttemplates", "tenants"]Track Changes
Monitor events:
bash
kubectl get events --all-namespaces | grep TenantCompliance
Data Retention
Configure deletion policies for compliance:
yaml
persistentVolumeClaims:
- id: data
deletionPolicy: Retain # Keep data after tenant deletionImmutable Resources
Use CreationPolicy: Once for audit resources:
yaml
configMaps:
- id: audit-log
creationPolicy: Once # Never updateVulnerability Management
Container Scanning
Scan operator images:
bash
# Using Trivy
trivy image ghcr.io/kubernetes-tenants/tenant-operator:latest
# Using Snyk
snyk container test ghcr.io/kubernetes-tenants/tenant-operator:latestDependency Updates
Keep dependencies updated:
bash
# Update Go dependencies
go get -u ./...
go mod tidy
# Check for vulnerabilities
go list -json -m all | nancy sleuthBest Practices
- Never hardcode credentials - Use Secrets with SecretRef
- Enforce least privilege - Scope RBAC to specific namespaces
- Apply security contexts - Run as non-root, drop capabilities
- Enable audit logging - Track all CRD changes
- Scan container images - Regular vulnerability scanning
- Rotate credentials - Regular password rotation
- Apply network policies - Isolate tenant traffic
- Enforce resource quotas - Prevent resource exhaustion
