Illustration: Open Policy Agent

Enforcing Kubernetes a policy with Open Policy Agent

Roy Hiroyuki OSAKI
5 min readFeb 19, 2020

This article’s goal is as follows,

  • Run Open Policy Agent on top of Kubernetes
  • Create a minimum policy for Open Policy Agent which is similar to tutorial
  • Check that the policy is enforced to requests in Kubernetes

What is Open Policy Agent (OPA)

Open Policy Agent (OPA) is a policy engine which enforces Kubernetes and its requests to obey given policies. Its main benefit is that Kubernetes administrator can secure her/his organization with rejecting any requests that might break rules.

Open Policy Agent (OPA) checks if requests follow rules

OPA executes two kinds of policy check.

  • Validation : Admit requests which follow rules and reject other requests
  • Mutation: Update request contents in order to follow rules

We can apply OPA policy to Docker, Kubernetes, SSH, Terraform and Envoy.
At this time, OPA v0.17.1 is available.
OPA can read REGO language in policy files.

I will show the installation process and check results of OPA.

Prepare OPA environmet

First, I prepared this environment

  • Kubernetes (using Kind)
  • kubectl, helm

There are two packages which enables Kubernetes to support OPA control.

  • kube-mgmt
  • Gatekeeper

I tried kube-mgmt this time because I am using helm and kube-mgmt supports Mutating

Helm package for kube-mgmt and OPA is published here.

helm/charts

(1) Install OPA (with kube-mgmt) onto Kubernetes

I created a Namespace called opa.

kubectl create namespace opa

Next, I created a configuration file for helm installation.

# admissionControllerKind: I chose Mutating
admissionControllerKind: MutatingWebhookConfiguration
# opa: No need to include existing policy files
opa: null
# mgmt: We have to enable this feature in order to add configmap
mgmt:
configmapPolicies:
enabled: true
namespaces: [opa, opa-example]
requireLabel: true
replicate:
cluster:
- v1/namespaces
namespace:
- extensions/v1beta1/ingresses
# rbac: OPA needs to access these kinds of resources in Kubernetes
rbac:
create: true
rules:
cluster:
- apiGroups:
- "*"
resources:
- configmaps
verbs:
- get
- list
- watch
- patch
- update
- apiGroups:
- "*"
resources:
- namespaces
- ingresses
verbs:
- get
- list
- watch
sar:
enabled: true
authz:
enabled: false

I installed OPA and kube-mgmt with helm and this configuration file (doc).

$ helm repo add open-policy-agent https://open-policy-agent.github.io/kube-mgmt/charts
$ helm repo up
$ helm install opa open-policy-agent/opa -f helm-values.yaml --namespace opa

(2) Create a Policy

The system overview is like this.

This OPA example checks Ingress requests

This OPA example checks Ingress addition requests..

Kubernetes configuration is as follows.

  • All requests is about creation of ingress
  • data is information in Kubernetes itself ( Namespace configuration)
  • policy includes two policy files; the first is a default policy main.rego, and the second is a policy ingress-whitelist.rego that is specific for Ingress resource.

Take a close look at these policies.

The first is main.rego. This allows all requests basically.

The second is ingress-whitelist.rego . This allows some Ingress addition requests whose hostname is supported in Namespace and rejects other requests.

I added ConfigMap resource including these two files. This example command finishes two files with one command. But it is not necessary and you can use seperate ConfigMap resources for each file.

The most important point is that it must include a specific labal openpolicyagent.org/policy=rego that enables OPA to include the ConfigMap as policy.

$ kubectl create  -n opa configmap policy --from-file ./main.rego --from-file ./ingress-whitelist.rego
$ kubectl label -n opa configmap policy openpolicyagent.org/policy=rego

I checked the policy was imported into OPA.

After OPA imported this ConfigMap as policy, special annotation openpolicyagent.org/policy-status: ‘{“status”:”ok”}' was added in the ConfigMap automatically by OPA. I confirmed the policy was successfully imported.

(3) Check the Policy working

Last, I checked if the policy was working like this.

I created a Namespace for testing.

This Namespace has an annotation ingress-whitelist which can be seen from OPA. This Namespace is found to allow two patterns of hostname in Ingress; *.ok.com and *.secondok.com .

$ kubectl apply -f test/namespace.yaml 
namespace/opa-example created

I tried to create these Ingress resources in this Namespace.

  1. ingress-ok.yaml

2. ingress-ok2.yaml

3. ingress-bad.yaml

These Ingress resource configurations are different in only hostname.

  - host: test.ok.com
- host: test2.secondok.com
- host: test.ng.com

I checked if these Ingress configurations could be added in Kubernetes.

$ kubectl create -f test/ingress-ok.yaml
ingress.extensions/ingress-ok created

$ kubectl create -f test/ingress-ok2.yaml
ingress.extensions/ingress-ok-2 created

$ kubectl create -f test/ingress-bad.yaml
Error from server (invalid ingress host "test.ng.com"): error when creating "test/ingress-bad.yaml": admission webhook "webhook.openpolicyagent.org" denied the request: invalid ingress host "test.ng.com"

Here is what I got.

The first two Ingress configurations were successfully added to Kubernetes. But the last one could not be added with displaying some error. This was meant to be. The last one included unsupported hostname by Namespace (not included in *.ok.com and *.secondok.com). And I found the error message was created by ingress-whitelist.rego policy as the form of msg.

I confirmed the OPA policy was working correctly.

Summary

I confirmed basic function of OPA with simple environment.

  • Ran OPA on top of Kubernetes
  • Added simple policies as ConfigMap
  • Checked the policies were working successfully after I added some Ingress resources

I found OPA was powerful. This would be possibly universal policy engine across Kubenetes and other platform tools.

Writing a policy in the REGO language, which is a special programming language, is a great feature, and at the same time, I feels like it raises the barrier to entry a little.

Reference

--

--

Roy Hiroyuki OSAKI

@Hiroyuki_OSAKI Sr. research engineer (Hitachi America/Hitachi), CKA/CKAD/CKS, 大崎裕之(Japan) The opinions expressed here are my own, not those of Company.