Rego is the declarative policy language used by Open Policy Agent (OPA). This tile covers writing and testing Rego policies for Kubernetes admission control, Terraform and infrastructure-as-code plan validation, Docker container authorization, HTTP API authorization, RBAC and role-based access control, data filtering, metadata annotations with opa inspect, and OPA policy testing with opa test.
99
Quality
Pending
Does it follow best practices?
Impact
99%
1.19xAverage score across 31 eval scenarios
Pending
The risk profile of this skill
external-referenceFunctions must operate only on their arguments. Never reference input or data directly inside a function body — pass all required data as explicit arguments. Regal external-reference.
Functions with external references are hard to test (you cannot mock input independently of the function) and create hidden dependencies.
# Wrong — references input inside function body
is_privileged(name) if {
some c in input.request.object.spec.containers # external reference!
c.name == name
c.securityContext.privileged
}
# Correct — container is passed as explicit argument
is_privileged(container) if {
container.securityContext.privileged == true
}zero-arity-functionFunctions without arguments are just rules. Don't define f() := value — write it as a rule f := value. Regal zero-arity-function.
function-arg-returnReturn values via the function head, not via a last argument. Use result := f(x) at the call site — never f(x, result). Regal function-arg-return.
# METADATA
# title: Container Security Validation
# description: Denies pods with privileged containers or missing resource limits
# authors:
# - Security Team <security@example.com>
# custom:
# category: kubernetes-admission
package kubernetes.admission
import rego.v1
# METADATA
# title: Deny privileged containers
# description: No container may run as privileged
# entrypoint: true
# custom:
# severity: HIGH
deny contains msg if {
input.request.kind.kind == "Pod"
some container in input.request.object.spec.containers
is_privileged(container)
msg := sprintf("container '%v' runs as privileged", [container.name])
}
# METADATA
# title: Deny missing resource limits
# description: All containers must declare CPU and memory limits
# entrypoint: true
# custom:
# severity: MEDIUM
deny contains msg if {
input.request.kind.kind == "Pod"
some container in input.request.object.spec.containers
not has_resource_limits(container)
msg := sprintf("container '%v' is missing resource limits", [container.name])
}
# Helper functions — take container as explicit argument, no external references
is_privileged(container) if {
container.securityContext.privileged == true
}
has_resource_limits(container) if {
container.resources.limits.cpu
container.resources.limits.memory
}# admission_test.rego
package kubernetes.admission_test
import rego.v1
import data.kubernetes.admission
test_deny_privileged_container if {
result := admission.deny with input as {"request": {
"kind": {"kind": "Pod"},
"object": {"metadata": {"name": "p"}, "spec": {"containers": [
{"name": "app", "securityContext": {"privileged": true},
"resources": {"limits": {"cpu": "100m", "memory": "128Mi"}}}
]}}
}}
count(result) == 1
}
test_deny_missing_limits if {
result := admission.deny with input as {"request": {
"kind": {"kind": "Pod"},
"object": {"metadata": {"name": "p"}, "spec": {"containers": [
{"name": "app", "securityContext": {"privileged": false}, "resources": {}}
]}}
}}
count(result) == 1
}
test_allow_compliant_container if {
result := admission.deny with input as {"request": {
"kind": {"kind": "Pod"},
"object": {"metadata": {"name": "p"}, "spec": {"containers": [
{"name": "app", "securityContext": {"privileged": false},
"resources": {"limits": {"cpu": "100m", "memory": "128Mi"}}}
]}}
}}
count(result) == 0
}docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
scenario-29
scenario-30
scenario-31