Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

lukaszbudnik/haproxy-auth-gateway

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

10 Commits

Repository files navigation

haproxy-auth-gateway Docker

haproxy-auth-gateway is an authentication and authorization gateway for cloud native apps.

haproxy-auth-gateway features include:

  • parsing JWT token from the HTTP Authorization header
  • Keycloak realm roles support
  • RS256, HS256, HS512 signature verification
  • expiration time verification
  • issuer verification
  • audience verification

haproxy-auth-gateway can be configured with the following env variables:

  • OAUTH_PUBKEY_PATH - contains location to issuer public key (mandatory)
  • OAUTH_ISSUER - contains name of the issuer (optional)
  • OAUTH_AUDIENCE - contains name of the audience (optional)

Docker image

haproxy-auth-gateway is available on docker hub:

docker pull lukasz/haproxy-auth-gateway

or on ghcr.io:

docker pull ghcr.io/lukaszbudnik/haproxy-auth-gateway

Example

The below example shows how to deploy & configure lukasz/haproxy-auth-gateway in Kubernetes. It also shows how to invoke the Lua verify script and write ACLs.

If you are interested in running a complete distributed demo app on Kubernetes check out: lukaszbudnik/keycloak-kubernetes. This demo app uses Keycloak as Identity and Access Management solution and haproxy-auth-gateway for transparent authentication and authorization for backend services.

Kubernetes deployment

haproxy-auth-gateway requires:

  • your haproxy config (file)
  • public key of the JWT issuer (file)
  • OAUTH_PUBKEY_PATH set to the path of the public key of the JWT issuer (env variable)
  • OAUTH_ISSUER and OAUTH_AUDIENCE are optional should you want a more fine-grained JWT verification (env variable)

You can create haproxy config and public key files as config maps:

kubectl create configmap haproxy-auth-gateway-iss-cert --from-file=config/hotel.pem
kubectl create configmap haproxy-auth-gateway-haproxy-cfg --from-file=config/haproxy.cfg

Then you can map them to volumes and then mount them into haproxy-auth-gateway container. In the container spec you also set the env variables:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: gateway
 labels:
 app.kubernetes.io/name: gateway
spec:
 replicas: 1
 selector:
 matchLabels:
 app.kubernetes.io/name: gateway
 template:
 metadata:
 labels:
 app.kubernetes.io/name: gateway
 spec:
 containers:
 - name: gateway
 image: lukasz/haproxy-auth-gateway
 env:
 - name: OAUTH_PUBKEY_PATH
 value: /etc/certs/hotel.pem
 - name: OAUTH_ISSUER
 value: issuer_is_optional
 - name: OAUTH_AUDIENCE
 value: audience_is_optional
 ports:
 - containerPort: 80
 volumeMounts:
 - name: iss-cert
 mountPath: /etc/certs
 - name: haproxy-cfg
 mountPath: /usr/local/etc/haproxy
 volumes:
 - name: haproxy-cfg
 configMap:
 name: haproxy-auth-gateway-haproxy-cfg
 - name: iss-cert
 configMap:
 name: haproxy-auth-gateway-iss-cert
---
apiVersion: v1
kind: Service
metadata:
 name: gateway
 labels:
 app.kubernetes.io/name: gateway
spec:
 type: ClusterIP
 clusterIP: None
 selector:
 app.kubernetes.io/name: gateway
 ports:
 - protocol: TCP
 port: 80

Then we are ready to deploy haproxy-auth-gateway:

kubectl apply -f gateway.yaml

haproxy ACL

haproxy-auth-gateway will verify passed JWT and will (if all good):

  • set txn.authorized variable to true
  • set txn.roles variable to a comma separated list of realm_access.roles

Above variables can be used in haproxy ACLs.

For example:

# deny if no Authorization header sent
http-request deny unless { req.hdr(authorization) -m found }
# invoke the jwtverify Lua script
http-request lua.jwtverify
# check if authorized successfully
http-request deny unless { var(txn.authorized) -m bool }
# check roles
http-request deny if PATH_camarero ! { var(txn.roles) -m sub camarero }

Troubleshooting

The script outputs many useful debug messages. To enable debug add the following configuration to you haproxy.cfg:

global
 log stdout local0 debug
defaults
 log global

Sample JWT

A sample JWT token generated by Keycloak looks like this:

eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJXejFuaDNCWDI4UHMxVEMzSDRoOW52Q1VWRXpjVVBzQms4Z1NmeEp4ZS1JIn0.eyJleHAiOjE2MTM4NTQ3OTgsImlhdCI6MTYxMzg1Mzg5OCwiYXV0aF90aW1lIjoxNjEzODUzNjk2LCJqdGkiOiIxMmI1YTMxYS1hYjM1LTQxMDMtYTkxNC0wZjRlODUzMzg4ZjUiLCJpc3MiOiJodHRwczovL2F1dGgubG9jYWx0ZXN0Lm1lL2F1dGgvcmVhbG1zL2hvdGVsIiwic3ViIjoiMWE1NWUxMjktZjliYi00ZDYwLWJlZDEtMGJhYmIwOWJlZTNlIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicmVhY3QiLCJub25jZSI6Ijg4NGNiMzY1LTRjMTQtNDZhYS04ZTBjLWViM2Q3ZjBjYTRmMCIsInNlc3Npb25fc3RhdGUiOiI3NDZhNDZhZC1hY2Y3LTRhMTYtYWI2Yy1iMWZhNWE1YTgxZDMiLCJhY3IiOiIwIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY29jaW5lcmEiLCJkb25jZWxsYSIsImNhbWFyZXJvIl19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiQW5nZWxhIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYW5nZWxhIiwiZ2l2ZW5fbmFtZSI6IkFuZ2VsYSJ9.kkv2K-XYpHexnKmCoyNED_pO7G8hNI8hi2WCUzhpErkvrazNNZmUYZ8ZAjiybpi1u6ouc2EsHGykTNhUBD2jRhb2dWHYqcEEDaIn9MUq62B-nbTIcB-6vf1SrKnY_Vdnq_olmV_MhIJSQjPbDfcCVKKiUxHYmSBc9Vuno-enPehfUb_EpoRaM24SfJ0WDU281rTPxsgAJBdB4Yg0E9KMfCgaXkwRaHXMEGVpzHHqdi8S1lWwxs12Par-Qz4HqP-Tsw6KqNPU11dG3v6H_Q2fWmDsX5vvMqnmWkMQOFzco2fffsx7lcClPxNw3VghSVT-qB_7dMKUoT-DfyIo1Rcbqw

When parsed and decoded becomes the following.

Header:

{
 "alg": "RS256",
 "typ": "JWT",
 "kid": "Wz1nh3BX28Ps1TC3H4h9nvCUVEzcUPsBk8gSfxJxe-I"
}

Payload:

{
 "exp": 1613854798,
 "iat": 1613853898,
 "auth_time": 1613853696,
 "jti": "12b5a31a-ab35-4103-a914-0f4e853388f5",
 "iss": "https://auth.localtest.me/auth/realms/hotel",
 "sub": "1a55e129-f9bb-4d60-bed1-0babb09bee3e",
 "typ": "Bearer",
 "azp": "react",
 "nonce": "884cb365-4c14-46aa-8e0c-eb3d7f0ca4f0",
 "session_state": "746a46ad-acf7-4a16-ab6c-b1fa5a5a81d3",
 "acr": "0",
 "allowed-origins": ["http://localhost:3000"],
 "realm_access": {
 "roles": ["cocinera", "doncella", "camarero"]
 },
 "scope": "openid email profile",
 "email_verified": false,
 "name": "Angela",
 "preferred_username": "angela",
 "given_name": "Angela"
}

Public key:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyn1SYrKiXgJembEG1emG
lUw/NliK0tOTeKr8eBp7TZxI8D9k9FUkfzEeQyWekShPt3yTG9boZ9Sq/K7FAfs7
vXFG+kTKYYXysvfdkHHKJnPWEAJgqj3vDEpHB/Xqw5OtqOkSNPNYOxJ65ZmmZVNB
77NpGK5xW5s7xc7XXvLuILhfbOQXlObPbMnjVcnQSGHjmfbtTKsQ/im6ayxtShsL
FQgEJycplJU21WRy3T9cDHpGOMF3LehFIOmsxspcuC/idS0Nber3Fuw9QndSHZQL
KPTkDlyacPu9SyOJiMmD9S4QOZo9UVQWA8JlKa+KuL6TXyZ1OZdSkPSX1o1xeH7L
ewIDAQAB
-----END PUBLIC KEY-----

Original project

haproxy-auth-gateway is based on great project from haproxytech folks: https://github.com/haproxytech/haproxy-lua-oauth.

haproxy-auth-gateway contains changes to support Keycloak realm roles out of the box.

About

haproxy-auth-gateway is an authentication and authorization gateway for cloud native apps.

Topics

Resources

License

Stars

Watchers

Forks

Packages

AltStyle によって変換されたページ (->オリジナル) /