A Practical Guide to Kubernetes Security Management

Published:6 July 2026 - 9 min. read

Audit Active Directory for stale users, weak passwords, and other security risks with Specops Password Auditor.

Kubernetes gives you a flexible way to run containerized applications, but that flexibility cuts both ways. A cluster can be technically healthy and still be risky because a service account has too many permissions, a pod runs as root, a namespace has no network boundaries, or a compromised container starts doing things no one expected.

That is where Kubernetes security management comes in. Instead of treating security as a one-time checklist, you manage the cluster as a living system: define a baseline, scan for drift, restrict workload behavior, segment traffic, and watch runtime activity.

In this tutorial, you will learn how to build that operating model with practical controls you can apply in almost any cluster. You will also see where tools such as Kubescape, Falco, and Microsoft Defender for Containers fit.

Prerequisites

This post is a practical guide, not a lab that requires a dedicated Kubernetes cluster. To follow the examples, you should have:

  • A working Kubernetes cluster or a test cluster such as kind, minikube, AKS, EKS, or GKE.

  • kubectl configured with access to a non-production namespace.

  • Permission to create namespaces, roles, role bindings, and network policies in that test environment.

  • A basic understanding of pods, deployments, services, and namespaces.

[!WARNING]

Do not test security policies in a shared production namespace first. NetworkPolicy, Pod Security, and RBAC changes can block application traffic or break deployments when applied too broadly.

What Kubernetes Security Management Means

Kubernetes security management is the continuous work of reducing the cluster’s attack surface and detecting risky behavior. That definition matters because Kubernetes security is not one control. It is a stack of controls that protect different moments in the workload lifecycle.

A practical Kubernetes security program usually includes:

  • Posture management to find misconfigurations, risky permissions, and compliance gaps.

  • Identity and access management to limit what users and service accounts can do.

  • Pod hardening to keep workloads from running with dangerous defaults.

  • Network segmentation to limit east-west movement inside the cluster.

  • Vulnerability management to track risky images and packages.

  • Runtime detection to catch suspicious process, file, and network activity after a workload starts.

The official Kubernetes security documentation recommends thinking across the entire cluster, including API access, node security, workload isolation, and secrets handling. Start with the Kubernetes project’s own securing a cluster guidance before layering vendor tooling on top.

Kubernetes Security Posture Management (KSPM) is the part of this program that continuously checks whether your cluster and workloads match the security baseline you expect. A KSPM tool does not replace secure design. It gives you a repeatable way to find drift.

Building Your Baseline First

Before you install a scanner, define what good looks like. If you skip this step, every tool becomes a noisy dashboard full of findings no one owns.

Start with a short baseline that your platform and security teams both understand:

  1. Namespaces must have an owner and environment label.

  2. Default service accounts must not be used by application workloads.

  3. Workloads must not run as privileged containers.

  4. Pods must request CPU and memory resources.

  5. Ingress and egress traffic must be intentionally allowed.

  6. Secrets must not be stored in plain text manifests.

  7. Cluster-admin access must be exceptional, time-bound, and reviewed.

You can express part of that baseline directly in Kubernetes. For example, namespace labels let you apply standards and organize scans consistently.

kubectl create namespace payments-dev
kubectl label namespace payments-dev owner=payments env=dev security-tier=restricted

Those labels are simple, but they create a foundation for policy, reporting, and ownership. When a KSPM tool flags a risky deployment, the namespace labels help route the finding to the right team.

[!TIP]

Keep your first baseline small enough to enforce. A ten-rule baseline that teams follow is better than a hundred-rule policy document that no one reads.

Hardening Access with RBAC and Service Accounts

Identity is one of the easiest places to create hidden Kubernetes risk. A deployment that can list secrets, create pods, or update roles has enough power to turn a small compromise into a larger incident.

Kubernetes controls API permissions with Role-Based Access Control (RBAC). The official RBAC documentation explains the full model, but day-to-day hardening usually starts with three habits:

  • Create a dedicated service account per application.

  • Bind only the verbs and resources the application needs.

  • Prefer namespace-scoped Role and RoleBinding objects over cluster-wide permissions.

The following example gives a workload read-only access to ConfigMaps in one namespace. It does not grant access to Secrets, Pods, Deployments, or cluster-wide resources.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: config-reader
  namespace: payments-dev
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: configmap-read-only
  namespace: payments-dev
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: config-reader-binding
  namespace: payments-dev
subjects:
  - kind: ServiceAccount
    name: config-reader
    namespace: payments-dev
roleRef:
  kind: Role
  name: configmap-read-only
  apiGroup: rbac.authorization.k8s.io

After creating a binding, test what the account can do. kubectl auth can-i is one of the fastest ways to catch permission mistakes.

kubectl auth can-i list configmaps \
  --as=system:serviceaccount:payments-dev:config-reader \
  --namespace payments-dev

kubectl auth can-i list secrets \
  --as=system:serviceaccount:payments-dev:config-reader \
  --namespace payments-dev

The first command should return yes; the second should return no. If both return yes, your role is too broad for this example.

Enforcing Safer Pods with Pod Security Standards

RBAC controls what identities can do through the Kubernetes API. Pod hardening controls what containers can do after they are scheduled.

Kubernetes provides Pod Security Standards with three policy levels: Privileged, Baseline, and Restricted. For most application namespaces, Baseline is a practical starting point and Restricted is the goal for workloads that can support it.

You can enforce Pod Security Standards by labeling a namespace:

kubectl label namespace payments-dev \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

This configuration enforces Baseline while warning and auditing against Restricted. That gives teams a migration path. They see what would fail under Restricted before you make Restricted mandatory.

Inside the workload manifest, set a security context. The following snippet shows a safer starting point for many Linux containers:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: payments-api
  namespace: payments-dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: payments-api
  template:
    metadata:
      labels:
        app: payments-api
    spec:
      serviceAccountName: config-reader
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: api
          image: nginx:1.27-alpine
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "256Mi"

This example does not make the application magically secure, but it removes several dangerous defaults. It avoids running as root, uses the runtime default seccomp profile, drops Linux capabilities, blocks privilege escalation, and defines resource boundaries.

Segmenting Traffic with Network Policies

By default, many Kubernetes environments allow pods to communicate freely unless a network policy and a supporting network plugin enforce restrictions. That flat network is convenient for development and dangerous during an incident.

The Kubernetes NetworkPolicy documentation describes how policies select pods and allow traffic. The key word is allow. Once a pod is selected by a NetworkPolicy, only traffic allowed by policy is permitted for that direction.

A good starter pattern is to deny all ingress traffic in a namespace, then add explicit allow rules.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: payments-dev
spec:
  podSelector: {}
  policyTypes:
    - Ingress

Now allow only pods labeled app=frontend to reach the payments API on port 8080:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-payments-api
  namespace: payments-dev
spec:
  podSelector:
    matchLabels:
      app: payments-api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

NetworkPolicy support depends on your cluster’s Container Network Interface (CNI) plugin. If policies do nothing in your test cluster, verify that your CNI supports NetworkPolicy before assuming the YAML is wrong.

[!IMPORTANT]

Network policies are not a substitute for application authentication. They reduce reachable paths inside the cluster, but your application still needs to validate callers and protect sensitive operations.

Running Continuous Posture Scans with Kubescape

After you have a baseline, use KSPM scanning to find drift. Kubescape is a CNCF project that can scan Kubernetes clusters and manifests against security frameworks. The CNCF lists Kubescape as a CNCF project, and the Kubescape documentation covers CLI and in-cluster usage.

A simple local scan usually starts with the CLI:

kubescape scan framework nsa --format pretty-printer

You can also scan manifests before they reach the cluster:

kubescape scan deployment.yaml --format json --output results.json

Use these scans in two places:

  1. CI/CD: block or warn on unsafe manifests before deployment.

  2. Cluster monitoring: detect changes made after deployment, including manual changes and drift.

Do not treat the first scan as a pass/fail event for the whole organization. Initial scans often reveal a backlog. Sort findings by exploitability, workload exposure, and owner. A privileged internet-facing workload deserves attention before a low-risk warning in an internal development namespace.

Detecting Runtime Threats with Falco

Posture management asks, “Is this configured safely?” Runtime detection asks, “What is this workload doing right now?”

Falco is a CNCF graduated runtime security project. The CNCF project page for Falco and the Falco documentation describe how it observes system calls and emits alerts when behavior matches suspicious rules.

A common Falco deployment runs as a DaemonSet so each node has a sensor. Falco can alert on activity such as:

  • A shell spawned inside a container.

  • A process writing to a sensitive path.

  • A container running in privileged mode.

  • Unexpected outbound network tooling.

  • Package manager activity inside a running container.

For example, a Falco rule can identify shell activity in a container. The exact default rules change over time, but the operational response stays the same: enrich the alert with Kubernetes context, identify the workload owner, check whether the activity is expected, and contain the pod or namespace if it is not.

Runtime alerts are most useful when they connect back to the posture baseline. If Falco reports shell activity in a pod that also runs as root and has a broad service account, that is a higher-priority incident than the same alert in an isolated test pod with no API permissions.

Using Microsoft Defender for Containers in Enterprise Environments

Open-source tools are valuable, but many enterprises want Kubernetes findings in the same place as cloud, identity, endpoint, and SIEM alerts. Microsoft Defender for Containers is one option for organizations already using Microsoft Defender for Cloud, Microsoft Sentinel, or Azure Kubernetes Service.

Microsoft’s Defender for Containers overview describes capabilities for Kubernetes posture, vulnerability assessment, and runtime threat protection across supported environments. For Microsoft-heavy teams, the key value is correlation. A Kubernetes alert can sit next to identity, registry, and cloud-resource findings instead of living in a separate tool.

That does not mean every cluster needs the same platform. Use the job-to-be-done model:

Need Good fit
Open-source posture scanning and manifest checks Kubescape
Runtime syscall and container behavior detection Falco
Centralized enterprise CNAPP and Microsoft security integration Microsoft Defender for Containers
Baseline hardening standards Kubernetes Pod Security Standards and CIS Kubernetes Benchmark

The CIS Kubernetes Benchmark is also worth tracking if your organization needs a recognized hardening reference for audits or internal governance.

Creating a Triage Workflow That Teams Follow

Security management fails when findings pile up without ownership. Before adding more tools, decide how a finding moves from detection to remediation.

A practical workflow looks like this:

  1. Detect: A KSPM scan, admission policy, or runtime rule creates a finding.

  2. Enrich: Add namespace, owner, environment, internet exposure, image, service account, and severity.

  3. Prioritize: Rank by exploitability and business impact, not just scanner severity.

  4. Assign: Route to the team that owns the namespace or service.

  5. Fix: Change manifests, RBAC, image versions, or application behavior.

  6. Verify: Re-run the scan or confirm the runtime alert stopped.

  7. Prevent: Add the control to CI/CD, admission policy, or a reusable platform template.

For example, if a scan finds a privileged pod in payments-dev, do not simply close the finding after editing the deployment. Add a namespace-level Pod Security label, update the team’s Helm chart, and add a pipeline check so the same setting does not return next week.

[!NOTE]

The best Kubernetes security program is boring in the right ways: predictable labels, predictable service accounts, predictable policies, and predictable escalation paths.

Putting It All Together

Kubernetes security management works best as a loop. Define your baseline, apply native controls, scan continuously, detect runtime behavior, and feed every lesson back into deployment templates and policy.

Start with the controls Kubernetes already gives you: RBAC, service accounts, Pod Security Standards, resource limits, and NetworkPolicy. Then add KSPM scanning with a tool such as Kubescape so configuration drift becomes visible. Add runtime detection with Falco or a commercial platform so you can see suspicious behavior after containers start. If your organization runs on Microsoft security tooling, evaluate Defender for Containers for centralized posture and alert correlation.

The goal is not to buy one tool and call Kubernetes secure. The goal is to make unsafe changes harder to introduce, risky behavior easier to see, and remediation easier to repeat.

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!