Claude-skill-registry kubernetes-security
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/kubernetes-security" ~/.claude/skills/majiayu000-claude-skill-registry-kubernetes-security && rm -rf "$T"
manifest:
skills/data/kubernetes-security/SKILL.mdtags
source content
Kubernetes / OpenShift Security Guide
Comprehensive security assessment, hardening, and compliance for production clusters.
Current Security Tools (January 2026)
| Tool | Version | Purpose | Documentation |
|---|---|---|---|
| Trivy | 0.58.x | Vulnerability scanning | https://aquasecurity.github.io/trivy/ |
| Kyverno | 1.13.x | Policy engine | https://kyverno.io/ |
| OPA Gatekeeper | 3.18.x | Policy engine | https://open-policy-agent.github.io/gatekeeper/ |
| Falco | 0.39.x | Runtime security | https://falco.org/ |
| kube-bench | 0.8.x | CIS benchmarks | https://github.com/aquasecurity/kube-bench |
| kubescape | 3.0.x | Security posture | https://kubescape.io/ |
| External Secrets | 0.12.x | Secret management | https://external-secrets.io/ |
| Sealed Secrets | 0.27.x | GitOps secrets | https://sealed-secrets.netlify.app/ |
Tool Installation
# Trivy brew install trivy # Kyverno CLI brew install kyverno # kubescape curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | /bin/bash # kube-bench (as a Job) kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
Command Usage Convention
IMPORTANT: This skill uses
kubectl as the primary command. When working with:
- OpenShift/ARO clusters: Replace
withkubectloc - Standard Kubernetes (AKS, EKS, GKE): Use
as shownkubectl
Security Assessment Workflow
- Inventory: Identify workloads, namespaces, service accounts
- Audit: Run security scans, check configurations
- Classify: Risk level based on exposure and sensitivity
- Remediate: Apply hardening based on priority
- Monitor: Continuous compliance verification
Pod Security Standards (PSS) - Kubernetes 1.31
Security Levels
| Level | Description | Use Case |
|---|---|---|
| Unrestricted policy | System workloads only |
| Minimally restrictive | Standard workloads |
| Heavily restricted | Security-sensitive workloads |
Enforcement Modes
| Mode | Behavior |
|---|---|
| Reject violating pods |
| Log violations, allow pods |
| Warn user, allow pods |
Namespace Configuration
apiVersion: v1 kind: Namespace metadata: name: ${NAMESPACE} labels: # Enforce restricted standard pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/enforce-version: latest # Audit for baseline pod-security.kubernetes.io/audit: baseline pod-security.kubernetes.io/audit-version: latest # Warn for restricted pod-security.kubernetes.io/warn: restricted pod-security.kubernetes.io/warn-version: latest
Restricted Profile Requirements
spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL # Recommended: readOnlyRootFilesystem: true runAsNonRoot: true
RBAC Best Practices
Principle of Least Privilege
# BAD: Overly permissive rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] # GOOD: Specific permissions rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch"] resourceNames: ["app-config"] # Even more specific
Role vs ClusterRole
| Type | Scope | Use When |
|---|---|---|
| Namespace | App-specific permissions |
| Cluster-wide | Cross-namespace or cluster resources |
Common RBAC Patterns
Read-Only Application Access
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: app-reader namespace: ${NAMESPACE} rules: - apiGroups: [""] resources: ["pods", "services", "configmaps"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["deployments", "replicasets"] verbs: ["get", "list", "watch"]
CI/CD Deployment Access
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: deployer namespace: ${NAMESPACE} rules: - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch"] - apiGroups: [""] resources: ["configmaps", "secrets", "services"] verbs: ["get", "list", "watch", "create", "update", "patch"]
Monitoring Access
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: monitoring-reader rules: - apiGroups: [""] resources: ["pods", "nodes", "services", "endpoints"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get"] - apiGroups: ["metrics.k8s.io"] resources: ["pods", "nodes"] verbs: ["get", "list"]
RBAC Audit Commands
# Check what a service account can do kubectl auth can-i --list --as=system:serviceaccount:${NS}:${SA} # Check specific permission kubectl auth can-i create deployments --as=system:serviceaccount:${NS}:${SA} # Find overly permissive roles kubectl get clusterroles -o json | jq -r \ '.items[] | select(.rules[].verbs | contains(["*"])) | .metadata.name'
NetworkPolicy Zero-Trust
Default Deny All
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all namespace: ${NAMESPACE} spec: podSelector: {} policyTypes: - Ingress - Egress
Allow DNS Egress (Required)
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns namespace: ${NAMESPACE} spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system - podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53
Allow Ingress from Controller
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ingress-controller namespace: ${NAMESPACE} spec: podSelector: matchLabels: app.kubernetes.io/name: ${APP_NAME} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: ingress-nginx ports: - protocol: TCP port: 8080
Allow Inter-Service Communication
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-frontend-to-backend namespace: ${NAMESPACE} spec: podSelector: matchLabels: app.kubernetes.io/name: backend policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app.kubernetes.io/name: frontend ports: - protocol: TCP port: 8080
Secrets Management
External Secrets Operator (v0.12.x)
# Install helm repo add external-secrets https://charts.external-secrets.io helm install external-secrets external-secrets/external-secrets \ --namespace external-secrets \ --create-namespace \ --set installCRDs=true
# ClusterSecretStore for Vault apiVersion: external-secrets.io/v1beta1 kind: ClusterSecretStore metadata: name: vault-backend spec: provider: vault: server: "https://vault.example.com" path: "secret" version: "v2" auth: kubernetes: mountPath: "kubernetes" role: "external-secrets" --- apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: app-secrets namespace: ${NAMESPACE} spec: refreshInterval: 1h secretStoreRef: name: vault-backend kind: ClusterSecretStore target: name: app-secrets creationPolicy: Owner data: - secretKey: DATABASE_URL remoteRef: key: apps/${APP_NAME} property: database_url
Sealed Secrets (GitOps-friendly, v0.27.x)
# Install helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets helm install sealed-secrets sealed-secrets/sealed-secrets \ --namespace kube-system # Install CLI brew install kubeseal # Create sealed secret kubeseal --format=yaml < secret.yaml > sealed-secret.yaml # Apply (controller decrypts it) kubectl apply -f sealed-secret.yaml
OpenShift Security Context Constraints
SCC Hierarchy (Most to Least Restrictive)
- Default, most restrictiverestricted-v2
- Must run as non-rootnonroot-v2
- Allow host networkhostnetwork-v2
- Run as any UIDanyuid
- Full privileges (avoid!)privileged
Check SCC Assignment
# See which SCC a pod is using oc get pod ${POD} -n ${NS} -o yaml | grep scc # List available SCCs oc get scc # Check SA SCC permissions oc adm policy who-can use scc restricted-v2
Grant SCC to Service Account
oc adm policy add-scc-to-user ${SCC} -z ${SERVICE_ACCOUNT} -n ${NAMESPACE}
# Via RoleBinding (GitOps-friendly) apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ${SA}-scc-${SCC} namespace: ${NAMESPACE} roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:openshift:scc:${SCC} subjects: - kind: ServiceAccount name: ${SERVICE_ACCOUNT} namespace: ${NAMESPACE}
Image Security
Trivy Scanning
# Scan image for vulnerabilities trivy image ${IMAGE}:${TAG} # Scan with severity filter trivy image --severity HIGH,CRITICAL ${IMAGE}:${TAG} # Scan and output JSON trivy image -f json -o results.json ${IMAGE}:${TAG} # Scan Kubernetes cluster trivy k8s --report summary cluster
Kyverno Policy Examples
# Require non-root containers apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-run-as-nonroot spec: validationFailureAction: enforce rules: - name: run-as-non-root match: resources: kinds: - Pod validate: message: "Containers must run as non-root" pattern: spec: containers: - securityContext: runAsNonRoot: true --- # Block privileged containers apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: disallow-privileged spec: validationFailureAction: enforce rules: - name: deny-privileged match: resources: kinds: - Pod validate: message: "Privileged containers are not allowed" pattern: spec: containers: - securityContext: privileged: "!true"
Security Audit Script
#!/bin/bash echo "=== KUBERNETES SECURITY AUDIT ===" # Check for privileged containers echo "### Privileged Containers ###" kubectl get pods -A -o json | jq -r \ '.items[] | select(.spec.containers[].securityContext.privileged == true) | "\(.metadata.namespace)/\(.metadata.name)"' # Check for root containers echo -e "\n### Containers Running as Root ###" kubectl get pods -A -o json | jq -r \ '.items[] | select(.spec.containers[].securityContext.runAsUser == 0) | "\(.metadata.namespace)/\(.metadata.name)"' # Check for host namespace access echo -e "\n### Host Namespace Access ###" kubectl get pods -A -o json | jq -r \ '.items[] | select(.spec.hostNetwork == true or .spec.hostPID == true) | "\(.metadata.namespace)/\(.metadata.name)"' # Check for default service accounts echo -e "\n### Pods Using Default SA ###" kubectl get pods -A -o json | jq -r \ '.items[] | select(.spec.serviceAccountName == "default") | "\(.metadata.namespace)/\(.metadata.name)"' # Check for overly permissive RBAC echo -e "\n### Wildcard RBAC Roles ###" kubectl get clusterroles -o json | jq -r \ '.items[] | select(.rules[].verbs | contains(["*"])) | .metadata.name' # Check namespaces without NetworkPolicy echo -e "\n### Namespaces Without NetworkPolicy ###" for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do count=$(kubectl get networkpolicy -n $ns --no-headers 2>/dev/null | wc -l) [ "$count" -eq 0 ] && echo "$ns" done
CIS Benchmark Compliance
# Run kube-bench kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml kubectl logs -f job/kube-bench # Run kubescape kubescape scan framework nsa --exclude-namespaces kube-system kubescape scan framework cis-v1.23-t1.0.1