Check compliance and apply the rules that close it
Score a cluster against published frameworks, see which workloads fail each control, and apply the rule that closes it with Kubernetes built-in admission or with Kyverno.
Once a cluster is connected, AuthFI scores it against published compliance frameworks. Every failing control names the workloads that fail it and the rule that would close it. Each rule comes in two forms, so you can apply it with what your cluster already has:
Use this guide to read the score, and to turn a failing control into a rule in your cluster.
Before you begin
You need:
- A cluster with Zero-Code installed. See Install Zero-Code on a cluster.
kubectl, with permission to create the rule: aValidatingAdmissionPolicyand aValidatingAdmissionPolicyBindingfor built-in admission, or aClusterPolicyfor Kyverno.
Open the compliance score
In the AuthFI console, open Security > Compliance.
Choose the cluster in Cluster and the framework in Compliance framework. To score the cluster again, choose Score again.
The tiles Passing, Failing and We cannot decide count the controls. The table lists each control with the columns Control, Requires, Status, Objects scanned and Would refuse.
Find the failing controls
Choose the Fail chip above the table to show only failing controls. Each control has one of five statuses, and only Pass counts as a pass.
Would refuse shows how many workloads the rule would deny, before you apply it.
Read a failing control
Select a control's row. A drawer opens with four tabs.
A control you already guard with your own Kyverno policy gets no suggestion. See How your own Kyverno policies are counted.
Choose how you will apply it
On The rule that closes it, under Apply with, choose Kubernetes built-in admission (no extra install) or Kyverno. The rule shown below changes to that form. The same choice sits above the table, beside the button that copies every rule at once.
Copy the rule and apply it
Choose Copy for built-in admission or Copy as Kyverno. The rule is copied to the clipboard as JSON, and the console confirms how many rules were copied.
Save it to a file and apply it to the cluster yourself:
kubectl apply -f authfi-privileged-container.jsonA built-in admission rule is two objects: a ValidatingAdmissionPolicy that holds the check, and a ValidatingAdmissionPolicyBinding that puts it in force. They are copied together as one List. This is the rule for the privileged containers check:
{
"apiVersion": "v1",
"kind": "List",
"items": [
{
"apiVersion": "admissionregistration.k8s.io/v1",
"kind": "ValidatingAdmissionPolicy",
"metadata": { "name": "authfi-privileged-container" },
"spec": {
"failurePolicy": "Fail",
"matchConstraints": {
"resourceRules": [
{ "apiGroups": [""], "apiVersions": ["*"], "operations": ["CREATE", "UPDATE"], "resources": ["pods"] },
{
"apiGroups": ["apps"],
"apiVersions": ["*"],
"operations": ["CREATE", "UPDATE"],
"resources": ["deployments", "statefulsets", "daemonsets"]
},
{
"apiGroups": ["batch"],
"apiVersions": ["*"],
"operations": ["CREATE", "UPDATE"],
"resources": ["jobs", "cronjobs"]
}
]
},
"variables": [
{
"name": "spec",
"expression": "has(object.spec.jobTemplate) ? object.spec.jobTemplate.spec.template.spec : (has(object.spec.template) ? object.spec.template.spec : object.spec)"
},
{
"name": "containers",
"expression": "variables.spec.containers + (has(variables.spec.initContainers) ? variables.spec.initContainers : []) + (has(variables.spec.ephemeralContainers) ? variables.spec.ephemeralContainers : [])"
}
],
"validations": [
{
"expression": "variables.containers.all(c, !has(c.securityContext) || !has(c.securityContext.privileged) || !c.securityContext.privileged)",
"message": "EADMIT001: Containers must not be privileged",
"reason": "Forbidden"
}
]
}
},
{
"apiVersion": "admissionregistration.k8s.io/v1",
"kind": "ValidatingAdmissionPolicyBinding",
"metadata": { "name": "authfi-privileged-container" },
"spec": { "policyName": "authfi-privileged-container", "validationActions": ["Warn", "Audit"] }
}
]
}The Kyverno form of the same rule is one ClusterPolicy:
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": { "name": "authfi-privileged-container" },
"spec": {
"validationFailureAction": "Audit",
"background": true,
"rules": [
{
"name": "privileged_container",
"match": { "any": [{ "resources": { "kinds": ["Pod"] } }] },
"validate": {
"message": "EADMIT001: Containers must not be privileged",
"pattern": {
"spec": {
"=(containers)": [{ "=(securityContext)": { "=(privileged)": false } }],
"=(initContainers)": [{ "=(securityContext)": { "=(privileged)": false } }],
"=(ephemeralContainers)": [{ "=(securityContext)": { "=(privileged)": false } }]
}
}
}
}
]
}
}Every rule's message starts with a stable code, such as EADMIT001, so you can search your logs for it whatever the wording.
Every exported rule only watches. A built-in admission binding is ["Warn", "Audit"]: whoever applies a failing object sees a warning, and the API server's audit log records it. A Kyverno policy is in Audit. Neither denies anything, so applying a rule cannot break a deployment.
To copy the rules for every control shown in the table at once, choose Copy the rules for built-in admission or Copy the rules as Kyverno above the table. One rule copies as one object, and several copy as one List.
Switch the rule to deny
When the warnings and reports are clean, switch the rule to deny yourself and apply it again:
- Built-in admission: set the binding's
validationActionsto["Deny"]. - Kyverno: set
validationFailureActiontoEnforce.
AuthFI reads, scores and writes the rule. You apply it, and you decide what is admitted to your cluster.
Check that it works
For a built-in admission rule, list the rule, then ask the API server to admit a failing object without creating it:
kubectl get validatingadmissionpolicy authfi-privileged-container
kubectl run probe --image=busybox --privileged --dry-run=serverWhile the binding is ["Warn", "Audit"], the second command prints a warning carrying EADMIT001. Once the binding is ["Deny"], the same command is refused with that code.
For a Kyverno policy, open Security > Policy and choose the Admission chip. Your policy is listed beside every other rule in force, marked with whether it denies or only monitors. A policy in Audit is counted as monitoring. Once it is in Enforce, it is counted as a guard and the control is covered by you.
Frameworks
Checks
The last check comes from traffic the nodes observed, not from configuration. It tells you what is happening. The other checks tell you what is permitted.
Statuses
A control that cannot be answered from the cluster is shown as We cannot decide. It is not counted as passing, so the score reflects only what was checked.
How your own Kyverno policies are counted
If the cluster runs Kyverno, AuthFI reads your ClusterPolicy and Policy objects.
Your policies appear on Security > Policy beside every other rule in force. Each is marked with whether it denies or only monitors.
How current the score is
The score is computed from what the cluster last reported. The Store tile shows current or stale.
If a cluster has not reported for an hour, the page says the result is stale and shows when it was last complete.