Newer version of Envoy (after v1.17.0?) supports a feature, External Authorization (part of the v2 API), which you can configure the network or http filter to call external service (via http or gRPC) for authentication/authorization purpose. This is a very simple example to illustrate the setup.
This example is based on the front-proxy example in official Envoy github
https://github.com/envoyproxy/envoy/tree/master/examples/front-proxy
After cloning the example from github, go to the examples/front-proxy directory and run
~/Documents/envoy-ext-authz 🐰$ docker-compose up -d
Starting envoy-ext-authz_service2_1 ... done
Starting envoy-ext-authz_front-envoy_1 ... done
Starting envoy-ext-authz_service1_1 ... done
The front-envoy and 2 services with side-car envoy dockers are running. Try to access the http://localhost:8000/service/1 endpoint using Postman.
Now what about if we want to authenticate the request before it’s passed to upstream services?
First of all, let’s create a dummy authentication service using express that will extract the basic auth header and validate the username and password in hardcoded manner.
Dockerize it
Add the following to the docker-compose.yml
Run docker-compose build
~/Documents/envoy-ext-authz 🐰$ docker-compose up --build
Now there should be 4 docker containers running:
The final step is to modify the front-envoy.yaml. In the filter section, add the envoy.ext-authz filter and under the clusters section, add the auth service cluster.
All set! Let’s run the request again
It got a 403 Forbidden without setting the basic auth header.
The request is directed to service 1 successful when the username & password is correct.
Got 401 when the password didn’t match.
Restriction
It’s pretty straight forward, but one of restriction I encountered is the request body cannot be passed to the external auth service, so if you do something like verifying digital signature against the request body, it won’t work.