
Overview
Some companies implement a policy on their Kubernetes clusters to ensure that every configuration and setup is deployed in accordance with applicable rules, to meet sound security standards, and, most importantly, to comply with the ISO 27001 standard, which requires that every running workload meet minimum security standards based on the CIS Benchmark.
Background
GitOps is a common practice found in many organizations. By integrating Kubernetes manifest management—for example, using Helm charts and ArgoCD—the deployment workflow for Kubernetes workloads becomes controllable and auditable. However, does this approach cover everything? Unfortunately, this mechanism only covers the client-side, where in a business-as-usual scenario, users are required to create manifests using templates from the provided charts—which sometimes also impose restrictions on helper files.These templates are meant to ensure conventions and governance remain within established guidelines—for example, every deployment must have a “team” tag, or a container image must not use the “latest” tag. However, these mechanisms only enforce compliance on the client-side. The same applies to ArgoCD: ArgoCD only ensures that running workloads align with the declarative manifest stored in the VCS. Although it offers auto-sync and auto-heal features, both still have time intervals that could potentially create security vulnerabilities. So, how can we ensure security not only on the client-side but also on the server-side? What if a user with access to the cluster has the necessary role to create or modify existing workloads? That user could potentially escalate their privileged access to perform uncontrolled actions. That’s where Kyverno comes in....
Bottom line:
Helm’s helpers.tpl and ArgoCD’s self-heal feature bridge the gap between “what’s in Git” and “what’s in the cluster.” However, both assume that the entire resource lifecycle originates from and is controlled solely through the Git → Helm render → ArgoCD apply pipeline. As soon as a resource originates from another path—such as a controller/operator, subchart, runtime debug, a reconciliation time gap, or a tooling compromise—that protection no longer applies. Kyverno closes that gap because it is positioned not within a “specific deployment pipeline,” but within the API server itself, so its scope automatically covers all of the above paths without needing to know where the resource came from.
Explanation
Kyverno runs on a Kubernetes Admission Controller (KAC, a component of the Kubernetes API Server), intercepting requests entering the Kubernetes API before they are forwarded and stored in etcd, while performing mutations and validations. In addition, Kyverno also functions as a controller, using a watch-and-reconcile mechanism to generate new rules or modify existing ones in response to activities or events that occur.
The following is a flowchart showing how Kyverno reviews and patches incoming requests from clients.

The following is Kyverno’s flow as a controller that performs watch-and-reconcile events or activities.

Use Case
Kubernetes has a native, built-in admission controller commonly referred to as podSecurity or PSA (Pod Security Admission). PSA has only three profiles: privileged, baseline, and restricted. Once you apply a profile, all the controls within it take effect simultaneously; you cannot selectively enable or exclude specific controls, for example, on a per-image or per-container basis.
For example, suppose you want to use the “restricted” profile for all namespaces starting with “prod-*,” but there’s a Cadvisor container that needs access to the host’s /proc directory; this causes the container to fail the Seccomp check. PSA also only has the capability to block at the pod level, not at the controller level. As a result, a Deployment or StatefulSet can still be deployed even if the pods are not; this will create “ghost” events or resources due to control desynchronization.
Why do we need it?
Kubernetes doesn’t have a single place to manage “policies” comprehensively.
- RBAC handles who can access what
- ResourceQuota and LimitRange handle resource quotas
- NetworkPolicy handles network traffic
- PSA handles pod security. These four components operate independently, have different configuration methods, and none of them can be used to create policies specific to our own business needs—such as “images must come from the internal registry” or “all resources must have a ‘team’ label.” Kyverno unifies all of these into a single policy model written in YAML.
Another issue is that all of those built-in mechanisms are purely for validation, and even then, their scope is limited. None of them can automatically “correct” or create new resources on their own if something is missing. Kyverno has the capability to do that—it can mutate existing resources and even automatically generate new ones—a capability that no native mechanism possesses.
As for PSA, even though it’s a built-in Kubernetes feature, it actually has quite a few limitations. It applies only to Pods, operates on an all-or-nothing basis per profile, cannot be customized per image or per container, has very rigid exceptions, and we cannot get violation reports directly within the cluster—we have to go through audit logs located outside the cluster.
And most importantly, the ecosystem has been around for a long time and is well-established. There are hundreds of ready-to-use policies available in the official library; it supports image signature verification (Sigstore/Notary); there are Policy Reports to monitor compliance; and a CLI for testing policies directly in CI. So we don’t need to build separate tools to get all of this.

Overview
Beberapa perusahaan menerapkan sebuah policy pada kubernetes cluster yang mereka miliki guna memastikan setiap konfigurasi dan setup dapat terdeploy sesuai dengan rule yang berlaku, untuk memenuhi standard security yang baik dan utamanya untuk memenuhi standard ISO 27001 yang mengharuskan setiap workload yang running memiliki standard minimum security standard based on CIS Benchmark.
Background
GitOps merupakan hal yang umum yang sering kita temui pada banyak organisasi, dengan mengawinkan management kubernetes manifest misalnya dengan menggunakan Helm charts dan juga ArgoCD, flow deployment dalam konteks kubernetes workload menjadi dapat dikontrol dan diaudit, namun apakah approach tsb sudah mengcover semuanya? sayangnya, mekanisme tsb baru mengcover client-side area, dimana dalam case business-as-usual user diharuskan membuat manifest dengan menggunakan template dari chart yang disediakan yang dimana terkadang juga ada restriction pada file helpers.tpl untuk menjaga convention serta governance tetap pada koridornya, misalnya setiap deployment diwajibkan memiliki sebuah tag team atau sebuah container image tidak boleh menggunakan tag latest, namun mekanisme tsb hanya menjaga di domain client-side, hal yang serupa juga berlaku untuk ArgoCD, ArgoCD hanya memastikan workload yang running sesuai dengan declarative manifest yang di simpan pada VCS, walaupun ada fitur auto-sync dan auto-heal namun kedua fitur tsb tetap memiliki interval jeda waktu yang dapat berpotensi menjadi celah keamanan, lalu bagaimana menjaga bukan hanya di ranah client-side namun juga di ranah server-side? jika ada user yang memiliki akses kedalam cluster dengan role yang mumpuni untuk membuat atau memodifikasi existing workload? privileged access sangat dimungkinkan untuk di eskalasi oleh user tsb untuk melakukan tindakan yang tidak terkontrol. Oleh karena itu disini Kyverno hadir....
Intinya: Helm helpers.tpl + ArgoCD self-heal menutup celah "apa yang tertulis di Git vs apa yang ada di cluster". Tapi keduanya sama-sama berasumsi bahwa seluruh lifecycle resource berasal dan hanya dikontrol lewat jalur Git -> Helm render -> ArgoCD apply. Begitu ada resource yang lahir dari jalur lain; controller/operator, subchart, runtime debug, celah waktu reconcile, atau kompromi tooling itu sendiri, proteksi itu tidak berlaku. Kyverno menutup celah itu karena posisinya bukan di "jalur deployment tertentu", tapi di API server itu sendiri, sehingga cakupannya otomatis mencakup semua jalur di atas tanpa perlu tahu resource itu datang dari mana.
Explanation
Kyverno berjalan pada sebuah Kubernetes Admission Controller (KAC adalah component di Kubernetes API Server), bekerja dengan meng-intercept request yang masuk ke Kubernetes API sebelum request tsb diteruskan dan disimpan ke etcd dengan melakukan mutating dan validating. Selain itu, Kyverno juga berjalan sebagai controller dengan menggunakan mekanisme watch-and-reconcile untuk melakukan generating ataupun mutate-existing rule terhadap activity atau event yang terjadi.
Berikut adalah flow bagaimana Kyverno melakukan review dan patching terhadap request yang masuk dari client.

Berikut adalah flow Kyverno sebagai controller yang melakukan watch-and-reconcile event atau activity.

Use Case
Kubernetes memiliki native built-in admission contoller yang biasanya disebut podSecurity / PSA (Pod Security Admission), PSA hanya memiliki 3 profile yaitu privileged, baseline, dan restricted dan begitu kamu pakai satu profile, semua kontrol di dalamnya berlaku sekaligus, kamu tidak bisa pilih kontrol mana yang mau diaktifkan atau dikecualikan misalnya per image/container.
Contohnya kamu ingin menggunakan restricted profile untuk seluruh namespace prod-*, tapi ada container cadvisor yang butuh akses ke /proc host, hal tsb menyebabkan container gagal cek Seccomp. PSA juga hanya memiliki kapability untuk melakukan blockir di level pod bukan di level controller, alhasil deployment / statefulset dapat tetap terdeploy walaupun pod nya tidak, hal ini akan menimbulkan event / resource "hantu" akibat adanya ketidaksinkronan control
Why we need it?
Kubernetes tidak memiliki satu tempat untuk mengatur "policy" secara menyeluruh.
- RBAC ngurusin siapa boleh akses apa
- ResourceQuota sama LimitRange ngurusin kuota resource
- NetworkPolicy ngurusin lalu lintas network
- PSA ngurusin keamanan Pod. Empat hal ini jalan sendiri-sendiri, cara konfigurasinya beda-beda, dan nggak ada satupun yang bisa dipakai buat bikin aturan spesifik ke bisnis kita sendiri, misalnya "image wajib dari registry internal" atau "semua resource harus ada label team-nya". Kyverno menyatukan semua itu jadi satu model policy yang ditulis dalam YAML.
Masalah lain, semua mekanisme bawaan tadi sifatnya cuma validasi doang, dan itupun scope-nya sempit. Tidak ada satupun yang bisa otomatis "membenerkan" atau bikin resource baru sendiri kalau ada yang kurang. Kyverno punya kemampuan buat itu, bisa mutate resource yang sudah ada, bahkan bisa generate resource baru otomatis, yang tidak dipunyai mekanisme native manapun.
Soal PSA, walaupun ini fitur bawaan Kubernetes, kenyataannya keterbatasannya cukup banyak. Cuma berlaku buat Pod, semua-atau-tidak-sama-sekali per profile nya, tidak bisa dikustomisasi per image atau per container, exception-nya kaku banget, dan kita tidak bisa dapat laporan pelanggaran secara langsung di dalam cluster, harus lewat audit log yang letaknya di luar cluster.
Dan yang paling penting, ekosistemnya udah jalan lama dan matang. Ada ratusan policy siap pakai yang tinggal kita ambil dari library resminya, sudah support verifikasi signature image (Sigstore/Notary), ada Policy Reports buat pantau kepatuhan, plus CLI buat testing policy langsung di CI. Jadi kita nggak perlu rakit-rakit tool terpisah buat dapat semua ini.