Skip to content

Instantly share code, notes, and snippets.

Last active March 30, 2021 17:33
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Using HAProxy as an API Gateway, Part 5 [Monetization]
$ git clone
$ cd haproxy-api-monetization-demo
$ sudo docker-compose up -d
$ curl --request POST \
--url 'http://localhost/auth/realms/weather-services/protocol/openid-connect/token' \
--data 'client_id=acme-corp' \
--data 'client_secret=7f2587ee-a178-4152-bd91-7b758c807759' \
--data 'grant_type=client_credentials'
lua-load /usr/local/share/lua/5.3/jwtverify.lua
setenv OAUTH_ISSUER http://localhost/auth/realms/weather-services
setenv OAUTH_AUDIENCE http://localhost/api/weather-services
setenv OAUTH_PUBKEY_PATH /etc/haproxy/pem/pubkey.pem
-----END PUBLIC KEY-----
frontend fe_api
bind :80
# a stick table stores the count of requests each clients makes
stick-table type ipv6 size 100k expire 1m store http_req_cnt
# allow 'auth' request to go straight through to Keycloak
http-request allow if { path_beg /auth/ }
use_backend keycloak if { path_beg /auth/ }
# deny requests that don't send an access token
http-request deny deny_status 401 unless { req.hdr(authorization) -m found }
# verify access tokens
http-request lua.jwtverify
http-request deny deny_status 403 unless { var(txn.authorized) -m bool }
# add the client's subscription level to the access logs: bronze, silver, gold
http-request capture var(txn.oauth_scopes) len 10
# deny requests after the client exceeds their allowed requests per minute
http-request deny deny_status 429 if { var(txn.oauth_scopes) -m sub bronze } { src,table_http_req_cnt gt 10 }
http-request deny deny_status 429 if { var(txn.oauth_scopes) -m sub silver } { src,table_http_req_cnt gt 100 }
http-request deny deny_status 429 if { var(txn.oauth_scopes) -m sub gold } { src,table_http_req_cnt gt 1000 }
# track clients' request counts. This line will not be called
# once the client is denied above, which prevents them from perpetually
# locking themselves out.
http-request track-sc0 src
default_backend be_api
$ sudo docker-compose restart haproxy
$ curl --request POST \
--url 'http://localhost/auth/realms/weather-services/protocol/openid-connect/token' \
--data 'client_id=acme-corp' \
--data 'client_secret=9e9e2acc-cd15-4878-9e5a-c815d29a976f' \
--data 'grant_type=client_credentials'
$ curl --request GET \
--url http://localhost/api/weather-services/43213 \
--header 'authorization: Bearer [ACCESS_TOKEN]'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment