https://github.com/open-policy-agent/opa-envoy-plugin
A plugin to enforce OPA policies with Envoy
https://github.com/open-policy-agent/opa-envoy-plugin
authorization cloud-native compliance envoy istio-proxy opa opa-envoy policy
Last synced: 3 months ago
JSON representation
A plugin to enforce OPA policies with Envoy
- Host: GitHub
- URL: https://github.com/open-policy-agent/opa-envoy-plugin
- Owner: open-policy-agent
- License: apache-2.0
- Created: 2018-03-08T19:55:10.000Z (over 8 years ago)
- Default Branch: main
- Last Pushed: 2026-02-26T19:39:29.000Z (4 months ago)
- Last Synced: 2026-02-27T01:33:50.981Z (4 months ago)
- Topics: authorization, cloud-native, compliance, envoy, istio-proxy, opa, opa-envoy, policy
- Language: Go
- Homepage:
- Size: 923 MB
- Stars: 353
- Watchers: 18
- Forks: 124
- Open Issues: 18
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Maintainers: MAINTAINERS.md
Awesome Lists containing this project
- awesome-opa - OPA Envoy Plugin - The OPA Envoy Plugin (compatible with Envoy, Istio, Gloo Edge, more) (Kubernetes / Service Mesh Authorization)
README
# opa-envoy-plugin
[](https://github.com/open-policy-agent/opa-envoy-plugin/actions) [](https://goreportcard.com/report/github.com/open-policy-agent/opa-envoy-plugin)
This repository contains an extended version of OPA (**OPA-Envoy**) that allows you to enforce OPA policies with Envoy.
> **Note about the repository size:** ~1 GB due to historical vendored WebAssembly binaries. For faster clones, use `git clone --depth 1`. See [partial clone options](https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/).
## Issue Management
Use [GitHub Issues](https://github.com/open-policy-agent/opa-envoy-plugin/issues) to request features or file bugs.
## Examples with Envoy-based service meshes
The OPA-Envoy plugin can be deployed with Envoy-based service meshes such as:
* [Istio](./examples/istio)
* [Gloo Edge](./examples/gloo-edge)
## Overview
OPA-Envoy extends OPA with a gRPC server that implements the [Envoy External
Authorization
API](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/ext_authz_filter.html).
You can use this version of OPA to enforce fine-grained, context-aware access
control policies with Envoy _without_ modifying your microservice.
More information about the OPA-Envoy plugin including performance benchmarks, debugging tips, detailed usage examples
can be found in the [OPA documentation](https://www.openpolicyagent.org/docs/envoy).
## Quick Start
This section assumes you are testing with Envoy v1.10.0 or later.
1. Start Minikube.
```bash
minikube start
```
1. Install OPA-Envoy.
```bash
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/opa-envoy-plugin/main/quick_start.yaml
```
The `quick_start.yaml` manifest defines the following resources:
* A ConfigMap containing an Envoy configuration with an External Authorization Filter to direct authorization checks to the OPA-Envoy sidecar.
See `kubectl get configmap proxy-config` for details.
* OPA configuration file, and an OPA policy into ConfigMaps in the namespace where the app will be deployed, e.g., `default`.
* A Deployment consisting an example Go application with OPA-Envoy and Envoy sidecars. The sample app provides information
about employees in a company and exposes APIs to `get` and `create` employees. More information about the app
can be found [here](https://github.com/ashutosh-narkar/go-test-server). The deployment also includes an init container that
installs iptables rules to redirect all container traffic through the Envoy proxy sidecar. More information can be
found [here](https://github.com/open-policy-agent/contrib/tree/main/envoy_iptables).
1. Make the application accessible outside the cluster.
```bash
kubectl expose deployment example-app --type=NodePort --name=example-app-service --port=8080
```
1. Set the `SERVICE_URL` environment variable to the service’s IP/port.
**minikube**:
```bash
export SERVICE_PORT=$(kubectl get service example-app-service -o jsonpath='{.spec.ports[?(@.port==8080)].nodePort}')
export SERVICE_HOST=$(minikube ip)
export SERVICE_URL=$SERVICE_HOST:$SERVICE_PORT
echo $SERVICE_URL
```
**minikube (example)**:
```bash
192.168.99.100:31380
```
1. Exercise the sample OPA policy.
For convenience, we’ll want to store Alice’s and Bob’s tokens in environment variables.
```bash
export ALICE_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiZ3Vlc3QiLCJzdWIiOiJZV3hwWTJVPSIsIm5iZiI6MTUxNDg1MTEzOSwiZXhwIjoxOTQxMDgxNTM5fQ.rN_hxMsoQzCjg6lav6mfzDlovKM9azaAjuwhjq3n9r8"
export BOB_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYWRtaW4iLCJzdWIiOiJZbTlpIiwibmJmIjoxNTE0ODUxMTM5LCJleHAiOjE5NDEwODE1Mzl9.ek3jmNLPclafELVLTfyjtQNj0QKIEGrbhKqpwXmQ8EQ"
```
Check that `Alice` can get employees **but cannot** create one.
```bash
curl -i -H "Authorization: Bearer "$ALICE_TOKEN"" http://$SERVICE_URL/people
curl -i -H "Authorization: Bearer "$ALICE_TOKEN"" -d '{"firstname":"Charlie", "lastname":"OPA"}' -H "Content-Type: application/json" -X POST http://$SERVICE_URL/people
```
Check that `Bob` can get employees and also create one.
```bash
curl -i -H "Authorization: Bearer "$BOB_TOKEN"" http://$SERVICE_URL/people
curl -i -H "Authorization: Bearer "$BOB_TOKEN"" -d '{"firstname":"Charlie", "lastname":"Opa"}' -H "Content-Type: application/json" -X POST http://$SERVICE_URL/people
```
Check that `Bob` **cannot** create an employee with the same firstname as himself.
```bash
curl -i -H "Authorization: Bearer "$BOB_TOKEN"" -d '{"firstname":"Bob", "lastname":"Rego"}' -H "Content-Type: application/json" -X POST http://$SERVICE_URL/people
```
## Configuration
To deploy OPA-Envoy include the following container in your Kubernetes Deployments:
```yaml
containers:
- image: openpolicyagent/opa:latest-envoy
imagePullPolicy: IfNotPresent
name: opa-envoy
volumeMounts:
- mountPath: /config
name: opa-envoy-config
args:
- run
- --server
- --addr=localhost:8181
- --diagnostic-addr=0.0.0.0:8282
- --config-file=/config/config.yaml
livenessProbe:
httpGet:
path: /health?plugins
port: 8282
readinessProbe:
httpGet:
path: /health?plugins
port: 8282
```
The OPA-Envoy configuration file should be volume mounted into the container. Add the following volume to your Kubernetes Deployments:
```yaml
volumes:
- name: opa-envoy-config
configMap:
name: opa-envoy-config
```
### Example Bundle Configuration
In the [Quick Start](#quick-start) section an OPA policy is loaded via a volume-mounted ConfigMap. For production
deployments, we recommend serving policy [Bundles](https://www.openpolicyagent.org/docs/management-bundles) from a remote HTTP server.
Using the configuration shown below, OPA will download a sample bundle from [https://www.openpolicyagent.org](https://www.openpolicyagent.org).
The sample bundle contains the exact same policy that was loaded into OPA via the volume-mounted ConfigMap.
**config.yaml**:
```yaml
services:
- name: controller
url: https://www.openpolicyagent.org
bundles:
envoy/authz:
service: controller
plugins:
envoy_ext_authz_grpc:
addr: :9191 # default `:9191`
path: envoy/authz/allow # default: `envoy/authz/allow`
dry-run: false # default: false
enable-reflection: false # default: false
grpc-max-recv-msg-size: 40194304 # default: 1024 * 1024 * 4
grpc-max-send-msg-size: 2147483647 # default: max Int
skip-request-body-parse: false # default: false
enable-performance-metrics: false # default: false. Adds `grpc_request_duration_seconds` prometheus histogram metric
```
You can download the bundle and inspect it yourself:
```bash
mkdir example && cd example
curl -s -L https://www.openpolicyagent.org/bundles/envoy/authz | tar xzv
```
In this way OPA can periodically download bundles of policy from an external server and hence loading the policy via a
volume-mounted ConfigMap would not be required. The `readinessProbe` to `GET /health?bundles` ensures that the `opa-envoy`
container becomes ready after the bundles are activated.
## Dependencies
Dependencies are managed with [Modules](https://github.com/golang/go/wiki/Modules).
If you need to add or update dependencies, modify the `go.mod` file or
use `go get`. More information is available [here](https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies).
Finally commit all changes to the repository.
## Maintainers
Please see the [MAINTAINERS.md](./MAINTAINERS.md) file for maintainer details.