A lightweight, reusable Kong custom plugin for role-based authorization using OIDC/JWT claims (with Keycloak-friendly defaults).
This repository packages a Kong plugin named oidc-role that reads identity claims from validated tokens and maps them to Kong consumer/ACL authorization decisions.
Author: Written by Vahid Tavakkoli (2026).
oidc-role is intended to be used after authentication (for example, after kong-oidc, OpenID Connect introspection, or JWT validation).
The plugin focuses on authorization and identity mapping by:
- validating/introspecting bearer tokens (depending on config),
- extracting claim values (including nested paths),
- optionally mapping claims to Kong consumers,
- injecting identity headers/groups for upstream services,
- enabling Kong ACL-based access control per route/service.
This project enables centralized API authorization in Kong when your identity provider (for example Keycloak) provides role/group claims in access tokens.
Typical use case:
- Identity provider authenticates users and issues tokens,
- Kong plugin reads token claims such as
realm_access.roles, - Kong ACL and consumer mapping enforce route-level access.
- Kong custom plugin structure compatible with Kong plugin loading.
- Works in both:
- DB-less mode (
kong.ymldeclarative config), - DB-backed mode (PostgreSQL + Admin API / decK / Kong Manager).
- DB-less mode (
- Supports nested claim extraction (for example
realm_access.roles). - Optional consumer mapping by
id,username, orcustom_id. - Identity/group/header injection for upstream services.
- Docker-based local demo setup for quick testing.
- Request reaches Kong route/service with
oidc-roleenabled. - Plugin processes auth path based on configuration:
- bearer JWT verify,
- introspection,
- or OIDC authorization flow.
- Plugin extracts configured claims and sets Kong credential context.
- Plugin can map claims to Kong consumer entities.
- Kong ACL plugin (or upstream authorization logic) enforces route access.
.
├── config-example/
│ └── kong.yml # DB-less declarative example (demo values)
├── oidc-role/
│ ├── filter.lua # Request filtering helper
│ ├── handler.lua # Main plugin handler (access phase)
│ ├── schema.lua # Kong plugin schema
│ ├── session.lua # Session secret handling
│ └── utils.lua # Shared helpers
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile # Custom Kong image with plugin
├── LICENSE # MIT license
├── Makefile # Common developer commands
├── NOTICE # Attribution / notices
├── SECURITY.md
├── VERSION
└── docker-compose.yml # DB-less docker compose demo
docker build -t kong-oidc-role:local .Copy oidc-role/ to:
/usr/local/share/lua/5.1/kong/plugins/oidc-role
Then enable plugin loading in Kong config:
plugins = bundled,oidc-roleRestart Kong.
plugins:
- name: oidc-role
config:
discovery: "https://<idp-host>/realms/<realm>/.well-known/openid-configuration"
client_id: "<client-id>"
client_secret: "<client-secret>"
bearer_only: "yes"
use_jwks: "yes"
consumer_claim: "realm_access.roles"
consumer_by: "custom_id"- Update
config-example/kong.ymlwith your real IdP endpoints and credentials. - Start Kong in DB-less mode.
docker compose up --buildUse PostgreSQL-backed Kong and configure resources via Admin API/decK.
High-level steps:
- Install plugin on all Kong data-plane nodes.
- Enable
oidc-rolein Kongpluginslist. - Create services/routes/consumers.
- Attach
oidc-roleand ACL config via Admin API or declarative sync (decK).
# build
make build
# run in detached mode
make up
# inspect logs
make logs
# stop/remove containers
make downBy default the compose setup exposes:
- Proxy:
http://localhost:9180 - Admin API:
http://localhost:9181
- Keep plugin behavior backwards-compatible unless explicitly versioned.
- Favor small, targeted changes in Lua handlers.
- Use placeholders for demo configuration values (never real secrets).
- Run
make validatebefore committing docs/config updates.
No automated unit test suite is currently bundled with runtime dependencies in this repository.
Recommended validation path:
- Static/config checks (
make validate), - Launch demo (
make up), - Verify unauthorized and authorized request behavior with curl.
Unauthorized (missing/invalid token):
curl -i http://localhost:9180/lob1Authorized (valid token placeholder):
curl -i \
-H "Authorization: Bearer <VALID_ACCESS_TOKEN>" \
http://localhost:9180/lob1Replace
<VALID_ACCESS_TOKEN>with a real token from your identity provider.
- This repository is primarily a reference implementation and demo packaging.
- Behavior depends on correct token/claim structure from your IdP.
- Production-hardening (timeouts, retries, observability, policy rules) should be tailored to your environment.
- Do not store client secrets in plain text in version-controlled config files.
- Use environment variables, Docker secrets, or a secret manager.
- Treat
config-example/kong.ymlvalues as placeholders only. - Validate TLS settings and avoid insecure
ssl_verifybehavior in production. - Review and threat-model this plugin before production deployment.
See SECURITY.md for reporting guidance and deployment recommendations.
- Add automated plugin tests (busted/spec + CI workflow).
- Add compatibility matrix for Kong versions.
- Add examples for claim-based role matching policies beyond consumer mapping.
- Improve structured logging and operational metrics.
- Author: Vahid Tavakkoli (2026)
- License: MIT (see
LICENSE) - Additional attribution details: see
NOTICE