Adonai Costa explains: how to simplify security policies in Kubernetes? Forget REGO and use YAML to ensure compliance and avoid risks.

SRE/Kubernetes Admin
Adonai Costa

Stop suffering with REGO, go with YAML
Creating Security policies in Kubernetes is an unceasing pursuit by the Security area to prevent incidents from exposing businesses to risks, such as data leakage. Until then, we know that the deal is to apply security policies in Kubernetes clusters to prevent any exposure to risk as much as possible, and, on the market, there are several alternatives of Security Policies for this: OPA, Gatekeeper, Syra, AWS Opa, Azure Policy etc. However, the challenge for us, Kubernauts on duty, lies in implementing and maintaining these policies in the language in which they are written, REGO. Because we are used to working with YAML, tools that use a new language, in this case REGO, only make our lives harder! It is like taking a step backward in what we are doing to learn a new language and then apply it to the security policies of the K8s cluster. Tired of suffering with this, I went looking for an alternative and found Kyverno. Kyverno is a Kubernetes controller capable of creating its own security policy with YAML. Moreover, if you change your cloud provider, your rules will already be part of your CI/CD or a velero backup or, in the worst-case scenario, in the YAMLS files of your hidden directory on your drive. In summary, it is easy to write, easy to understand, they stay in a single place and can migrate from cloud provider or even to on-premise, avoiding lock-in with cloud providers. You can achieve almost anything with Kyverno, check it out:
Block resource deletion, especially Kyverno itself;
Track what is running that might infringe on the security of the nodes;
Automate and police label creation to charge $$ from teams when dealing with a multi-tenant K8s;
Automate the creation of Network Policies and who can modify them;
Block the use of specific resources, for example, I only want Ingress to be spun up using my ingress-nginx or my kong, and traefik is only for team X;
Automagically know that any deployment must have a minimum of: . cpu/memory resources . labels . replicas
Distribute secrets and configmaps to any created namespace;
Restrict the use of LoadBalancer and/or NodePort services;
Make it impossible for people to spin up things in the Default namespace;
Force every resource to use tags on images and always from the same registry;
Apply NetworkPolicy when a new namespace is created;
Create a namespace, generate all policies and generate a report of what is applied.
Additionally, you can generate violation, inspection, and enforcement reports — all in YAML — for you to extract with that “-o json” and play around with converting to HTML. There is a CLI for those who like it too.Installing Kyverno
Want to install Kyverno, play with some initial policies, and see how it works?
The installation is non-intrusive! Nothing will stop, no error will be generated by the installation, and there is no default rule that forces any policy. That is, you can apply Kyverno to your production cluster, as it will generate at most policy reports indicating where there is a problem to be addressed, based on default rules that do not interfere, only assess. Want to install Kyverno, play with some initial policies, and see how it works? Just be mindful of the fact that the more workloads you have in your cluster, the more CPU and memory resources your Kyverno will need to analyze, generate, and maintain policies and reports. If that is your case, increase these values in the Kyverno deployment.Let's get to the point! You will need:
* kubectl
* helm => 3.23
* 1 k8s cluster
* git
* kyverno cli, https://kyverno.io/docs/kyverno-cli/ (optional, only if you really want to, to validate policies, etc)$ helm repo add kyverno https://kyverno.github.io/kyverno/
Verify if the Kyverno pod is installed:
From this moment on, “get cpol” will return the policies applied to the cluster, at the cluster level. The “get polr -A” will bring the reports by namespaces, if you have namespaces created and with running workloads. See that all policies created by default are in audit in the action column, meaning they only audit the workloads. From the moment you want them to be applied and block some execution or configuration, just change the rule validationFailureAction: enforce and this will prevent the next pod from continuing to “break the policy”.
Apply this policy:
Verify in the Kyverno pod logs and ClusterPolicy objects:
Here, we can already see that our rule requiring the informed labels to be applied to any workload in any namespace, with the exception of namespaces app1, kube-system, and workloads-x.
Create a test deployment:
Notice here that I only created a label app.kubernetes.io/name: web, which does not entirely satisfy my newly created policy.
To view the FAIL audits of the reports, run:
(...) The policyReport will show the kubernetes service and the default namespace with the same missing labels we indicated in the policy. If this policy is on enforce, then adding these labels to these resources will be mandatory, and the pod will not be created until this issue is resolved.
There are dozens of other policies that can be applied in terms of a cluster, which does not prevent you from applying them only to a specific namespace, using kind: ClusterPolicy or for namespace, using Kind: Policy. They are available at https://github.com/kyverno/policies. One that I really like is the one that limits resource usage and forces every pod to obey a predefined rule of resource limits/requests:
With this, any pod, in any namespace, with the exception of Kube-system, will have to declare the utilization of resources and, still, respect the limits for requests and limits. As my brother would say: “there are a thousand ways to prepare Neston, invent yours”.
Based on the models and examples in the repository and the documentation, it is easy to create the policies we need to apply, without needing to learn a new language or dive into various K8s resources for troubleshooting or evolution.
That is it, folks! I highly recommend you run to get updated. Kyverno is wonderful and the learning curve is just a few hours.
Any questions, suggestions, or criticism, you can reach out to me: adonai@getup.io.
Newsletter Getup.
Atualizações sobre Kubernetes e Software Supply Chain Security todos os meses.
Operating Kubernetes in production for more than 13 years. With Quor, this experience extends to software supply chain security as well.
GET UP
© Getup · 2026
