Skip to content

Lab 03 — Kyverno

In the previous lab, you controlled:

Who can perform an action?

using Kubernetes RBAC.

Now you will control:

What kind of Kubernetes resource
should be allowed to exist?

This lab introduces Kyverno, a Kubernetes-native policy engine used to enforce security and governance rules against Kubernetes resources.

The progression is:

Identity
RBAC
Permission Granted
Resource Submitted
Kyverno Policy
Allow / Reject / Modify / Report

This is a major step toward enterprise Kubernetes security.

Difficulty: Intermediate

Estimated Time: 90–120 minutes

Primary Skills:

Kubernetes Admission Control
Policy-as-Code
Kyverno
Validation Policies
Workload Guardrails
Security Context Enforcement
Image Governance
Policy Testing
Policy Reporting
Security Remediation

Your organization operates multiple Kubernetes clusters.

Development teams deploy applications independently, which has resulted in inconsistent workload security.

The platform security team has identified several recurring issues:

Privileged Containers
Containers Running as Root
Missing Resource Limits
Unapproved Container Registries
Missing Required Labels

Manual review is no longer scalable.

You have been asked to implement automated policy controls using Kyverno.

Your mission is to create security policies that evaluate Kubernetes workloads before they are accepted into the cluster.

By the end of this lab, you should be able to:

  • Explain Kubernetes admission control
  • Understand where Kyverno fits in the request lifecycle
  • Verify Kyverno installation
  • Inspect Kyverno components
  • Understand ClusterPolicy and Policy
  • Create validation policies
  • Test compliant workloads
  • Test non-compliant workloads
  • Block privileged containers
  • Require non-root execution
  • Require resource controls
  • Enforce image registry standards
  • Require application labels
  • Understand audit vs enforce behavior
  • Review policy results
  • Troubleshoot policy failures
  • Document policy violations
  • Apply policy-as-code thinking

Your security architecture will look like:

Developer
kubectl / CI/CD
Kubernetes API
Authentication
RBAC Authorization
Admission Request
Kyverno
Security Policy Evaluation
Allow / Deny
Kubernetes Resource

Without policy enforcement:

Developer
Creates Insecure Workload
Deployment Succeeds
Security Team Finds It Later

With preventive policy enforcement:

Developer
Creates Insecure Workload
Kyverno Evaluates It
Deployment Rejected

This shifts security from:

Detect Later

to:

Prevent Earlier

You need:

Authorized Kubernetes Training Cluster
kubectl
Kyverno Installed
Permission to Create a Lab Namespace
Permission to Create Policies

For cluster-wide policy exercises, you may require permissions to create:

ClusterPolicy

If you do not have cluster-scoped permissions, perform equivalent namespace-scoped exercises with Policy where practical.

Perform this lab only in:

Your Own Cluster
Training Environment
Explicitly Authorized Kubernetes Environment

Do not apply new admission policies directly to production without:

Testing
Change Approval
Impact Analysis
Rollback Planning

A badly designed admission policy can prevent legitimate workloads from deploying.

A Kubernetes API request typically passes through several security stages.

Conceptually:

API Request
Authentication
Authorization
Admission Control
Resource Stored

Authentication asks:

Who are you?

RBAC asks:

Are you allowed to create this resource?

Admission control asks:

Should this resource configuration
be accepted?

A developer may legitimately have:

create pods

permission.

But they attempt to create:

Privileged Pod

RBAC may say:

Allowed

Kyverno can still say:

Rejected

because the configuration violates security policy.

Identity Control
+
Configuration Control
Stronger Security

Kyverno can support capabilities such as:

Validate
Mutate
Generate
Verify Images
Report Policy Results

This lab focuses mainly on:

Validation

because it directly demonstrates security guardrails.

Validation checks whether a resource complies with policy.

Example:

Container Privileged?
Yes
Reject

Mutation can automatically modify resources.

Conceptually:

Missing Standard Configuration
Kyverno Adds Configuration

Kyverno can generate supporting Kubernetes resources based on policy.

Kyverno can also participate in container supply-chain controls by enforcing image-related policies.

Check:

Terminal window
kubectl config current-context

Then:

Terminal window
kubectl cluster-info

Always verify:

Cluster
Context
Environment

before applying admission policies.

Check Kyverno namespace resources.

A common installation uses:

Terminal window
kubectl get pods -n kyverno

You may see several Kyverno components depending on version and deployment architecture.

Also inspect:

Terminal window
kubectl get deployments -n kyverno

Confirm:

Kyverno Components Exist
Pods Are Healthy
Controllers Are Available

Use the installation procedure approved for your training environment.

Do not blindly apply external installation manifests to enterprise clusters.

Your organization may manage Kyverno through:

Helm
GitOps
Platform Automation
Cluster Add-On Management

Part 05 — Inspect Kyverno Policy Resources

Section titled “Part 05 — Inspect Kyverno Policy Resources”

Run:

Terminal window
kubectl api-resources | grep -i kyverno

Depending on the installed version, you may see resources related to:

Policy
ClusterPolicy
PolicyReport
ClusterPolicyReport

A namespace Policy applies within a namespace context.

Conceptually:

Policy
Namespace

A ClusterPolicy can apply across the cluster depending on its matching rules.

Conceptually:

ClusterPolicy
Multiple Namespaces / Cluster Scope

Start with the smallest practical scope.

Do not begin with:

Apply Everything Everywhere

when:

One Training Namespace

is sufficient for testing.

Create:

Terminal window
kubectl create namespace ghc-kyverno-lab

Verify:

Terminal window
kubectl get namespace ghc-kyverno-lab

Set it as your current namespace if desired:

Terminal window
kubectl config set-context --current --namespace=ghc-kyverno-lab

Create:

baseline-deployment.yaml

Add:

apiVersion: apps/v1
kind: Deployment
metadata:
name: baseline-app
namespace: ghc-kyverno-lab
labels:
app: baseline-app
spec:
replicas: 1
selector:
matchLabels:
app: baseline-app
template:
metadata:
labels:
app: baseline-app
spec:
containers:
- name: web
image: nginx

Apply:

Terminal window
kubectl apply -f baseline-deployment.yaml

Verify:

Terminal window
kubectl get deployments
kubectl get pods

The workload works.

But ask:

Does it run as root?
Does it define resource limits?
Is the image source approved?
Does it use strong security settings?

This is the difference between:

Operationally Functional

and:

Security Compliant

Part 08 — Policy 01: Require Application Labels

Section titled “Part 08 — Policy 01: Require Application Labels”

Organizations often require metadata for:

Ownership
Cost Allocation
Monitoring
Incident Response
Compliance

You will require:

owner

on Deployments in the lab namespace.

Create:

require-owner-label.yaml

Add:

apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: require-owner-label
namespace: ghc-kyverno-lab
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-owner-label
match:
any:
- resources:
kinds:
- Deployment
validate:
message: "Deployments must include the owner label."
pattern:
metadata:
labels:
owner: "?*"

Apply:

Terminal window
kubectl apply -f require-owner-label.yaml

Conceptually:

New Deployment
Does metadata.labels.owner exist?
Yes → Allow
No → Reject

Create:

bad-label-app.yaml

Add:

apiVersion: apps/v1
kind: Deployment
metadata:
name: bad-label-app
namespace: ghc-kyverno-lab
spec:
replicas: 1
selector:
matchLabels:
app: bad-label-app
template:
metadata:
labels:
app: bad-label-app
spec:
containers:
- name: web
image: nginx

Try:

Terminal window
kubectl apply -f bad-label-app.yaml

The deployment should be rejected when the policy is operating in enforce mode.

The user may have valid:

create deployment

permission.

But policy prevents deployment because:

Required Governance Metadata
Is Missing

Modify the metadata:

metadata:
name: good-label-app
namespace: ghc-kyverno-lab
labels:
owner: platform-team

Ensure the Deployment selector and Pod labels remain valid.

Apply again.

The compliant workload should now pass.

Always test:

Negative Case
+
Positive Case

A policy is incomplete if you only confirm that it blocks something.

You must also confirm legitimate workloads succeed.

Part 11 — Policy 02: Block Privileged Containers

Section titled “Part 11 — Policy 02: Block Privileged Containers”

Privileged containers can significantly weaken container isolation.

Attack path:

Application Vulnerability
Container Compromise
Privileged Container
Potential Host Impact

Create:

disallow-privileged.yaml

Add:

apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: disallow-privileged
namespace: ghc-kyverno-lab
spec:
validationFailureAction: Enforce
background: true
rules:
- name: block-privileged-containers
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Privileged containers are not permitted."
pattern:
spec:
containers:
- securityContext:
privileged: "false"

Apply:

Terminal window
kubectl apply -f disallow-privileged.yaml

Policy syntax and behavior can vary based on the Kyverno version and the exact resource structure being evaluated.

Treat the lab YAML as a learning pattern and validate it against the Kyverno version deployed in your training environment.

Create:

privileged-pod.yaml

Add:

apiVersion: v1
kind: Pod
metadata:
name: privileged-test
namespace: ghc-kyverno-lab
spec:
containers:
- name: test
image: nginx
securityContext:
privileged: true

Apply:

Terminal window
kubectl apply -f privileged-pod.yaml

Expected result:

Rejected by Policy

You have now moved from:

Security Recommendation:
Do Not Use Privileged Containers

to:

Security Enforcement:
Privileged Containers Cannot Be Created

Create:

restricted-pod.yaml

Add:

apiVersion: v1
kind: Pod
metadata:
name: restricted-test
namespace: ghc-kyverno-lab
spec:
containers:
- name: web
image: nginx
securityContext:
privileged: false

Apply:

Terminal window
kubectl apply -f restricted-pod.yaml

Validate:

Terminal window
kubectl get pods

Part 14 — Policy 03: Require Non-Root Workloads

Section titled “Part 14 — Policy 03: Require Non-Root Workloads”

Running applications as unnecessary root increases risk.

Desired:

Application
Non-Root User

Instead of:

Application
Root

Create:

require-non-root.yaml

Add:

apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: require-non-root
namespace: ghc-kyverno-lab
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-run-as-non-root
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Pods must require non-root execution."
pattern:
spec:
securityContext:
runAsNonRoot: true

Apply:

Terminal window
kubectl apply -f require-non-root.yaml
Pod Submitted
runAsNonRoot = true?
Yes → Allow
No → Reject

Create:

missing-nonroot.yaml

Add:

apiVersion: v1
kind: Pod
metadata:
name: missing-nonroot
namespace: ghc-kyverno-lab
spec:
containers:
- name: web
image: nginx

Try:

Terminal window
kubectl apply -f missing-nonroot.yaml

The policy should reject the workload if it does not meet the required structure.

Update:

apiVersion: v1
kind: Pod
metadata:
name: nonroot-app
namespace: ghc-kyverno-lab
spec:
securityContext:
runAsNonRoot: true
containers:
- name: web
image: nginx
securityContext:
privileged: false

A policy-compliant configuration may expose an application compatibility problem.

Some container images may expect to run as root.

This is useful security feedback.

The solution is not necessarily:

Disable the Policy

Instead ask:

Can We Use a Better Image?
Can We Configure the App Correctly?
Does the Workload Truly Need Root?

Policy engineering must balance:

Security
+
Application Requirements

An overly strict policy applied without testing can:

Block Legitimate Workload
Deployment Failure
Business Impact

This is why enterprise policy rollout often uses stages.

A useful rollout model is:

Audit
Observe Violations
Understand Impact
Remediate Workloads
Enforce

This is safer than immediately blocking everything.

Audit-style behavior allows teams to discover:

Which Existing Workloads
Would Violate the Policy?

before enforcement.

Enforce prevents non-compliant resources from being accepted.

Use:

Audit for Discovery
Enforce for Prevention

according to change-management requirements.

Part 18 — Policy 04: Require Resource Requests and Limits

Section titled “Part 18 — Policy 04: Require Resource Requests and Limits”

Resource governance contributes to:

Availability
Scheduling Reliability
Multi-Tenant Stability

Workloads without resource controls may contribute to:

Resource Exhaustion
Node Pressure
Application Instability

Create:

require-resources.yaml

Add:

apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: require-resources
namespace: ghc-kyverno-lab
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-container-resources
match:
any:
- resources:
kinds:
- Pod
validate:
message: "CPU and memory requests and limits are required."
pattern:
spec:
containers:
- resources:
requests:
cpu: "?*"
memory: "?*"
limits:
cpu: "?*"
memory: "?*"

Apply:

Terminal window
kubectl apply -f require-resources.yaml

Part 19 — Test Missing Resource Controls

Section titled “Part 19 — Test Missing Resource Controls”

Create a workload without resources.

Attempt deployment.

It should be rejected if the policy applies.

Then update the container:

resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "250m"
memory: "128Mi"

Resource controls support:

Availability

by reducing the risk of uncontrolled workload consumption.

Create:

compliant-pod.yaml

Use:

apiVersion: v1
kind: Pod
metadata:
name: compliant-app
namespace: ghc-kyverno-lab
labels:
owner: platform-team
spec:
securityContext:
runAsNonRoot: true
containers:
- name: web
image: nginx
securityContext:
privileged: false
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "250m"
memory: "128Mi"

Apply:

Terminal window
kubectl apply -f compliant-pod.yaml

Depending on the container image and runtime behavior, you may need to use an image compatible with non-root execution.

Your workload now has to satisfy:

Non-Privileged
+
Non-Root
+
Resource Controls

This demonstrates how multiple policy controls create:

Defense in Depth

Part 21 — Policy 05: Image Registry Governance

Section titled “Part 21 — Policy 05: Image Registry Governance”

Organizations may want workloads to use images from approved registries.

Why?

Because:

Unknown Image Source
Unknown Supply Chain
Higher Security Risk

A desired model may be:

Approved Registry
Validated Images
Production Cluster

For learning purposes, imagine your organization allows images only from:

registry.example.internal

Do not expect this example registry to contain usable images.

The goal is to understand the policy pattern.

Container Image
Approved Registry?
Yes → Allow
No → Reject

A Kyverno policy can validate image references using pattern matching.

Conceptually:

validate:
message: "Images must come from the approved registry."
pattern:
spec:
containers:
- image: "registry.example.internal/*"

For real implementation, validate the policy syntax against your deployed Kyverno version and your organization’s image naming convention.

Registry policy design needs to consider:

Init Containers
Ephemeral Containers
Mirrors
Digests
Approved Exceptions

Without control:

Developer
Random Public Image
Production

Potential risks include:

Malware
Typosquatting
Compromised Image
Unpatched Packages
Unverified Publisher

Registry restrictions can reduce this attack surface.

Consider:

nginx:latest

versus:

Explicit Version

or immutable image identifiers.

Mutable tags can create uncertainty:

Same Manifest
Different Image Later

An enterprise policy may restrict:

latest

to improve deployment consistency.

Part 25 — Policy 06: Disallow Latest Tag

Section titled “Part 25 — Policy 06: Disallow Latest Tag”

Conceptual policy objective:

IF image ends with :latest
THEN reject

This supports:

Version Control
Repeatability
Change Traceability

Sometimes a workload legitimately requires an exception.

The wrong approach is:

Disable Security Everywhere

The better approach is:

Specific Exception
Documented Reason
Limited Scope
Approval
Expiration / Review

Record:

Policy
Workload
Namespace
Business Owner
Justification
Compensating Controls
Review Date

You can now visualize:

RBAC
Can developer create Pod?
Yes
Kyverno
Is Pod compliant?
Yes
Create Pod

This is stronger than either control alone.

Create an intentionally non-compliant Pod that has:

No Owner Label
Privileged Container
No Non-Root Setting
No Resource Controls

Submit it.

Observe which policy violations are reported.

One workload may violate:

Multiple Security Controls

A mature security platform should report them clearly enough for the developer to remediate.

Security policy messages matter.

Bad message:

Request Denied

Better:

Privileged containers are not permitted.
Set securityContext.privileged to false.

Good policy design should help users understand:

What Failed
Why
How to Fix It

Run:

Terminal window
kubectl get policies

Inspect a policy:

Terminal window
kubectl describe policy require-non-root

You can also inspect YAML:

Terminal window
kubectl get policy require-non-root -o yaml

Identify:

Policy Name
Rules
Matched Resources
Validation Logic
Failure Action

If policy reporting resources are available in your installed Kyverno environment, inspect them.

Examples may include:

Terminal window
kubectl get policyreports

and cluster-level reporting where permitted.

The exact resource behavior depends on the installed Kyverno version and configuration.

Which Resource Failed?
Which Policy?
Which Rule?
What Was the Result?

Policy reports can contribute to:

Compliance Monitoring
Security Dashboards
Developer Feedback
Risk Tracking

Part 32 — Policy Enforcement vs Detection

Section titled “Part 32 — Policy Enforcement vs Detection”

Policy enforcement provides:

Preventive Control

Runtime security provides:

Detective Control

Example:

Kyverno
Blocks Privileged Pod

versus:

Runtime Security
Detects Suspicious Shell

Strong Kubernetes security uses both.

A compliance requirement may state:

Containers must not run with excessive privileges.

Translate that into:

Control Requirement
Kyverno Policy
Automated Evaluation
Evidence

This converts policy-as-code into compliance evidence.

Security Requirement Kyverno Control
Containers must not be privileged Validation policy
Workloads must run as non-root Validation policy
Resources must be defined Validation policy
Approved images only Image policy
Required ownership metadata Label validation

A professional rollout may follow:

Identify Risk
Define Security Requirement
Write Policy
Test in Lab
Run in Audit
Review Violations
Remediate Workloads
Enforce
Monitor

Always test:

Expected Pass
Expected Fail
Boundary Condition
Exception
Existing Workload Impact

Policy:

Containers Must Not Be Privileged

Tests:

privileged: true
Reject
privileged: false
Allow

Also test:

securityContext missing

to verify the policy behaves as intended.

A policy that only checks one specific YAML shape may be bypassed by another workload structure.

For example, enterprise policy design may need to consider:

Containers
Init Containers
Ephemeral Containers

This is why security policies should be:

Reviewed
Tested
Version Controlled

A poorly scoped policy could accidentally affect:

System Namespaces
Platform Controllers
Security Agents

Use:

Match
Exclude
Namespace Scope
Exception Process

carefully.

Be especially cautious before applying experimental policies to:

kube-system
kyverno
Monitoring Namespaces
CNI Namespaces

Platform components may have legitimate security requirements different from ordinary application workloads.

Part 40 — Policy Failure Troubleshooting

Section titled “Part 40 — Policy Failure Troubleshooting”

If an expected policy does not block a resource, check:

Is Kyverno Healthy?
Is the Policy Created?
Is the Correct Namespace Used?
Does Match Select the Resource?
Is the Resource Kind Correct?
Is the Pattern Correct?
Is the Failure Mode Enforcing?
Is There an Exclusion?
Policy Not Working
Check Policy Exists
Check Policy Status
Check Matching
Check Rule
Check Kyverno Logs
Retest

If your permissions allow, inspect Kyverno component logs using the deployment or Pod names in your environment.

First identify components:

Terminal window
kubectl get pods -n kyverno

Then use:

Terminal window
kubectl logs -n kyverno <kyverno-pod-name>

Do not assume a fixed Pod name.

Policy Processing Errors
Admission Issues
Configuration Errors
Controller Problems

Inspect:

Terminal window
kubectl get policy <policy-name> -o yaml

Review status-related information exposed by your Kyverno version.

A policy file that exists is not enough.

Confirm:

Policy Is Accepted
Policy Is Active
Policy Matches Intended Resources

Part 43 — Controlled Policy Failure Exercise

Section titled “Part 43 — Controlled Policy Failure Exercise”

Create a safe policy with an incorrect match target.

For example:

Policy Matches:
ConfigMap
But You Test:
Pod

Observe that:

Pod Is Not Evaluated by That Rule

Then correct the match.

Security policy effectiveness depends on:

Correct Requirement
+
Correct Policy Logic
+
Correct Scope

Document a workload violation.

Example:

Finding:
Privileged Container Deployment Attempt
Affected Resource:
privileged-test
Namespace:
ghc-kyverno-lab
Security Control:
disallow-privileged
Evidence:
Kyverno rejected the Pod because
securityContext.privileged was set to true.
Risk:
High
Threat Scenario:
If the workload were compromised,
privileged container access could increase
the potential impact on the Kubernetes node.
Recommendation:
Run the application without privileged mode
and grant only the minimum required capabilities.

Use:

Finding:
Policy:
Rule:
Affected Resource:
Namespace:
Observed Configuration:
Expected Configuration:
Evidence:
Security Impact:
Risk:
Recommendation:
Validation:

Suppose:

Before:
privileged = true

Policy result:

Rejected

Developer remediates:

privileged = false

Now validate:

Deployment Accepted
+
Application Functional

Successful security remediation requires:

Security Compliance
+
Operational Functionality

Capture:

Kyverno Components
Lab Namespace
Policy List
Require Label Policy
Privileged Container Policy
Non-Root Policy
Resource Policy
Rejected Workload
Compliant Workload
Policy Result
Remediation Validation
Lab:
Kyverno Policy Enforcement
Date:
Cluster:
Namespace:
Policy 01:
Require Owner Label
Test Result:
Policy 02:
Disallow Privileged Containers
Test Result:
Policy 03:
Require Non-Root
Test Result:
Policy 04:
Require Resource Controls
Test Result:
Security Finding:
Remediation:
Validation:

Review all policies and ask:

What Risk Does This Policy Address?
Which Resources Does It Match?
Which Namespaces?
What Is Excluded?
Does It Prevent the Risk?
Could It Break Legitimate Workloads?
How Is Compliance Measured?

Think:

Security Requirement
Policy Logic
Resource Match
Enforcement
Security Outcome

Weakness at any step reduces effectiveness.

You now have two important Kubernetes controls.

RBAC:

WHO
can perform the request?

Kyverno:

WHAT
resource configuration is acceptable?

Together:

Identity
Authorization
Policy Validation
Secure Resource

Kyverno can also enforce that teams follow networking standards.

For example, an organization may require:

Production Namespace
NetworkPolicy Present

NetworkPolicy defines:

Allowed Communication

Kyverno can help enforce:

Required Security Configuration

Kyverno policies can support image governance.

Security model:

Source
Build
Image
Registry
Image Policy
Kubernetes

This can help enforce:

Trusted Registries
Approved Image Patterns
Image Verification Requirements

Policy-as-code fits naturally into DevSecOps.

Developer
Manifest
CI Validation
Git
Deployment
Kyverno Admission

Instead of security being:

Final Manual Review

security becomes:

Continuous Guardrail

In an enterprise environment, policies should be treated like code.

Store them in:

Version Control

Review changes through:

Pull Requests
Peer Review
Security Review
Testing
Create
Test
Review
Approve
Deploy
Monitor
Improve

Use clear names.

Good:

disallow-privileged-containers
require-non-root
require-resource-limits

Poor:

policy1
security-rule
test

Clear naming helps:

Operations
Audit
Troubleshooting
Compliance

Use messages that explain remediation.

Example:

Privileged containers are prohibited.
Set securityContext.privileged to false.

Instead of:

Denied.

If a policy exception is needed, capture:

Who Requested It?
Why?
Which Resource?
Which Namespace?
Which Policy?
What Compensating Control?
When Does It Expire?

Exceptions should not become permanent security bypasses without review.

A mature policy program may track:

Number of Policies
Violations
Blocked Deployments
Audit Findings
Exceptions
Remediation Time

This helps answer:

Are Developers Becoming More Compliant?
Which Policies Cause Most Failures?
Where Is Security Debt Increasing?

Create a policy requirement:

Every Deployment
must contain:
environment
label

Use acceptable values such as:

dev
test
production

Test:

Missing Label → Reject
Valid Label → Allow

Design a policy that conceptually requires:

readOnlyRootFilesystem: true

for appropriate application containers.

Before enforcing it broadly, consider:

Which Applications Require Writable Paths?
Should Writable Paths Use Volumes?
Which Exceptions Are Required?

Design an image policy for:

Approved Registry Only

Document:

Allowed Pattern
Blocked Pattern
Business Justification
Exception Process

Create a policy rollout plan for production.

Use:

Stage 1
Develop Policy
Stage 2
Test in Lab
Stage 3
Audit in Development
Stage 4
Audit in Production
Stage 5
Remediate Violations
Stage 6
Enforce
Stage 7
Monitor

Map each control to a threat.

Policy Threat Reduced
Disallow privileged Host-level impact
Require non-root Excessive container privilege
Resource controls Resource exhaustion
Approved registry Untrusted software supply chain
Required labels Poor ownership/governance

Before deleting everything, capture your lab evidence.

List:

Terminal window
kubectl get policies -n ghc-kyverno-lab

List resources:

Terminal window
kubectl get all -n ghc-kyverno-lab

Then remove the training namespace:

Terminal window
kubectl delete namespace ghc-kyverno-lab

Namespace-scoped Policies and workloads inside it will be removed.

Delete only ClusterPolicies created specifically for this lab.

Example:

Terminal window
kubectl delete clusterpolicy <lab-policy-name>

Do not remove:

Production Policies
Platform Policies
Kyverno System Components

If you changed the active namespace:

Terminal window
kubectl config set-context --current --namespace=default

Verify:

Terminal window
kubectl config view --minify
  • Verified Kyverno availability
  • Inspected Kyverno resources
  • Understood Policy vs ClusterPolicy
  • Understood admission control
  • Created label validation policy
  • Created privileged-container policy
  • Created non-root policy
  • Created resource-control policy
  • Understood registry policy concepts
  • Tested non-compliant workload
  • Observed policy rejection
  • Created compliant workload
  • Verified successful deployment
  • Tested positive and negative cases
  • Inspected Policies
  • Reviewed policy results
  • Understood audit vs enforce
  • Troubleshot policy matching
  • Understood exception requirements
  • Identified privileged workload risk
  • Identified root execution risk
  • Identified image supply-chain risk
  • Identified resource exhaustion risk
  • Documented policy violation
  • Mapped requirements to policy
  • Understood staged enforcement
  • Understood policy version control
  • Understood exception governance
  • Understood policy metrics

You have now worked with:

Admission Control
Kyverno
Policy-as-Code
Kubernetes Policies
Validation
Security Guardrails
Workload Hardening
Image Governance
Resource Governance
Compliance Evidence
Policy Troubleshooting

These skills are valuable for:

Kubernetes Security Engineer
Platform Security Engineer
DevSecOps Engineer
Cloud Security Engineer
Cloud Security Architect
Platform Engineer
Security Consultant

Kyverno skills are especially valuable in environments where teams need:

Self-Service Kubernetes
+
Central Security Governance
  1. What is Kubernetes admission control?
  2. Where does admission control occur in the API request lifecycle?
  3. What is Kyverno?
  4. Why is Kyverno considered Kubernetes-native?
  5. What is policy-as-code?
  6. What is a Kyverno Policy?
  7. What is a ClusterPolicy?
  8. What is the difference between Policy and ClusterPolicy?
  9. How is RBAC different from Kyverno?
  10. Can a user with Pod creation permission still be blocked by Kyverno?
  11. What does validation do?
  12. What is mutation?
  13. What is resource generation?
  14. Why would you block privileged containers?
  15. Why should workloads run as non-root where possible?
  16. Why are resource requests and limits security-relevant?
  17. Why should organizations restrict container registries?
  18. What risk does the latest image tag create?
  19. What is an admission policy violation?
  20. What is the difference between audit and enforce?
  21. Why might an organization deploy policy in audit mode first?
  22. Why should policies have clear failure messages?
  23. Why should you test both compliant and non-compliant workloads?
  24. What could happen if a policy is scoped incorrectly?
  25. Why should system namespaces be treated carefully?
  26. How would you troubleshoot a policy that is not matching workloads?
  27. Why should Kyverno policies be stored in version control?
  28. What is a policy exception?
  29. Why should exceptions have review dates?
  30. How does Kyverno support compliance?
  31. How does Kyverno support DevSecOps?
  32. How can Kyverno contribute to software supply-chain security?
  33. What is an approved image registry?
  34. How can policy prevent insecure workload configuration?
  35. How do RBAC and admission policy complement each other?
  36. How do Kyverno and NetworkPolicy complement each other?
  37. Why is policy testing important?
  38. What is defense in depth?
  39. How would you introduce a new security policy into production safely?
  40. How would you measure whether a Kubernetes policy program is effective?

You should now be able to receive a security requirement such as:

Production containers
must not run privileged.

and translate it into:

Security Requirement
Kyverno Policy
Resource Match
Validation Rule
Violation Message
Enforcement
Testing

Then validate:

Privileged Workload
Rejected

and:

Compliant Workload
Allowed

You should also understand the difference between:

RBAC:
Can the developer deploy?

and:

Kyverno:
Is the deployment secure enough
to be accepted?

Together:

IDENTITY
AUTHORIZATION
POLICY
SECURE CONFIGURATION

Remember:

SECURITY REQUIREMENT
POLICY-AS-CODE
ADMISSION CONTROL
RESOURCE VALIDATION
ALLOW / DENY
COMPLIANT KUBERNETES

The goal is not to write policies simply because policy engines exist.

The goal is to turn:

Security Standards

into:

Automated,
Repeatable,
Enforceable
Guardrails.

Before this lab:

You understood that Kubernetes workloads
should follow security standards.

After this lab:

You translated standards into policies,
tested secure and insecure workloads,
blocked unsafe configurations,
validated compliant resources,
reviewed policy results,
and practiced policy governance.

You have moved from:

Security Recommendation

to:

Automated Security Enforcement.

➡️ Lab 04 — Network Policies

In the next lab, you will move from:

Can This Workload Be Deployed?

to:

Who Can This Workload
Communicate With?

You will build practical Kubernetes network segmentation using:

Pod Communication
Ingress Rules
Egress Rules
Namespace Segmentation
Default-Deny
Application Allow Rules
Lateral Movement Reduction

The lab progression becomes:

Lab 01 — Kubernetes Fundamentals
Understand Resources
Lab 02 — Kubernetes RBAC
Control Identity
Lab 03 — Kyverno
Control Configuration
Lab 04 — Network Policies
Control Communication

You are now building Kubernetes security layer by layer.