Secure a Kubernetes workload before it ships

Sat Sep 05 2026

Secure a Kubernetes workload before it ships

CVE-2026-19274 was reported with a CVSS score of 9.6 after a namespace-level write permission could reach cluster-wide RBAC impact through an operator’s naming design. Security Arsenal reports no confirmed exploitation as of September 4, 2026. The failure came from the authority around the workload. Its application code was not the problem.

ZeroPath reports that CVE-2026-10840 involved an OpenShift Pipelines operator granting every authenticated cluster user write access to Kueue and cert-manager custom resources. The report says that access could enable workload disruption and certificate overwrites.

But neither incident needed a vulnerable application image to cause trouble. The dangerous object was authority: who could write which resource, and how an operator translated a namespaced object into cluster-wide permissions.

But people keep treating Kubernetes security as image scanning with a few YAML checks attached. That framing misses where the worst failures happen: identity, admission, and the operators trusted to wire them together. These Kubernetes security basics start with the boundaries around the image.

So we’ll follow one workload as it ships. We’ll write the manifest, request access, move images and Secrets through CI, pass admission, restrict network reach, then detect changes and abuse. You don’t need to own every link. You do need to know who does.

In this article

Your Deployment crosses five operational stages

And consider a fictional payments-api Deployment in the payments namespace. It uses one ServiceAccount, reads a database credential from a Secret, connects to an internal database, and runs an image built by CI.

And its path has five operational stages. Identity and manifest review share the first boundary:

  1. Write and request access: your code and deployment identity submit resources to Kubernetes; RBAC decides what they may change.
  2. Build and store the artifact: CI builds, scans, signs, and pushes the image to a registry.
  3. Admit the pod: Pod Security Admission and any additional policy decide whether the pod may run.
  4. Connect the workload: network policy limits reachable services, while Secret configuration controls credential access.
  5. Detect changes: audit logs and runtime signals show who changed the boundary and what happened afterward.

You may control the image, Deployment, ServiceAccount, namespace labels and CI permissions. The platform team may control the API server, etcd and kubelet. It may also control admission configuration, network implementation and the audit pipeline. For identity questions, start with Blackhawk’s identity and access management guidance.

Managed services usually operate much of the control plane, but the exact boundary and available evidence vary by provider. Ask which parts are managed. Ask what you can configure and what proof you can receive. A managed control plane does not make application RBAC, pod policy, image provenance, or Secret access safe automatically.

For payments-api, CI establishes facts about the artifact. RBAC controls who can submit or alter resources. Admission checks dangerous pod settings, while network policy limits reachable workloads. Secret permissions protect the database credential. The platform team should provide configuration evidence for the boundaries it operates.

Your workload should rarely need cluster-wide RBAC

Begin with the ServiceAccount. Then inspect every permission attached to it.

Use a namespace-scoped Role and RoleBinding by default. A ClusterRole or ClusterRoleBinding belongs in the design only when the workload genuinely requires cluster-wide access. A binding to cluster-admin is not a shortcut; it is an admission that nobody has designed the permission the workload actually needs.

For payments-api, ask:

  • Which ServiceAccount does the pod use?
  • Which resources can that identity access?
  • Which verbs are allowed?
  • Does it need list and watch, or only get?
  • Does CI need to create resources across the cluster, or only in payments?
  • Which bindings do operators and Helm charts install?

If the application only consumes a mounted Secret or ConfigMap, it may need no Kubernetes API permission at all. That assumes the kubelet or deployment configuration injects the value; a process that calls the Kubernetes API to fetch it needs explicit permission.

For example, payments-api should have no API access if its database credential arrives through a mounted Secret and the process never queries Kubernetes. Its deployment identity may still need permission to update the Deployment and Service in payments, but that is a separate identity with a separate job.

Least privilege creates debugging friction. “Why can’t CI deploy?” is often the first useful failure because it identifies a permission that someone has failed to design.

An IJERT review of RBAC and ServiceAccount misconfiguration describes risks including privilege escalation, unauthorized resource access, Secret exposure, API abuse, and possible cluster compromise.

The two 2026 operator cases make installed RBAC part of your review. Security Arsenal reports that, in the Instana case, cluster-scoped objects keyed by a bare custom-resource name could collide when identically named resources existed in different namespaces. It reports that namespace-level write access was sufficient to reach a cluster-wide impact.

Your change is a narrow ServiceAccount and a namespaced binding. The platform team’s proof should be a review of cluster-wide bindings, operator-generated RBAC, and the identities allowed to modify them.

Restricted PSA should be a test your pod passes

PodSecurityPolicy was removed in Kubernetes 1.25. Pod Security Standards and the built-in Pod Security Admission controller replaced it, and PSA has been stable since Kubernetes v1.25. The profiles are Privileged, Baseline, and Restricted.

Privileged imposes essentially no restrictions. Baseline blocks known privilege escalations while supporting common workloads. Restricted is the useful target for applications that can meet it.

restricted will reject some ordinary-looking pod manifests. That friction helps you find unsafe settings before deployment.

For payments-api, a Restricted-compatible pod should set allowPrivilegeEscalation: false, use an allowed seccomp profile such as RuntimeDefault, avoid hostPath, avoid privileged containers and init containers, drop restricted capabilities. It should avoid privileged ports. Exact requirements vary by Kubernetes version and the profile version configured by the platform team.

Restricted review itemWhat you check
Privilege escalationSet allowPrivilegeEscalation: false.
SeccompDeclare an allowed profile, commonly RuntimeDefault.
Host filesystem accessRemove hostPath volumes.
Privileged executionKeep containers and init containers unprivileged.
CapabilitiesDrop capabilities the application does not need.
PortsAvoid ports treated as privileged by the active profile.

Namespaces select the PSA mode with labels:

pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/enforce: restricted

audit records violations, warn reports them to the submitting user, and enforce rejects the pod. The Kubernetes Pod Security Admission documentation says namespaces without configuration should be considered unsecured and recommends configuring all namespaces.

A practical rollout starts with audit and warn, then moves to enforce after workloads have been repaired. Validate payments-api against the cluster’s Kubernetes version and the Restricted profile version configured by the platform team. Use the admission response or the platform’s validation report to resolve the exact failure rather than guessing from a generic checklist.

PSA is deliberately coarse. Kyverno or OPA Gatekeeper can add rules for organization-specific requirements, but each adds another admission policy system, test suite, owner, and failure mode. Use one when someone will operate it.

Your change is a pod that passes Restricted or has a documented exception. The platform team’s proof is namespace labeling, enforcement mode, and the validation behavior in the target cluster.

For payments-api, the database password has a storage path

A database password has a storage path, a reader list, and a rotation owner. Treat those as security decisions.

A native Kubernetes Secret stores ordinary data as base64-encoded text. Base64 only encodes the data; it does not encrypt it. Encryption at rest depends on the cluster’s etcd configuration.

Reference the Secret from the workload rather than embedding its value in a repository or plain manifest. For payments-api, the Secret should contain only the database credential it needs, and only the intended ServiceAccount or deployment path should be able to read it.

Ask the platform team for specific evidence:

  • Is etcd encryption at rest enabled?
  • How are encryption keys managed and rotated?
  • Which identities can read Secrets in payments?
  • How are Secret reads recorded without placing Secret values in logs?
  • Which external secret store, if any, owns rotation and recovery?

For self-managed clusters, the API server’s --encryption-provider-config mechanism belongs to control-plane configuration. Developers should not add it to a managed cluster themselves. Ask the operator for the relevant configuration snapshot and its owner.

Encryption at rest protects stored data. It does not stop an overprivileged ServiceAccount from requesting plaintext.

Sealed Secrets, External Secrets Operator, and Vault can fit organizations that already operate an external secret store. The right choice depends on ownership, rotation, recovery, and how applications receive credentials — none of which is visible in a Deployment manifest.

Close the network paths you did not intend to open

RBAC answers what an identity may do through the Kubernetes API. Network policy answers which workloads a pod may reach.

Target a default-deny posture, then add explicit ingress and egress for required traffic. For payments-api, that means permitting its application callers, DNS, the internal database, health checks, and telemetry. It does not mean allowing unrestricted traffic across the namespace.

A practical rollout is to apply the policy in a non-production namespace first, then test each dependency: successful traffic, rejected traffic, DNS resolution, telemetry, and failure behavior. The exact behavior depends on the cluster’s networking implementation.

The network advice deserves the closest scrutiny: default-deny is a sound target, but a manifest alone cannot prove that your CNI, DNS path, and observability stack enforce it correctly. Test those claims in your cluster.

The platform team should identify the supported network-policy features and provide the enforcement evidence. You should document required connections and test them. Network policy limits reachability; RBAC limits API actions. Neither repairs a privileged container or an untrusted image.

Make CI stop the wrong artifact before deployment

Scan the image in CI before it reaches the deployment path. A post-deployment scan cannot stop the original admission unless the cluster separately enforces its result.

Use this sequence:

  • Choose a maintained base image. Record its source and update owner.
  • Scan dependencies and the final image. Use the approved scanner and the organization’s CI exit rule.
  • Pin image references where policy permits. This prevents a deployment from silently selecting a later mutable tag.
  • Sign and verify artifacts where supported. A Sigstore-based workflow can establish who produced an image and whether it changed. The platform must verify the signature somewhere meaningful.
  • Restrict production pulls. Use approved registries and record failed admission or verification results.

Scanning and provenance answer different questions. A scan establishes known-vulnerability status at one point in time; provenance establishes origin and integrity.

Your team owns the Dockerfile, dependencies, CI gate, and image reference. Ask the platform team which registries are allowed, whether signatures are verified at admission, and where a failed verification appears. A signature that nobody checks is decorative paperwork.

Blackhawk’s software supply-chain security guidance covers the broader build and dependency boundary.

Use the CIS Benchmark to assign ownership

The Center for Internet Security maintains the Kubernetes Benchmark as a version-dependent hardening checklist. Juliet describes it as around 120 controls, varying by Kubernetes version, They cover API-server configuration, RBAC and network policy. They also cover pod security, etcd encryption, PKI and kubelet settings.

A benchmark is useful evidence and terrible reading material for a developer who needs to ship today. Match the benchmark version to the cluster, then split the work by artifact:

AreaYou change or verifyThe platform team proves
RBACWorkload identity and bindings are narrow.Cluster-wide bindings and operator permissions are reviewed.
Pod securityThe manifest passes Restricted or has a documented exception.Namespace labels and enforcement modes are configured.
SecretsSecret references and access scope are limited.etcd encryption and key management are operating.
NetworkRequired ingress and egress are documented and tested.The CNI enforces the stated policy.
Control planeDeployment and CI assumptions are recorded.API server, kubelet, PKI, etcd, and audit settings are checked.

The useful interpretation is simple: if a control changes your Deployment, ServiceAccount, namespace labels, image reference, or declared network dependencies, you own the fix. If it changes API-server flags, etcd, kubelet, PKI, or audit retention, request evidence from the platform team.

Ask for different proof at each boundary: a binding review for RBAC, namespace labels for PSA, an encryption configuration snapshot for etcd, an admission result for signatures, and a version-matched benchmark report for the cluster.

Audit logs show who changed the boundary

Runtime monitoring comes after the first controls. Detection does not compensate for cluster-admin, unrestricted Secret access, or an unsigned image.

Security Arsenal’s CVE-2026-19274 analysis recommends capturing create, update, patch, and delete activity involving clusterrolebindings and clusterroles. Capture relevant custom resources too, then ship those records to a SIEM.

The platform team owns the audit policy, retention period, SIEM delivery, and runtime tooling. Ask for a query or alert that identifies new cluster-wide bindings, changes to operator permissions, and relevant Secret access without logging Secret contents. Also ask how an incident involving your workload is investigated.

You should know which signals exist and who receives them. That is enough. You do not need to operate the audit pipeline to notice when nobody can explain it.

Ask these six questions before shipping

  1. Does the pod use a narrowly scoped ServiceAccount?
  2. Has the namespace been tested against Restricted PSA, and are exceptions documented?
  3. Are Secrets encrypted at rest and readable only by identities that need them?
  4. Is networking default-deny with explicit required connections?
  5. Was the image scanned, and can the organization establish its provenance?
  6. Which API-server and kubelet controls belong to the platform team? What about etcd, audit logs, and cluster-wide RBAC? When was each last evidenced?

Ship the manifest with six answers attached; every unanswered platform control needs an owner and a date.