Share and distribute Open Policy Agent Bundles with OpenFaaS functions

One of the features of OpenFaaS is an auto-scaling mechanism. The auto-scaling means is that you can scale up/down your function instances as demand increases. Also, OpenFaaS provides a feature called zero-scale. By enabling this feature, you can scale to zero to recover idle resources is available in OpenFaaS.

Using OpenFaaS as an OPA’s Bundle API, you can have all the features by default with less effort. Also, you can’t have to manage to build/push and deploy phases with your Bundle API.

What you will learn in this post?

What is OPA (Open Policy Agent)?

OPA’s main goal is to decouple policy decision-making from policy enforcement. When your software needs to make policy decisions it queries OPA and supplies structured data (e.g., JSON) as input. OPA accepts arbitrary structured data as input.


How can we deploy OPA co-located with our service?

  • As a Go library
  • As a daemon

The recommended way is to run OPA is as a daemon. The reason is that this design increases performance and availability. By default, all of the policy and data that OPA uses to make decisions is kept in-memory for the low-latency and we should colocate OPA and the service to avoid the network latency also.


How can OpenFaaS help us with the OPA?

Let’s focus on Bundle API which is one of the Management API for OPA.

Bundle API’s purpose is to help OPA to load policies across the stack to the OPA instances.OPA can periodically download bundles of policy and data from remote HTTP servers. The policies and data are loaded on the fly without requiring a restart of OPA.

In this demo, we create a serverless function that mimics an OPA’s Bundle API. Simply, this serverless function designed as a plain file server. When OPA’s asks for the policies it basically returns bundles that ready on the filesystem as a response.



  • A Kubernetes cluster (kind, minikube, etc.)
  • OpenFaaS CLI
  • Arkade
  • Kubectl
  • KinD


1. Setup Tools

$ curl -sLS | sudo sh
  • KinD
$ arkade get kind
  • Kubectl
$ arkade get kubectl
  • faas-cli
$ arkade get faas-cli

2. Set Up Cluster

$ arkade get kind
$ kind create cluster

3. Deploy OpenFaaS

$ arkade install openfaas
  • Verify Deployment
$ kubectl rollout status -n openfaas deploy/gateway
  • Enable local access to Gateway
$ kubectl port-forward -n openfaas svc/gateway 8080:8080 &

4. Configure faas-cli

$ PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode; echo)
  • Login with using the password to Gateway
$ echo -n $PASSWORD | faas-cli login --username admin --password-stdin

5. Deploy Function

$ cd functions
$ faas-cli template store pull golang-middleware
$ faas-cli up -f bundle-api.yml

6. Load Images

$ docker image pull openpolicyagent/opa:latest
$ kind load docker-image openpolicyagent/opa:latest
$ docker image pull openpolicyagent/demo-restful-api:0.2
$ kind load docker-image openpolicyagent/demo-restful-api:0.27. Deploy the application
$ cd ../hack/manifests <br>
$ kubectl apply -f deployment.yaml
  • Verify Deployment
$ kubectl rollout status deployment demo-restful-api
  • Enable local access to the application
$ kubectl port-forward svc/demo-restful-api 5000:80 &


For this tutorial, our desired policy is:

  • People can see their own salaries (GET /finance/salary/{user} is permitted for {user})
  • A manager can see their direct reports’ salaries (GET /finance/salary/{user} is permitted for {user}’s manager)

Check that Alice can see her own salary

$ curl --user alice:password localhost:5000/finance/salary/alice

Check that bob CANNOT see charlie’s salary.

$ curl --user bob:password localhost:5000/finance/salary/charlie
  • bob is Alice's manager, so the following command will succeed.
$ curl --user bob:password localhost:5000/finance/salary/alice



I do mostly Go, Kubernetes, and cloud-native stuff ⛵️🐰🐳