Extracting the Input That OPA Reviews
· 6 min read
Introduction
As covered in the Learning OPA with TMC series, OPA is a powerful tool. You can use the Rego Playground to test the Rego language.
https://play.openpolicyagent.org/
But how do you actually extract the information that becomes this "Input"?... It turns out the method is properly documented:
https://github.com/open-policy-agent/gatekeeper#viewing-the-request-object
This post is a note on how to do it.
How to
First, create a ConstraintTemplate that returns an error for everything, like this:
cat <<EOF | kubectl apply -f -
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sdenyall
spec:
crd:
spec:
names:
kind: K8sDenyAll
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdenyall
violation[{"msg": msg}] {
msg := sprintf("REVIEW OBJECT: %v", [input.review])
}
EOF
Then create a constraint based on it. In this example, it triggers on Namespace creation.
cat <<EOF | kubectl apply -f -
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyAll
metadata:
name: deny-all-namespaces
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
EOF
In this state, creating a Namespace spits out the JSON usable as Input along with the error.
kubectl create ns hoge
Error from server ([denied by deny-all-namespaces] REVIEW OBJECT: {"object": {"apiVersion": "v1", "kind": "Namespace", "metadata": {"uid": "39365652-a7fb-4463-b23d-e00c6dc43374", "creationTimestamp": "2020-10-01T13:33:52Z", "name": "hoge"}, "spec": {"finalizers": ["kubernetes"]}, "status": {"phase": "Active"}}, "oldObject": null, "uid": "11b3051f-1c27-4d82-8bac-d4a0535b01e3", "requestKind": {"group": "", "version": "v1", "kind": "Namespace"}, "userInfo": {"username": "kubernetes-admin", "groups": ["system:masters", "system:authenticated"]}, "name": "hoge", "operation": "CREATE", "dryRun": false, "options": {"kind": "CreateOptions", "apiVersion": "meta.k8s.io/v1"}, "_unstable": {}, "kind": {"group": "", "version": "v1", "kind": "Namespace"}, "resource": {"resource": "namespaces", "group": "", "version": "v1"}, "requestResource": {"group": "", "version": "v1", "resource": "namespaces"}}): admission webhook "validation.gatekeeper.sh" denied the request: [denied by deny-all-namespaces] REVIEW OBJECT: {"object": {"apiVersion": "v1", "kind": "Namespace", "metadata": {"uid": "39365652-a7fb-4463-b23d-e00c6dc43374", "creationTimestamp": "2020-10-01T13:33:52Z", "name": "hoge"}, "spec": {"finalizers": ["kubernetes"]}, "status": {"phase": "Active"}}, "oldObject": null, "uid": "11b3051f-1c27-4d82-8bac-d4a0535b01e3", "requestKind": {"group": "", "version": "v1", "kind": "Namespace"}, "userInfo": {"username": "kubernetes-admin", "groups": ["system:masters", "system:authenticated"]}, "name": "hoge", "operation": "CREATE", "dryRun": false, "options": {"kind": "CreateOptions", "apiVersion": "meta.k8s.io/v1"}, "_unstable": {}, "kind": {"group": "", "version": "v1", "kind": "Namespace"}, "resource": {"resource": "namespaces", "group": "", "version": "v1"}, "requestResource": {"group": "", "version": "v1", "resource": "namespaces"}}
Handy.
Summary
Getting OPA's Input is easy.