Creating a security-first culture within Kubernetes teams starts with one key principle: secure defaults.

Let’s face it—security can’t always be the top priority for every developer, especially when they’re juggling rapid development cycles and the constant push to deliver new features. 

But what if we could make security easier by setting up our environments with secure configurations by default?

That’s the power of secure defaults. By ensuring that Kubernetes clusters, policies, and configurations are designed with security in mind from the start, we can significantly reduce the risk of misconfigurations and vulnerabilities. This approach doesn’t just protect the infrastructure—it also supports developers by removing some of the cognitive load associated with managing complex security settings.

But how can we guarantee that these secure defaults are always enforced, even as teams grow and changes are made?

Enter ValidatingAdmissionPolicy with Common Expression Language (CEL expressions). This powerful feature allows us to enforce security policies at the Kubernetes API server level, ensuring that any resources that don’t comply with our security standards are rejected before they are ever applied to the cluster.

As of Kubernetes version 1.30, ValidatingAdmissionPolicy is a stable feature, making it ready for production use.

Implementing Secure Defaults with ValidatingAdmissionPolicy

Example: Preventing Super Privileged Pods with Exceptions for Necessary System Pods

While setting secure defaults is essential, ensuring that these defaults are enforced cluster-wide is critical to maintaining a robust security posture. Using ValidatingAdmissionPolicy with CEL expressions, we can prevent the deployment of super privileged pods, except for those necessary for Kubernetes system operations.

ValidatingAdmissionPolicy:


apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: disallow-super-privileged-pods
spec:
  paramKind: {}
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["pods"]
  validations:
    - expression: |
        object.metadata.namespace.startsWith('kube-') ||
        !(
          (object.spec.hostPID == true) ||
          (object.spec.hostIPC == true) ||
          (object.spec.hostNetwork == true) ||
          object.spec.containers.exists(c, c.securityContext != null && (c.securityContext.privileged == true || c.securityContext.allowPrivilegeEscalation == true)) ||
          object.spec.initContainers.exists(c, c.securityContext != null && (c.securityContext.privileged == true || c.securityContext.allowPrivilegeEscalation == true)) ||
          object.spec.volumes.exists(v, v.hostPath != null)
        )
      message: "Super privileged pods are not allowed."
  failurePolicy: Fail


Activate the Policy with a Binding:


apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: disallow-super-privileged-pods-binding
spec:
  policyName: disallow-super-privileged-pods
  validationActions:
    - "Deny"


Explanation

The policy denies the creation or update of any pod that meets the conditions of being super privileged with the exception for Pods in namespaces starting with 'kube-', allowing necessary system operations.


  • Applies to all CREATE and UPDATE operations on pods in all namespaces.

  • Allows pods in namespaces starting with 'kube-' (e.g., `kube-system`).

  • Checks if: `hostPID`, `hostIPC`, or `hostNetwork` are set to `true`

  • Containers are in privileged mode or have `allowPrivilegeEscalation` enabled

  • Volumes using `hostPath` mounts


Benefits of this approach:


  1. Guaranteed Enforcement: By enforcing this policy at the API server level, we ensure that no super privileged pods are deployed accidentally or maliciously

  2. Security Compliance: Helps maintain compliance with security best practices and regulatory requirements.

  3. Reduced Attack Surface: Minimizes the risk of privilege escalation attacks and unauthorized access to the host system.

Benefits of ValidatingAdmissionPolicy


  • Guaranteed Enforcement: By using ValidatingAdmissionPolicy with CEL, we enforce security policies at the API server level, ensuring no deviations from our secure defaults.

  • Centralized Control: Policies are managed centrally, making it easier to maintain and audit security configurations across the entire cluster.

  • No need to maintain new tools: With VAP and CEL being integral parts of the Kubernetes API, there is no need or risk of maintaining an additional application for this purpose.

  • Flexibility and Power: CEL expressions provide a powerful and flexible way to define complex validation logic tailored to our specific needs.

  • Alignment with Shift-Left Security: Enforces security policies early in the deployment process, reducing the risk of vulnerabilities reaching production.

  • Developer-Friendly: Developers can focus on building features without worrying about complex security configurations, as the cluster enforces policies automatically.

I recently came across a great article on TL;DR Sec that dives deep into the business of secure defaults, and it reinforced how crucial this concept is for Kubernetes environments. When secure defaults are enforced at the API server level, teams don’t have to be security experts to deploy and manage secure systems. It’s a proactive way of embedding security into the very fabric of our workflows, helping us avoid common pitfalls and build a stronger, more resilient environment.

At Getup, we’ve seen firsthand how leveraging ValidatingAdmissionPolicy with CEL expressions in Kubernetes can simplify security management and foster a culture where security isn’t an afterthought—it’s a given. As we continue developing Zora, we’re committed to making it easier for teams to implement and maintain these secure defaults across their environments.

Note: The ValidatingAdmissionPolicy with CEL expressions is stable as of Kubernetes version 1.30, so make sure your clusters are updated to take advantage of this powerful feature. If your environments are outdated, this might be the first issue to address.

If you haven’t checked out the article yet, I highly recommend it: TL;DR Sec - The Business of Secure Defaults

Final Thoughts

By adopting ValidatingAdmissionPolicy with CEL expressions, we can set and enforce secure defaults, ensuring that our Kubernetes environments remain secure as they evolve. While implementing these policies provides strong security guarantees, identifying where they are needed and ensuring they are correctly configured can be challenging.

That’s why tools like Zora are valuable—they help teams detect misconfigurations and vulnerabilities, providing guidance on where and how to implement secure defaults effectively.

About Getup

At Getup, we’re passionate about making Kubernetes accessible and secure for teams of all sizes. Our product, Zora, is designed to help you identify and address misconfigurations that could be avoided with proper policies in place. By scanning your clusters and providing actionable insights, Zora empowers your team to implement secure defaults and enhance your security posture.

References:


  • Kubernetes Documentation on ValidatingAdmissionPolicy\

  • Common Expression Language deep dive

  • Common Expression Language (CEL) Github

  • Tools to Help Implement Policies:

    • CEL Playground: An interactive tool to learn, test, and validate CEL expressions.

    • Marvin: Our scanner that utilizes CEL expressions to assess Kubernetes resources.

Social

Fale conosco

Almeda Campinas 802, CJ 12, Jardim Paulista,

São Paulo - SP, 01404-001

Faça parte do time

Nossos conteúdos

Social

Fale conosco

Almeda Campinas 802, CJ 12, Jardim Paulista,

São Paulo - SP, 01404-001

Faça parte do time

Nossos conteúdos

Social

Fale conosco

Almeda Campinas 802, CJ 12, Jardim Paulista,

São Paulo - SP, 01404-001

Faça parte do time

Nossos conteúdos