<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Bits, Bots & Business]]></title><description><![CDATA[Where DevOps meets AI, software engineering meets startups, and tech decisions meet business impact.]]></description><link>https://blog.mrashed.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1768343970224/d55552be-29de-49c6-9e8a-99daaaed7a7d.png</url><title>Bits, Bots &amp; Business</title><link>https://blog.mrashed.com</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Apr 2026 18:59:09 GMT</lastBuildDate><atom:link href="https://blog.mrashed.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The "No" Button: Stopping Bad Configs Before They Wake You Up at 3 AM]]></title><description><![CDATA[You get a Slack message at 8 PM. A critical production service is down. After an hour of frantic debugging, you find the cause: a developer deployed a new version without resource limits, and the pod went rogue, triggering a cascading failure. We've ...]]></description><link>https://blog.mrashed.com/the-no-button-stopping-bad-configs-before-they-wake-you-up-at-3-am</link><guid isPermaLink="true">https://blog.mrashed.com/the-no-button-stopping-bad-configs-before-they-wake-you-up-at-3-am</guid><category><![CDATA[PolicyAsCode]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Platform Engineering ]]></category><category><![CDATA[kyverno]]></category><dc:creator><![CDATA[Mahmoud Rashed]]></dc:creator><pubDate>Fri, 23 Jan 2026 15:23:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769180538730/0e13e19e-af69-48ae-b0df-a217e573007f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You get a Slack message at 8 PM. A critical production service is down. After an hour of frantic debugging, you find the cause: a developer deployed a new version without resource limits, and the pod went rogue, triggering a cascading failure. We've all been there. Managing multiple Kubernetes clusters and development teams can feel like a constant battle against inconsistency and overlooked best practices.</p>
<p>In the previous two articles in this series, we covered the foundations of policy-as-code and explored the magic of mutation policies for automatically correcting configurations. Now, we turn our attention to the most powerful tool in the policy engine arsenal: <strong>Validation Policies</strong>. This article will focus on the most impactful and perhaps counter-intuitive uses of Validation Policies with Kyverno, presenting them not as a tool for enforcement, but for empowerment.</p>
<h1 id="heading-guardrails-not-gates-helping-devs-without-being-a-blocker"><strong>Guardrails, not Gates: Helping Devs Without Being a Blocker</strong></h1>
<p>The most effective policy strategy isn't about building gates that simply block developers when they do something wrong. It's about creating "guardrails" that gently guide them toward best practices, making the right way the easy way.</p>
<p>This philosophy is where Kyverno’s simplicity shines. Unlike tools that require learning a specialized language like Rego, Kyverno uses simple, declarative YAML for policy definitions. This approachability makes it easier for platform and development teams to collaborate on policy creation and maintenance. Instead of a complex, opaque language owned by a central team, policies become shared artifacts that everyone can understand and contribute to.</p>
<p>A great analogy for this is a validated drop-down list in a web form. The dropdown is a <strong>preventive control</strong>; it stops you from entering bad data from the very start. But it does so in a helpful, intuitive way by showing you the valid options. A good Kyverno policy works the same way. It prevents a misconfigured resource from ever entering the cluster, but when paired with clear error messages, it teaches the developer what needs to be fixed.</p>
<p>This turns policy management from a confrontational process into a collaborative one, improving both security posture and developer velocity. This isn't just about developer happiness; it's about shipping more secure code, faster, by shrinking the feedback loop from days (in a security review) to seconds (at <code>kubectl apply</code>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769181007123/c9c73943-fabf-48cd-8c5d-23319082a1bf.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-the-root-of-all-evil-why-we-block-root-users"><strong>The "Root" of all Evil: Why We Block Root Users</strong></h1>
<p>One of the most fundamental Kubernetes security best practices is to prevent containers from running as the root user. Allowing root access inside a container is a major security risk, opening the door to privilege escalation attacks if a vulnerability is exploited. Enforcing this rule manually across hundreds or thousands of workloads is impossible.</p>
<p>This is a perfect use case for a preventive validation policy. With a few lines of YAML, you can create a cluster-wide rule that automatically blocks any pod that attempts to run as root.</p>
<p>Here is a simple Kyverno <code>ClusterPolicy</code> that uses a Common Expression Language (CEL) expression to validate that pods are configured to run as a non-root user:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">kyverno.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ClusterPolicy</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">disallow-root-user</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">validationFailureAction:</span> <span class="hljs-string">Enforce</span>
  <span class="hljs-attr">rules:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">validate-run-as-non-root</span>
      <span class="hljs-attr">match:</span>
        <span class="hljs-attr">resources:</span>
          <span class="hljs-attr">kinds:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Pod</span>
      <span class="hljs-attr">validate:</span>
        <span class="hljs-attr">cel:</span>
          <span class="hljs-attr">expression:</span> <span class="hljs-string">"object.spec.securityContext.runAsNonRoot == true"</span>
</code></pre>
<p>This simple, declarative rule is incredibly powerful. It enforces a critical security standard across the entire cluster without any manual intervention. It's a classic example of a powerful preventive control that eliminates an entire class of security risks before a workload is even scheduled.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769181091754/47467151-cc5f-4e3f-afa8-2e57b1f6320d.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-audit-mode-how-to-test-rules-without-causing-a-mass-revolt"><strong>Audit Mode: How to Test Rules Without Causing a Mass Revolt</strong></h1>
<p>A common pitfall I see is platform teams rolling out a new, strict policy that immediately breaks existing workflows or blocks a critical production deployment. This is the moment where the platform team is seen as a blocker, causing friction and frustration. How do you enforce standards without causing a developer revolt?</p>
<p>This is where Kyverno’s distinction between preventive (<code>Enforce</code>) and detective (<code>Audit</code>) controls becomes a lifesaver.</p>
<p>• <strong>Enforce Mode:</strong> This is a <strong>preventive</strong> control. It actively blocks any resource that violates the policy before it can be created or updated in the cluster.</p>
<p>• <strong>Audit Mode:</strong> This is a <strong>detective</strong> control. It allows non-compliant resources to be created but flags them for review by generating policy reports.</p>
<p>This dual-mode capability allows for a safe, gradual rollout strategy. As Adevinta's engineering team noted in their tech blog on their transition to Kyverno:</p>
<p>"In audit mode, Kyverno will not reject any request but instead will produce a resource inside the cluster called ’<a target="_blank" href="http://admissionreport.kyverno.io">admissionreport.kyverno.io</a>’ and also ‘<a target="_blank" href="http://policyreport.kyverno.io">policyreport.kyverno.io</a>’."</p>
<p>This enables a practical and low-stress workflow for introducing new policies:</p>
<p>1. <strong>Deploy in Audit Mode:</strong> Initially, deploy all new policies with <code>validationFailureAction: Audit</code>.</p>
<p>2. <strong>Monitor Reports:</strong> Observe the generated policy reports to see which existing workloads are non-compliant and understand the real-world impact of the new rule.</p>
<p>3. <strong>Collaborate and Remediate:</strong> Work with the relevant development teams to help them fix their configurations based on the audit data.</p>
<p>4. <strong>Switch to Enforce Mode:</strong> Once you’ve confirmed that all critical workloads are compliant, you can confidently switch the policy to <code>validationFailureAction: Enforce</code>, knowing it won't cause unexpected disruptions.</p>
<p>This feature transforms policy implementation from a high-risk, all-or-nothing event into a gradual, data-driven process that builds trust between platform and development teams.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769181147969/36e00c07-71bf-4305-89d4-d9354de96bbb.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-cel-expressions-its-like-excel-formulas-but-for-kubernetes-security"><strong>CEL Expressions: It’s Like Excel Formulas, but for Kubernetes Security</strong></h1>
<p>One of the game-changing features in modern Kubernetes policy enforcement is the <strong>Common Expression Language (CEL)</strong>. CEL provides a standardized, declarative way to write validation logic directly into Kubernetes resources. This is a significant shift: for many common validation rules, you may no longer need a separate policy engine like Gatekeeper or even Kyverno's own pattern-matching engine; you can use the native capabilities that Kubernetes now provides. And because Kyverno offers first-class support for this standard, it gives you an incredibly powerful toolset.</p>
<p>Think of CEL expressions like writing formulas in a spreadsheet. You're given an <code>object</code> (the Kubernetes resource YAML being submitted) and you can write simple, powerful expressions to inspect its fields and validate its contents.</p>
<p>Here are a few common examples of what you can do with CEL:</p>
<p>• <strong>Checking for a specific label:</strong> <a target="_blank" href="http://object.metadata.labels.team"><code>object.metadata.labels.team</code></a> <code>== 'platform'</code> This simple check ensures a resource is correctly attributed to the platform team.</p>
<p>• <strong>Ensuring all containers have CPU limits:</strong></p>
<p>• This prevents runaway processes from starving other workloads and causing cluster-wide instability.</p>
<p>• <strong>Requiring at least one annotation:</strong> <code>has(object.metadata.annotations) &amp;&amp; object.metadata.annotations.size() &gt; 0</code> This is useful for ensuring resources have the necessary metadata for monitoring or automation tools.</p>
<p>• <strong>Validating an image registry using regex:</strong> <code>object.spec.containers.all(container, container.image.matches('^</code><a target="_blank" href="http://my-trusted-registry.io/.*"><code>my-trusted-registry.io/.*</code></a><code>'))</code> This is a critical supply-chain security control, ensuring that only vetted images from your organization's registry can run in the cluster.</p>
<p>With CEL, you get a simple yet incredibly powerful way to write complex, fine-grained validation rules directly in your Kyverno policies, making them more expressive and easier to maintain.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769181200753/d6325065-505c-45cf-a3f9-b779fab40245.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-real-talk-how-to-gently-force-people-to-use-labels"><strong>Real Talk: How to Gently Force People to Use Labels</strong></h1>
<p>A common problem in any large cloud or Kubernetes environment is inconsistent or missing labels. Without proper tagging, it becomes nearly impossible to answer basic questions like, "How much does this application cost?" or "Who owns this service?" This lack of metadata hygiene leads to operational blind spots and makes cost allocation a nightmare.</p>
<p>The solution is to define a tagging standard and then enforce it with a validation policy. First, decide on a set of required labels (e.g., <code>app</code>, <code>owner</code>, <code>cost-center</code>). Second, create a Kyverno policy to ensure every new resource has them.</p>
<p>This <code>ClusterPolicy</code> uses CEL to validate that all new Deployments contain the required labels:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">kyverno.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ClusterPolicy</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">require-standard-labels</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">validationFailureAction:</span> <span class="hljs-string">Enforce</span>
  <span class="hljs-attr">rules:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">check-for-standard-labels</span>
      <span class="hljs-attr">match:</span>
        <span class="hljs-attr">resources:</span>
          <span class="hljs-attr">kinds:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Deployment</span>
      <span class="hljs-attr">validate:</span>
        <span class="hljs-attr">cel:</span>
          <span class="hljs-attr">expression:</span> <span class="hljs-string">"has(object.metadata.labels) &amp;&amp; ['app', 'owner', 'cost-center'].all(key, key in object.metadata.labels)"</span>
</code></pre>
<p>A policy like this is the perfect candidate for the "Audit-then-Enforce" strategy. You can start by deploying it in <code>Audit</code> mode to discover which teams need to update their deployment manifests. This approach prevents the developer revolt that often happens when governance teams try to enforce tagging standards retroactively. It's about learning from the common mistakes seen in other ecosystems (like Azure) and applying a more intelligent, DevOps-native solution. This is the "gentle" part of the enforcement. Once you've given teams time to comply, you can switch to <code>Enforce</code> mode.</p>
<p>The payoff is immense: operational blind spots are eliminated, 'who owns this?' becomes a solved problem. Finance teams can finally get the clear cost allocation reports they've been asking for. This isn't just about hygiene; it's about running Kubernetes like a business.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769181288833/0d59f5bb-7570-4c04-a25d-69146b1dbde7.png" alt class="image--center mx-auto" /></p>
<hr />
<h1 id="heading-conclusion"><strong>Conclusion</strong></h1>
<p>Kyverno's validation policies are more than just a security tool; they are a flexible, powerful, and developer-friendly way to bring order and sanity to your Kubernetes clusters. By acting as helpful guardrails, offering a safe audit mode for rollouts, leveraging the power of CEL, and enforcing operational best practices like tagging, you can build a more secure, reliable, and collaborative platform.</p>
<p>To leave you with a final thought: <strong>What is the one small, unenforced standard in your cluster that, if automated with a policy, would have the biggest positive impact?</strong></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you found this useful, subscribe to our newsletter for more deep dives into cloud-native technologies. In the next article in this series, we’ll explore <strong>Generation Policies</strong> and show how they can automatically create resources like NetworkPolicies and RBAC rules to secure further and standardize your workloads.</div>
</div>

<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769181679746/364a5b97-a5c4-4580-8dc8-ad62cbc7a4e7.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-recommended-reading-amp-resources">📚 Recommended Reading &amp; Resources</h3>
<ul>
<li><p><strong>The "Real World" Story</strong> <a target="_blank" href="https://adevinta.com/techblog/opa-memory-usage-considerations-and-lessons-from-our-transition-to-kyverno/"><strong>Scaling Policy Enforcement: Lessons from Adevinta’s Migration</strong></a><strong>.</strong> <em>The engineering blog post is referenced in this article. A must-read for understanding the operational side of moving to Kyverno and the memory/performance benefits observed at scale.</em></p>
</li>
<li><p><strong>The Sandbox</strong> <a target="_blank" href="https://playground.kyverno.io/"><strong>Kyverno Policy Playground</strong></a><strong>.</strong> <em>Don't test in production! Use this interactive playground to write, test, and debug your validation policies and CEL expressions directly in your browser before applying them to your cluster.</em></p>
</li>
<li><p><strong>The Official Guide</strong> <a target="_blank" href="https://kyverno.io/docs/policy-types/cluster-policy/validate/"><strong>Kyverno Validation Rules Documentation</strong></a><strong>:</strong> <em>The complete reference for writing validation policies, including deep dives on patterns, anchors, and failure actions.</em></p>
</li>
<li><p><strong>The Deep Dive</strong> <a target="_blank" href="https://kubernetes.io/docs/reference/using-api/cel/"><strong>Kubernetes Common Expression Language (CEL) Reference:</strong></a> <em>Everything you need to know about the syntax and capabilities of CEL within Kubernetes. Bookmark this for when you need to write complex logic that goes beyond simple pattern matching.</em></p>
</li>
<li><p><strong>The "Why"</strong> <a target="_blank" href="https://www.cncf.io/blog/2025/01/13/cel-ebrating-simplicity-mastering-kubernetes-policy-enforcement-with-cel/"><strong>CEL-ebrating Simplicity: Mastering Kubernetes Policy Enforcement.</strong></a> <em>A great overview from the CNCF blog on why the industry is shifting toward CEL and how it simplifies the policy landscape for platform engineers.</em></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The Kubernetes Cleaning Fairy: Fixing Messy Manifests with Mutation]]></title><description><![CDATA[In a previous article, we laid the foundations for governing Kubernetes clusters, focusing on how admission policies act as essential gatekeepers. They ensure that only compliant, secure, and well-formed resources make it into your environment. But w...]]></description><link>https://blog.mrashed.com/the-kubernetes-cleaning-fairy-fixing-messy-manifests-with-mutation</link><guid isPermaLink="true">https://blog.mrashed.com/the-kubernetes-cleaning-fairy-fixing-messy-manifests-with-mutation</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[Platform Engineering ]]></category><category><![CDATA[kyverno]]></category><category><![CDATA[Devops]]></category><category><![CDATA[policy as code]]></category><category><![CDATA[cloud native]]></category><dc:creator><![CDATA[Mahmoud Rashed]]></dc:creator><pubDate>Mon, 19 Jan 2026 22:08:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768860396941/9fb5fb25-107b-45c4-82cc-14ccbc9ca486.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In a previous article, we laid the foundations for governing Kubernetes clusters, focusing on how admission policies act as essential gatekeepers. They ensure that only compliant, secure, and well-formed resources make it into your environment. But what if we could go beyond simple rejection or validation? What if the platform could not only identify problems but also automatically fix them?</p>
<p>This article dives into a more proactive and powerful tool in the platform engineer's arsenal: mutation policies. We'll explore how mutation works not just as a gatekeeper, but as a helpful assistant that corrects and enhances resources before they are even created. This shift from "<strong><em>rejecting the bad</em></strong>" to "perfecting the good" is a game-changer that turns your platform from a gatekeeper into a <em>collaborator</em>, actively improving developer velocity and reducing rework.</p>
<h1 id="heading-dont-reject-correct-being-a-helpful-platform-engineer">Don't Reject, Correct: Being a helpful platform engineer.</h1>
<p>The traditional approach to <strong>Kubernetes policy enforcement</strong> is strict validation: if a resource manifest (YAML) breaks the rules, the API server rejects it. The developer receives an error message and must return to their editor to fix the code. However, <strong>Mutation Policies</strong> offer a more collaborative alternative: <strong>proactive correction</strong>.</p>
<h2 id="heading-the-concept-of-proactive-correction">The Concept of Proactive Correction</h2>
<p>Mutation policies act as a "preventive control," transforming the platform into a helpful partner rather than a gatekeeper. Instead of blocking a deployment with a "no," the platform automatically fixes common omissions or misconfigurations—such as adding missing labels or setting default resource limits. This reduces developer friction, minimizes context switching, and ensures <strong>compliance by default</strong>.</p>
<h2 id="heading-a-preventative-control-stops-something-from-happening-it-prevents-it">A preventative control stops something from happening; it <em>prevents</em> it.</h2>
<p>By automatically correcting resources, the platform becomes a partner in the development process rather than just a critic. This significantly reduces developer friction and improves the overall experience of using the platform.</p>
<h2 id="heading-the-admission-controller-order">The Admission Controller Order</h2>
<p>The power to automatically correct resources lies in the <a target="_blank" href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/"><strong>Kubernetes Admission Controller</strong></a> order.</p>
<p>When a developer runs <code>kubectl apply</code>The request traverses several steps. <strong>Mutating Admission Webhooks</strong> trigger first—even before schema validation. This allows the platform to patch the resource definition on the fly. This architecture enables a true <strong>"shift-left" approach</strong> to compliance, solving issues at the earliest possible moment: API admission time.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768856712896/8240863c-60cd-409e-be87-9a8e29d2af06.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-the-oops-i-forgot-limits-fixer-upper">The "Oops, I Forgot Limits" Fixer-Upper.</h1>
<p>Here’s a classic Kubernetes scenario: a developer focuses on application logic but forgets to define <a target="_blank" href="https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/"><strong>resource requests and limits</strong></a> in their deployment manifest. A strict validation policy would reject the deployment, forcing the developer to context-switch and edit their YAML. While secure, this creates friction.</p>
<p>A <a target="_blank" href="https://www.google.com/search?q=https://kyverno.io/docs/writing-policies/mutate/"><strong>Kyverno mutation policy</strong></a> solves this by proactively fixing the manifest. Instead of rejecting the workload, the admission controller intercepts the request and automatically injects sensible default values for CPU and memory. This ensures that no pod runs without limits—crucial for <strong>cluster stability</strong> and preventing "<a target="_blank" href="https://www.google.com/search?q=https://kubernetes.io/blog/2016/06/quality-of-service-classes-kubernetes/">noisy neighbor</a>" issues—while maintaining a frictionless developer experience.</p>
<h3 id="heading-example-kyverno-clusterpolicy-for-default-limits">Example: Kyverno ClusterPolicy for Default Limits</h3>
<p>The following <code>ClusterPolicy</code> checks any Pod; if resource limits are missing, it patches them in automatically:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">kyverno.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ClusterPolicy</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">add-default-resources</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">add-default-cpu-memory-limits</span>
    <span class="hljs-attr">match:</span>
      <span class="hljs-attr">any:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">resources:</span>
          <span class="hljs-attr">kinds:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-string">Pod</span>
    <span class="hljs-attr">mutate:</span>
      <span class="hljs-attr">patchStrategicMerge:</span>
        <span class="hljs-attr">spec:</span>
          <span class="hljs-attr">containers:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-string">(name):</span> <span class="hljs-string">"*"</span>
            <span class="hljs-attr">resources:</span>
              <span class="hljs-attr">limits:</span>
                <span class="hljs-string">+(cpu):</span> <span class="hljs-string">"1"</span>
                <span class="hljs-string">+(memory):</span> <span class="hljs-string">"1Gi"</span>
              <span class="hljs-attr">requests:</span>
                <span class="hljs-string">+(cpu):</span> <span class="hljs-string">"100m"</span>
                <span class="hljs-string">+(memory):</span> <span class="hljs-string">"256Mi"</span>
</code></pre>
<h3 id="heading-understanding-the-syntax">Understanding the Syntax</h3>
<p>This policy uses specific Kyverno features to ensure precise application:</p>
<ul>
<li><p><code>patchStrategicMerge</code>: A declarative method for modifying resources. It is ideal for adding fields to a known structure without overwriting existing data.</p>
</li>
<li><p><code>(name): "*"</code>: A <a target="_blank" href="https://www.google.com/search?q=https://kyverno.io/docs/writing-policies/mutate/%23anchors"><strong>conditional anchor</strong></a> that acts as a wildcard, ensuring the patch applies to <em>all</em> containers within the pod spec.</p>
</li>
<li><p><code>+(cpu)</code> / <code>+(memory)</code>: The <code>+</code> The anchor is the key logic here. It instructs Kyverno to add the field <em>only if it is not already present</em>. If a developer <em>has</em> set a limit, this policy respects it and does nothing.</p>
</li>
</ul>
<h3 id="heading-impact-analysis">Impact Analysis</h3>
<p>This policy instantly improves <strong>Kubernetes governance</strong>. It guarantees fair resource allocation and prevents Out-Of-Memory (OOM) kills caused by uncapped containers, all without requiring manual intervention from the development team.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768857786579/448cd1f7-c0d0-437b-9ef5-2756e7c75849.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-invisible-sidecars-injecting-containers-like-a-ninja">Invisible Sidecars: Injecting Containers Like a Ninja</h1>
<p>If you've ever used a service mesh like Istio or an observability tool like the OpenTelemetry Operator, you've witnessed the magic of mutation. These tools use mutating webhooks to inject "sidecar" containers into your application pods automatically.</p>
<h2 id="heading-automating-sidecar-injection-with-mutation-policies">Automating Sidecar Injection with Mutation Policies</h2>
<p>If you have used a service mesh like <strong>Istio</strong> or an observability tool like the <a target="_blank" href="https://opentelemetry.io/docs/kubernetes/operator/"><strong>OpenTelemetry Operator</strong></a>, you have already witnessed the power of mutation. These tools leverage <strong>Mutating Admission Webhooks</strong> to automatically inject "sidecar" containers into application pods.</p>
<h3 id="heading-understanding-the-sidecar-pattern-in-platform-engineering">Understanding the Sidecar Pattern in Platform Engineering</h3>
<p><a target="_blank" href="https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/">Sidecar injection</a> is a core pattern in modern platform engineering. It allows platform teams to transparently add capabilities—such as logging, proxying, or security monitoring—to application pods without requiring developers to modify their deployment manifests. This ensures a clean <strong>separation of concerns</strong>: developers focus on business logic, while the platform handles infrastructure requirements.</p>
<h3 id="heading-real-world-examples-of-sidecar-injection">Real-World Examples of Sidecar Injection</h3>
<p>The <strong>Kubernetes Admission Controller</strong> enables several common automation scenarios:</p>
<ul>
<li><p><a target="_blank" href="https://istio.io/latest/docs/ops/deployment/architecture/"><strong>Istio Service Mesh</strong></a><strong>:</strong> Automatically adds an Envoy proxy sidecar to every pod to manage traffic, enforce mTLS, and gather telemetry.</p>
</li>
<li><p><strong>OpenTelemetry (OTel):</strong> Injects a collector sidecar to scrape metrics and traces, or adds an <strong>Init Container</strong> to auto-instrument the application before it starts.</p>
</li>
</ul>
<h3 id="heading-implementing-injection-with-kyverno-and-json-patch">Implementing Injection with Kyverno and JSON Patch</h3>
<p>While simple validations can use overlay patterns, complex injections often require <code>patchesJson6902</code>. This method is based on the imperative <a target="_blank" href="https://datatracker.ietf.org/doc/html/rfc6902"><strong>JSON Patch standard (RFC 6902)</strong></a>, making it ideal for structured modifications like appending items to a list.</p>
<p>Below is a Kyverno policy that injects a logging sidecar into any pod annotated with <code>logging-enabled: "true"</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">kyverno.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ClusterPolicy</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">add-logging-sidecar</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">inject-logging-container</span>
    <span class="hljs-attr">match:</span>
      <span class="hljs-attr">any:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">resources:</span>
          <span class="hljs-attr">kinds:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-string">Pod</span>
          <span class="hljs-attr">annotations:</span>
            <span class="hljs-attr">logging-enabled:</span> <span class="hljs-string">"true"</span>
    <span class="hljs-attr">mutate:</span>
      <span class="hljs-attr">patchesJson6902:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">"/spec/containers/-"</span>
        <span class="hljs-attr">op:</span> <span class="hljs-string">add</span>
        <span class="hljs-attr">value:</span>
          <span class="hljs-attr">name:</span> <span class="hljs-string">logging-sidecar</span>
          <span class="hljs-attr">image:</span> <span class="hljs-string">fluent/fluent-bit:latest</span>
          <span class="hljs-attr">args:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-string">"tail"</span>
          <span class="hljs-bullet">-</span> <span class="hljs-string">"-f"</span>
          <span class="hljs-bullet">-</span> <span class="hljs-string">"/var/log/app.log"</span>
</code></pre>
<h3 id="heading-syntax-deep-dive-json-patch">Syntax Deep Dive: JSON Patch</h3>
<p>The critical line here is <code>path: "/spec/containers/-"</code>.</p>
<ul>
<li><p><code>/spec/containers</code>: Targets the list of containers in the Pod definition.</p>
</li>
<li><p><code>/-</code>: This specific JSON Patch syntax tells the API server to <strong>append</strong> the new value to the <em>end</em> of the array, rather than replacing an existing index.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768858586445/53f50f64-84d2-4c91-bddc-dd3ca3b5fec8.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-the-order-of-chaos-why-mutation-runs-before-validation">The Order of Chaos: Why Mutation Runs Before Validation</h1>
<p>To build a truly robust platform, you must understand the <a target="_blank" href="https://www.google.com/search?q=https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/%23admission-control-phases"><strong>Kubernetes admission control lifecycle</strong>.</a> The order of operations is not accidental; it is what makes the symbiotic relationship between "correction" and "enforcement" possible.</p>
<p>The critical sequence for every API request is:</p>
<ol>
<li><p><strong>Mutation</strong> (Mutating Webhooks)</p>
</li>
<li><p><strong>Schema Validation</strong> (API Server checks)</p>
</li>
<li><p><strong>Validation</strong> (Validating Webhooks)</p>
</li>
</ol>
<h3 id="heading-why-this-order-matters">Why This Order Matters</h3>
<p>This sequence is the secret sauce of <strong>auto-compliance</strong>. A resource is first <em>modified</em> by mutating webhooks. Only then is the final, corrected object passed to the schema checker and validating webhooks.</p>
<h3 id="heading-a-practical-workflow-the-avengers-label">A Practical Workflow: "The Avengers" Label</h3>
<p>Consider this narrative where auto-correction and compliance work seamlessly together:</p>
<ol>
<li><p><strong>The Trigger:</strong> A developer deploys a new application, but forgets the mandatory <code>team-id</code> label.</p>
</li>
<li><p><strong>The Fix (Mutation):</strong> A <a target="_blank" href="https://www.google.com/search?q=https://kyverno.io/docs/writing-policies/mutate/"><strong>Kyverno mutating policy</strong></a> intercepts the request before it is saved. Based on the namespace, it automatically injects <code>team-id: "avengers"</code>.</p>
</li>
<li><p><strong>The Check (Validation):</strong> The request—now carrying the new label—proceeds to the validation stage.</p>
</li>
<li><p><strong>The Success:</strong> The validating policy confirms the <code>team-id</code> exists and approves the request.</p>
</li>
</ol>
<p>The result? The developer's deployment succeeds on the first try. The application is compliant from the moment of creation, and the platform team has enforced standards without blocking the workflow.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768859149577/8027acc5-7164-4971-821a-1bba1aef476d.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-when-magic-fails-debugging-mutations-without-pulling-your-hair-out">When Magic Fails, Debugging mutations without pulling your hair out</h1>
<p>While mutation policies can feel like magic, they are ultimately code—and code can have bugs. When a mutation policy fails, it can break deployments or slow down the API server. To avoid this, you need a robust strategy for <strong>testing, observability, and debugging</strong>.</p>
<h3 id="heading-1-pre-deployment-testing">1. Pre-Deployment Testing</h3>
<p>Never deploy a policy blindly.</p>
<ul>
<li><p><strong>Unit Testing:</strong> Use the <a target="_blank" href="https://www.google.com/search?q=https://kyverno.io/docs/kyverno-cli/%23test"><strong>Kyverno CLI</strong></a> <strong>(</strong><code>kyverno test</code>) to validate policies against mock resources locally before they ever touch a cluster.</p>
</li>
<li><p><strong>End-to-End (E2E) Testing:</strong> For complex scenarios, use <a target="_blank" href="https://www.google.com/search?q=https://kyverno.github.io/chainsaw/"><strong>Chainsaw</strong></a>, a declarative testing framework tailored for Kubernetes. It allows you to spin up virtual clusters, apply policies, and verify the mutations in a realistic environment.</p>
</li>
</ul>
<h3 id="heading-2-monitoring-webhook-performance">2. Monitoring Webhook Performance</h3>
<p>Every admission webhook adds latency to API server requests. If your policy is slow, the entire cluster slows down. You must monitor specific <a target="_blank" href="https://kubernetes.io/docs/reference/instrumentation/metrics/"><strong>Prometheus metrics</strong></a> exposed by the API server:</p>
<ul>
<li><p><code>apiserver_admission_webhook_admission_duration_seconds_bucket</code>: The most critical metric. It tracks exactly how much time your webhook adds to request processing.</p>
</li>
<li><p><code>apiserver_admission_webhook_fail_open_count</code>: Tracks requests that were allowed only because the webhook failed (if <code>failurePolicy: Ignore</code> is set).</p>
</li>
<li><p><code>apiserver_admission_webhook_request_total</code>: Useful for understanding the total load on your policy engine.</p>
</li>
</ul>
<h3 id="heading-3-debugging-with-audit-logs-amp-annotations">3. Debugging with Audit Logs &amp; Annotations</h3>
<p><strong>Native Kubernetes policies</strong> (like <code>MutatingAdmissionPolicy</code>) offer a powerful feature called <code>auditAnnotations</code>. This allows you to log specific values from the resource directly into the Kubernetes audit stream during evaluation.</p>
<p>For example, to debug why a CPU limit isn't being applied, you can log the incoming request value:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># Snippet from a MutatingAdmissionPolicy</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-comment"># ... other fields</span>
  <span class="hljs-attr">auditAnnotations:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">"cpu_request.my-company.com"</span>
      <span class="hljs-attr">valueExpression:</span> <span class="hljs-string">"object.spec.containers[0].resources.requests.cpu"</span>
</code></pre>
<p>This generates an audit log entry like <code>cpu_</code><a target="_blank" href="http://request.my-company.com"><code>request.my-company.com</code></a><code>: "250m"</code>, providing crystal-clear visibility into what the policy engine "saw."</p>
<h3 id="heading-4-safe-rollouts-with-audit-mode">4. Safe Rollouts with "Audit Mode"</h3>
<p>Policy engines like Kyverno allow you to set <code>validationFailureAction: Audit</code>. In this mode, requests are not blocked; instead, violations are recorded in <strong>PolicyReport</strong> CRDs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768859789159/c8ac8d34-24fa-422c-a112-c3fc7c53be03.png" alt class="image--center mx-auto" /></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text"><strong><em><mark>Warning</mark></em></strong><em><mark>: While </mark></em><strong><em><mark>Audit</mark></em></strong><em><mark> mode is excellent for testing, these reports are stored as Kubernetes objects. In a busy cluster, they can accumulate rapidly, bloating the </mark></em><strong><em><mark>etcd database</mark></em></strong><em><mark> and degrading control plane performance. Always use a cleanup policy or TTL for these reports.</mark></em></div>
</div>

<h1 id="heading-conclusion">Conclusion</h1>
<p>Mutation policies—especially when implemented with a robust engine like <strong>Kyverno</strong>—represent a significant evolution in <a target="_blank" href="https://platformengineering.org/"><strong>Platform Engineering</strong></a>. They empower platform teams to shed the role of "config police" and become true enablers.</p>
<p>By building a secure, compliant, and developer-friendly <strong>"</strong><a target="_blank" href="https://netflixtechblog.com/full-cycle-developers-at-netflix-a08c31f83249"><strong>paved road</strong></a><strong>"</strong> that automatically corrects common errors, you do more than just enforce rules. You codify <a target="_blank" href="https://sre.google/books/"><strong>operational excellence</strong></a> into the cluster itself, freeing developers to focus on what they do best: shipping great applications.</p>
<h2 id="heading-a-final-thought-for-platform-teams">A Final Thought for Platform Teams</h2>
<p>As you adopt these tools, consider the balance of power. While auto-correction reduces friction, it can also hide complexity.</p>
<ul>
<li><p><strong>The Challenge:</strong> How do you balance "invisible" compliance with developer awareness?</p>
</li>
<li><p><strong>The Goal:</strong> Ensure developers know <em>what</em> changed in their manifest, so the "magic" doesn't become a mystery.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768860182265/cef87983-9997-4adb-842a-38adcd28ce95.png" alt class="image--center mx-auto" /></p>
<hr />
<h3 id="heading-further-reading-amp-resources">📚 Further Reading &amp; Resources</h3>
<p><strong>Kyverno &amp; Mutation Policies</strong></p>
<ul>
<li><p><a target="_blank" href="https://www.google.com/search?q=https://kyverno.io/docs/writing-policies/mutate/"><strong>Kyverno Mutation Docs:</strong></a> The official guide to writing mutation rules, including <code>patchesJson6902</code> and <code>patchStrategicMerge</code>.</p>
</li>
<li><p><a target="_blank" href="https://kyverno.io/policies/"><strong>Kyverno Policy Library:</strong></a> A searchable collection of ready-to-use policies (great for finding examples to tweak).</p>
</li>
</ul>
<p><strong>Testing &amp; Validation</strong></p>
<ul>
<li><p><a target="_blank" href="https://www.google.com/search?q=https://kyverno.github.io/chainsaw/"><strong>Kyverno Chainsaw:</strong></a> The end-to-end testing tool mentioned in this post, designed specifically for Kubernetes controllers and policies.</p>
</li>
<li><p><a target="_blank" href="https://kyverno.io/docs/kyverno-cli/"><strong>Kyverno CLI:</strong></a> Learn how to run <code>kyverno test</code> locally to catch syntax errors before deployment.</p>
</li>
</ul>
<p><strong>Kubernetes Concepts</strong></p>
<ul>
<li><p><a target="_blank" href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/"><strong>Admission Controllers Reference:</strong></a> The official Kubernetes documentation explaining the lifecycle of a request (Mutation → Validation).</p>
</li>
<li><p><a target="_blank" href="https://jsonpatch.com/"><strong>JSON Patch (RFC 6902):</strong></a> A user-friendly guide to understanding the syntax used in <code>patchesJson6902</code>.</p>
</li>
</ul>
<p><strong>Platform Engineering</strong></p>
<ul>
<li><p><a target="_blank" href="https://netflixtechblog.com/full-cycle-developers-at-netflix-a08c31f83249"><strong>The "Paved Road" Concept:</strong></a> The original Netflix Tech Blog article that popularized the idea of building "Paved Roads" for developers.</p>
</li>
<li><p><a target="_blank" href="https://tag-app-delivery.cncf.io/whitepapers/platforms/"><strong>CNCF Platform Engineering Whitepaper:</strong></a> An in-depth look at modern platform engineering principles.</p>
</li>
</ul>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong><em>Enjoyed this deep dive into Kubernetes mutation? Subscribe to our newsletter for more platform engineering insights, and stay tuned for our next article, where we'll explore the world of advanced validation policies!</em></strong></div>
</div>]]></content:encoded></item><item><title><![CDATA[Stop Letting "YOLO Deployments" Break Your Cluster: Hello, Kyverno!]]></title><description><![CDATA[Introduction: The Silent Guardian of the API Server
Maintaining a Kubernetes cluster often feels like a constant battle against configuration drift. As teams scale, the anxiety of "who deployed what and why" grows. Without a gatekeeper, your API serv...]]></description><link>https://blog.mrashed.com/stop-letting-yolo-deployments-break-your-cluster-hello-kyverno</link><guid isPermaLink="true">https://blog.mrashed.com/stop-letting-yolo-deployments-break-your-cluster-hello-kyverno</guid><category><![CDATA[kyverno]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[cluster]]></category><dc:creator><![CDATA[Mahmoud Rashed]]></dc:creator><pubDate>Sat, 17 Jan 2026 10:28:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768345816967/ed8ca20f-5f80-4a43-98c2-31e4771e93c8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction-the-silent-guardian-of-the-api-server"><strong>Introduction: The Silent Guardian of the API Server</strong></h2>
<p>Maintaining a Kubernetes cluster often feels like a constant battle against configuration drift. As teams scale, the anxiety of "<mark>who deployed what and why</mark>" grows. Without a gatekeeper, your API server is essentially an open door to any configuration, regardless of how insecure or inefficient it might be.</p>
<p>This is where Admission Controllers step in. Think of them as the middleware of the Kubernetes world—an essential layer of logic that scrutinizes every request after it has passed authentication and authorization, but <em>before</em> the state is persisted to the <strong>etcd</strong> database. This specific timing makes them the ultimate arbiter of what actually enters your cluster’s "source of truth."</p>
<p>An admission controller is a piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object, but only after the request is authenticated and authorized. In simpler terms, admission controllers can be thought of as <mark>middleware that can validate, mutate, or reject requests to the Kubernetes API.</mark></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768681835445/2a80bf09-0501-49b8-8ab2-fd760f6da521.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-the-wild-west-of-k8s-why-we-cant-have-nice-things"><strong>The "Wild West" of K8s: Why we can't have nice things</strong></h2>
<p>At the scale of an large company, Kubernetes can quickly become a "Wild West." Without strict policy enforcement, clusters are prone to systemic risks. Some researches also identifies misconfigurations—specifically overly permissive RBAC and <strong>unbounded service accounts</strong>—as the leading cause of security breaches.</p>
<p>Beyond security, there is the silent financial leak of "<mark>Resource Asymmetry.</mark>" The <code>kube-scheduler</code> relies on a complex scoring algorithm to assign pods to nodes based on CPU and memory. However, because this scoring is highly variable, developers often "play it safe" by over-estimating resource requests to avoid performance issues. This leads to a scenario where "spending outstripping use" becomes the norm.</p>
<p>The danger of "<mark>Missing Requests and Limits</mark>" is particularly acute; without these guardrails, a single resource-hungry pod can trigger a <mark>denial-of-service</mark> for its neighbors. This evolving threat landscape, combined with the risk of insider threats, makes automated gatekeeping the architect's path to sanity.</p>
<h2 id="heading-kyverno-vs-opa-why-i-refuse-to-learn-another-language-rego"><strong>Kyverno vs. OPA: Why I refuse to learn another language (Rego)</strong></h2>
<p>When choosing a policy engine, the industry generally gravitates toward two heavyweights: Kyverno and OPA Gatekeeper. However, the friction of learning a specialized query language like Rego (used by OPA) often slows down security adoption for YAML-native teams.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768681847010/a91fae98-2361-40ec-b4b5-d66aa03a6759.png" alt class="image--center mx-auto" /></p>
<p>The tech team at Adevinta recently highlighted a "<mark>functional failure</mark>" in OPA Gatekeeper’s mutation capabilities that led them to migrate. Specifically, Gatekeeper's <code>Assign</code> feature failed because it could not modify fields based on <strong>contextual data</strong>—information residing outside the specific field being observed. While OPA requires a complex external data provider setup for this, Kyverno handles it natively within the same manifest.</p>
<h2 id="heading-its-just-yaml-the-moment-you-fall-in-love"><strong>It’s just YAML! (The moment you fall in love)</strong></h2>
<p>The Kyverno advantage is simple: it feels like a natural extension of the Kubernetes experience. Because policies are written in native YAML, they integrate seamlessly with <code>kubectl</code>, Helm, and GitOps workflows. It is a more intuitive way to handle governance than traditional programming-heavy engines.</p>
<p>We are also witnessing a major shift with the arrival of <strong><mark>CEL (Common Expression Language)</mark></strong><mark>.</mark> In Kubernetes <strong><mark>v1.33</mark></strong>, <code>ValidatingAdmissionPolicy</code> has officially reached <strong>V1 (GA)</strong>. This is a game-changer because it allows for declarative validation directly in the vanilla API server <strong>without external HTTP webhooks</strong>. By removing the need for these callouts, architects can eliminate network latency and webhook failure modes entirely. Even OPA Gatekeeper is acknowledging this shift by adding CEL support, signaling a move toward standardized, high-performance logic.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768681879352/b1087f89-8a56-46be-b2da-19a74241d769.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-3-minute-install-from-zero-to-governance">3-Minute Install: From "Zero" to "Governance"</h2>
<p>Getting started is faster than your coffee cools. You can go from an unmanaged cluster to a governed environment using the standard Helm workflow for Kyverno:</p>
<ol>
<li><p><strong>Add the Repo:</strong> <code>helm repo add kyverno</code> <a target="_blank" href="https://kyverno.github.io/kyverno/"><code>https://kyverno.github.io/kyverno/</code></a></p>
</li>
<li><p><strong>Update:</strong> <code>helm repo update</code></p>
</li>
<li><p><strong>Install:</strong> <code>helm install kyverno kyverno/kyverno --namespace kyverno --create-namespace</code></p>
</li>
</ol>
<h3 id="heading-the-lifecycle-of-a-request"><strong>The Lifecycle of a Request</strong></h3>
<p>To master admission control, you must understand the technical sequence of a request:</p>
<ol>
<li><p><strong>Mutating Phase:</strong> The controller modifies the request (e.g., injecting sidecars or team labels).</p>
</li>
<li><p><strong>Schema Validation:</strong> The API server performs a structural JSON check to ensure the resource is well-formed.</p>
</li>
<li><p><strong>Validating Phase:</strong> The controller checks the request against security rules and finally accepts or rejects it.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768681905795/eb44a427-7272-4145-917e-62fbe02bc06d.png" alt class="image--center mx-auto" /></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong><em>Pro Tip:</em></strong><em> Always start in </em><strong><em>Audit Mode</em></strong><em>. This allows you to assess the impact of policies without breaking existing developer workflows. Once you have sanitized the environment, flip the switch to </em><strong><em>Enforce Mode</em></strong><em>.</em></div>
</div>

<h2 id="heading-your-first-policy-ban-the-default-namespace"><strong>Your First Policy: Ban the default namespace</strong></h2>
<p>Isolating workloads is the first step toward maturity. Kubernetes ships with a static admission controller called <code>NamespaceLifecycle</code> that acts as a basic safeguard. It prevents the accidental deletion of three critical system-reserved namespaces: <code>default</code>, <code>kube-system</code>, and <code>kube-public</code>.</p>
<p>However, true governance requires moving beyond defaults to enforce <strong>ResourceQuotas</strong> and custom labels. This prevents one team from monopolizing node resources. From there, follow the experimental insights from S&amp;P 500 deployments to harden your <code>securityContext</code>:</p>
<ul>
<li><p><strong>Enforce Rootless Mode:</strong> Prohibit deployments where <code>runAsNonRoot</code> is false.</p>
</li>
<li><p><strong>Identity Mapping:</strong> Explicitly define <code>runAsUser</code> and <code>runAsGroup</code> (e.g., set to 1000) to ensure workloads never run under a root identity.</p>
</li>
<li><p><strong>Immutable Filesystems:</strong> Enforce <code>readOnlyRootFilesystem: true</code> to prevent attackers from persisting malicious scripts or exfiltrating data.</p>
</li>
</ul>
<h2 id="heading-conclusion-the-future-of-sovereign-clusters">Conclusion: The Future of Sovereign Clusters</h2>
<p>The evolution of Kubernetes is moving toward Zero Trust and "Sovereign Clusters"—environments where an enterprise maintains absolute sovereignty over its standards across multi-cluster platforms. By implementing these gatekeeping rules today, you lay the foundation for AI-driven threat detection and automated compliance.</p>
<p><mark>If your API server disappeared tomorrow, would your policy engine know how to rebuild the trust?</mark></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong><em>If you liked this article follow for more, and wait for the rest of the series, I will write more about each policy type and more…</em></strong></div>
</div>]]></content:encoded></item></channel></rss>