Skip to content
kubernetes-security logo

Kubernetes / OpenShift Security Guide

kubernetes-security

Kubernetes and OpenShift security assessment, hardening, and compliance. Use this skill when: (1) Auditing cluster or workload security posture (2) Implementing Pod Security Standards/Admission (3) Configuring RBAC roles and permissions (4) Setting up NetworkPolicies for zero-trust (5) Managing S...

SKILL.md

Full skill instructions

Kubernetes / OpenShift Security Guide

Comprehensive security assessment, hardening, and compliance for production clusters.

Current Security Tools (January 2026)

ToolVersionPurposeDocumentation
Trivy0.58.xVulnerability scanninghttps://aquasecurity.github.io/trivy/
Kyverno1.13.xPolicy enginehttps://kyverno.io/
OPA Gatekeeper3.18.xPolicy enginehttps://open-policy-agent.github.io/gatekeeper/
Falco0.39.xRuntime securityhttps://falco.org/
kube-bench0.8.xCIS benchmarkshttps://github.com/aquasecurity/kube-bench
kubescape3.0.xSecurity posturehttps://kubescape.io/
External Secrets0.12.xSecret managementhttps://external-secrets.io/
Sealed Secrets0.27.xGitOps secretshttps://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 kubectl with oc
  • Standard Kubernetes (AKS, EKS, GKE): Use kubectl as shown

Security Assessment Workflow

  1. Inventory: Identify workloads, namespaces, service accounts
  2. Audit: Run security scans, check configurations
  3. Classify: Risk level based on exposure and sensitivity
  4. Remediate: Apply hardening based on priority
  5. Monitor: Continuous compliance verification

Pod Security Standards (PSS) - Kubernetes 1.31

Security Levels

LevelDescriptionUse Case
privilegedUnrestricted policySystem workloads only
baselineMinimally restrictiveStandard workloads
restrictedHeavily restrictedSecurity-sensitive workloads

Enforcement Modes

ModeBehavior
enforceReject violating pods
auditLog violations, allow pods
warnWarn 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

TypeScopeUse When
RoleNamespaceApp-specific permissions
ClusterRoleCluster-wideCross-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)

  1. restricted-v2 - Default, most restrictive
  2. nonroot-v2 - Must run as non-root
  3. hostnetwork-v2 - Allow host network
  4. anyuid - Run as any UID
  5. privileged - Full privileges (avoid!)

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

More DevOps & CI/CD skills

Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.

6K 472.6K
View

Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.

6K 472.6K
View

Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.

1.5K 454.3K
View
azure-kubernetes logo
DevOps & CI/CD

azure-kubernetes

Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.

1.5K 447.1K
View

Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.

92.7K 354.9K
View
just-scrape logo
DevOps & CI/CD

just-scrape

Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.

69 245K
View

Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.

462 159.7K
View

Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.

462 159.1K
View
deploy-to-vercel logo
DevOps & CI/CD

deploy-to-vercel

Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".

31.9K 146.6K
View
programmatic-seo logo
DevOps & CI/CD

programmatic-seo

Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.

53.3K 140.1K
View

Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.

63 123.5K
View

Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".

31.9K 116.1K
View

Coding & apps AI tools

Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View
I
Coding & apps

Imagica

Build a no-code AI app in minutes.

Freemium
View
E
Coding & apps

Emergent.sh

An IDE for code migration from legacy to modern frameworks through coding agents.

Freemium
View
Wonder Dynamics logo
Coding & apps

Wonder Dynamics

Automate CGI animation in live-action scenes

Paid
View
M
Coding & apps

Mixo

Launch a website in seconds with AI.

Paid
View
AI Code Convert logo
Coding & apps

AI Code Convert

Streamline Your Coding Experience with AI Code Helper

Free
View