Microservices Authorization using Open Policy Agent and API Gateway
This is a proof of concept implementation of using Open Policy Agent for microservices authorization in API Gateway (Traefik).
Detailed description of our use-case and implementation is available in our blog - https://blog.appsecco.com/microservices-authorization-using-open-policy-agent-and-traefik-api-gateway-ae30f3bf2846
Why
Authentication and authorization in a microservices environment is non-trivial. This becomes especially true when identity and authorization controls are distributed across different applications.
In this proof of concept scenario, we want to demonstrate using the API Gateway pattern for centralised enforcement of authorisation rules.
To do this, we use following components
- Traefik (API Gateway)
- Open Policy Agent (AuthZ policy management and evaluation)
- Middleware (custom) for connecting Traefik with Open Policy Agent
Architecture
Setup
docker-compose up
Test
Request api-1
without authorization
curl http://localhost:88/api-1/
Generate a JWT for AuthZ for user1
export TOKEN1=`ruby -rjwt -e 'print JWT.encode({"email":"user1@tkqlm.onmicrosoft.com"}, nil, "none")'`
Test token: eyJhbGciOiJub25lIn0.eyJlbWFpbCI6InVzZXIxQHRrcWxtLm9ubWljcm9zb2Z0LmNvbSJ9.
Generate a JWT for AuthZ for user2
export TOKEN2=`ruby -rjwt -e 'print JWT.encode({"email":"user2@tkqlm.onmicrosoft.com"}, nil, "none")'`
Test token: eyJhbGciOiJub25lIn0.eyJlbWFpbCI6InVzZXIyQHRrcWxtLm9ubWljcm9zb2Z0LmNvbSJ9.
Request api-1
with the user1
token
curl -H "OPA-Authorization: $TOKEN1" http://localhost:88/api-1/
Try requesting api-1
with the user2
token
curl -H "OPA-Authorization: $TOKEN2" http://localhost:88/api-1/
Whats inside?
- Traefik is used as the API Gateway
- Check configuration in
traefik/traefik.yml
andtraefik/dynamic.yml
- Check configuration in
- Open Policy Agent is used for centralized authorization policy evaluation
- Check
opa/policy.rego
- Check
- 3 backend service is implemented
/
is public/api-1
is available to any user withrole=api-1-users
/api-2
is available to any user withrole=api-2-users