Sign inSign up

cnapcloud/kong-oidc

By cnapcloud

•Updated 6 months ago

Image
0

3.0K

cnapcloud/kong-oidc repository overview

⁠cnapcloud/kong-oidc

⁠Kong OIDC & Cookies-to-Headers Plugin

This image provides a powerful integration for Kong API Gateway to support seamless OpenID Connect (OIDC) authentication.

⁠Key Features
  • OIDC Authentication: Support for Identity Providers (IdPs) like Keycloak, Auth0, and any OIDC-compliant provider.
  • Token Propagation: Includes the cookies-to-headers plugin to propagate cookies (e.g., ID tokens) as headers to your backend services.
  • Architecture Friendly: Optimized for microservice-based architectures that require secure and transparent identity flow.
⁠Resources

⁠Docker Compose Usage Guide

This guide explains how to quickly set up a development environment for cnapcloud/kong-oidc using Docker Compose, including PostgreSQL, Keycloak, Redis, and Kong.


⁠Prerequisites
  • Docker ≥ 28.x
  • Docker Compose ≥ v2.33.x
  • Basic knowledge of Docker and environment variables

⁠Directory Structure
kong-oidc-demo
├─ docker-compose.yml
├─ .env
└─ init-db.sql
  • docker-compose.yml – Service definitions for Postgres, Keycloak, Redis, Kong, and a sample backend (httpbin).
  • .env – Environment variables for database credentials, Keycloak, and Kong.
  • init-db.sql – SQL script to create users and databases for Keycloak and Kong.

⁠Step 1: Configure Environment Variables

Create a .env file with the following content:

# Postgres
POSTGRES_TAG=:13
POSTGRES_USER=postgres
POSTGRES_PW=password
POSTGRES_DB_NAME=postgres

# Database for Kong
KONG_DB_USER=kong
KONG_DB_PW=password
KONG_DB_NAME=kong

# Keycloak
KEYCLOAK_TAG=:25.0.6
KEYCLOAK_PORT=8080
KEYCLOAK_USER=admin
KEYCLOAK_PW=password
KEYCLOAK_DB_USER=keycloak
KEYCLOAK_DB_PASSWORD=password
KEYCLOAK_DB_NAME=keycloak

# Kong
KONG_TAG=:3.9.1
KONG_DB_PORT=5432
KONG_SESSION_STORE_PORT=6379
KONG_HTTP_ADMIN_PORT=8001
KONG_HTTP_PROXY_PORT=8000

Change passwords and ports if needed for your environment.


⁠Step 2: Initialize Databases

Create an init-db.sql file with the following content to set up PostgreSQL users and databases:

-- User creation
CREATE USER keycloak WITH PASSWORD 'password';
CREATE USER kong WITH PASSWORD 'password';

-- Database creation
CREATE DATABASE kong OWNER kong;
CREATE DATABASE keycloak OWNER keycloak;

-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE kong TO kong;
GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;

This SQL will automatically be executed when the Postgres container starts.


⁠Step 3: Define Services in docker-compose.yml

Create a docker-compose.yml with the following configuration:

services:
  postgres_db:
    image: postgres${POSTGRES_TAG}
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER:     ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PW}
      POSTGRES_DB:       ${POSTGRES_DB_NAME}
    volumes:
      - .data/postgres16:/var/lib/postgresql/data
      - ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql

  keycloak:
    image: quay.io/keycloak/keycloak${KEYCLOAK_TAG}
    environment:
      JAVA_OPTS: -Xms1024m -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:8000
      _JAVA_OPTIONS: -XX:UseSVE=0
      KC_LOG_LEVEL: info
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres_db/${KEYCLOAK_DB_NAME}
      KC_DB_USERNAME: postgres
      KC_DB_PASSWORD: password
      KC_HTTP_ENABLED: true
      HTTP_ADDRESS_FORWARDING: true
      KEYCLOAK_ADMIN: ${KEYCLOAK_USER}
      KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_PW}
    command: start-dev
    ports:
      - 8080:8080
      - 9000:9000
    depends_on:
      - postgres_db

  redis:
    image: redis
    command: ["redis-server", "--requirepass", "redis"]
    ports:
      - 6389:6379

  kong:
    image: cnapcloud/kong-oidc${KONG_TAG}
    ports:
      - 8000:8000
      - 8443:8443
      - 8001:8001
      - 8002:8002
      - 8444:8444
    environment:
      KONG_LOG_LEVEL: info
      KONG_PLUGINS: bundled,oidc,cookies-to-headers
      KONG_X_SESSION_COMPRESSOR: zlib
      KONG_NGINX_LARGE_CLIENT_HEADER_BUFFERS: "4 16k"
      KONG_X_SESSION_STORAGE: redis
      KONG_X_SESSION_REDIS_HOST: redis
      KONG_X_SESSION_REDIS_PASSWORD: redis
      KONG_DB_UPDATE_FREQUENCY: "5"
      KONG_DB_UPDATE_PROPAGATION: "0"
      KONG_DB_CACHE_TTL: "3600"
      KONG_DATABASE:    postgres
      KONG_PG_HOST:     postgres_db
      KONG_PG_DATABASE: ${KONG_DB_NAME}
      KONG_PG_USER:     ${KONG_DB_USER}
      KONG_PG_PASSWORD: ${KONG_DB_PW}
      KONG_ADMIN_LISTEN: 0.0.0.0:${KONG_HTTP_ADMIN_PORT}
      KONG_PROXY_LISTEN: 0.0.0.0:${KONG_HTTP_PROXY_PORT}
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG:  /dev/stderr
      KONG_ADMIN_ERROR_LOG:  /dev/stderr
    depends_on:
      - postgres_db

  httpbin:
    image: kong/httpbin:latest
    ports:
      - 9080:80

Remove the _JAVA_OPTIONS: -XX:UseSVE=0 entry from the Keycloak service environment configuration on amd64 linux systems.


⁠Step 4: Start the Stack

Run the following command in the project root:

docker-compose up postgres_db redis -d
docker-compose run --rm kong kong migrations bootstrap
docker-compose up -d

This will:

  1. Start PostgreSQL and initialize databases.
  2. Launch Keycloak for identity management.
  3. Start Redis for session storage.
  4. Start Kong with the OIDC plugin enabled.
  5. Start a test backend (httpbin) for proxy testing.

⁠Step 5: Verify Services
  • PostgreSQL: localhost:5432
  • Keycloak: http://localhost:8080
  • Kong Admin API: http://localhost:8001
  • Kong Manager API: http://localhost:8002
  • Kong Proxy: http://localhost:8000
  • Httpbin (test backend): http://localhost:9080

Check logs if any service fails:
docker-compose logs -f

⁠Step 6: Stop the Stack
docker-compose down

This stops and removes all containers while keeping volumes intact.


⁠Environment Variables

⁠Core Kong Configuration
VariableDescriptionDefault / Example
KONG_LOG_LEVELKong log levelinfo
KONG_PLUGINSList of plugins to loadbundled,oidc,cookies-to-headers
KONG_DATABASEDatabase typepostgres
KONG_PG_HOSTPostgreSQL hostpostgres_db
KONG_PG_DATABASEPostgreSQL database name${KONG_DB_NAME}
KONG_PG_USERPostgreSQL username${KONG_DB_USER}
KONG_PG_PASSWORDPostgreSQL password${KONG_PW}
KONG_ADMIN_LISTENAdmin API listen address0.0.0.0:8001
KONG_PROXY_LISTENProxy listen address0.0.0.0:8000
⁠Session Storage
VariableDescriptionDefault / Example
KONG_X_SESSION_STORAGESession storage backendredis, shm, cookie, memcached, dshm
KONG_X_SESSION_NAMESession name identifieroidc_session
KONG_X_SESSION_COMPRESSORSession compression algorithmzlib
⁠Redis
VariableDescriptionDefault / Example
KONG_X_SESSION_REDIS_HOSTRedis host for session storageredis
KONG_X_SESSION_REDIS_PASSWORDRedis passwordredis
KONG_X_SESSION_REDIS_DATABASERedis DB index0
KONG_X_SESSION_REDIS_PREFIXRedis key prefixkong_sessions
KONG_X_SESSION_REDIS_POOL_SIZERedis connection pool size30
KONG_X_SESSION_REDIS_POOL_TIMEOUTRedis pool timeout3000
⁠SHM
VariableDescriptionDefault / Example
KONG_X_SESSION_SHM_STOREShared memory store nameoidc_sessions
KONG_X_SESSION_SHM_STORE_SIZESHM store size5m
⁠Database Caching
VariableDescriptionDefault / Example
KONG_DB_UPDATE_FREQUENCYDB cache sync frequency5
KONG_DB_CACHE_TTLCache TTL3600
⁠OIDC Plugin Cache
VariableDescriptionDefault / Example
X_OIDC_CACHE_DISCOVERY_SIZECache size for OIDC discovery128k
X_OIDC_CACHE_JWKS_SIZECache size for JWKS128k
X_OIDC_CACHE_INTROSPECTION_SIZECache size for token introspection128k

For production, it’s recommended to use redis as session storage and configure connection credentials securely.


⁠Improvements

Enhancements and fixes introduced while testing with Keycloak 25.0.6, focusing on OIDC compatibility, logout handling, and session management. A detailed list of the improvements is provided below.

⁠Logout Support
  • Added store_enc_id_token = true in util.lua for logout handling.
  • Changed Revoke Tokens On Logout default to yes.
  • Made Logout Path and Redirect After Logout URI required.
  • Removed redundant Access Token revocation request to avoid Keycloak warnings after Refresh Token revocation.
⁠Session Management Enhancements
  • Dynamic session names: session_name = route_id .. "_" .. plugin_name .. "_session" ensuring service-level session isolation.
  • Configurable session options:
    • idletime = 900 seconds (default 15 minutes)
    • lifetime = 3600 seconds (default 1 hour)
    • renew = 600 seconds
⁠ID Token Enhancements
  • Include signed ID TOKEN in browser login sessions and propagate it to backend service requests.
⁠OpenResty Module Improvements
  • Added OpenResty dependency modules directly into the source tree.
  • Fixed issue where Keycloak discovery failed to parse JSON.
  • Fixed logout issue where redirect_after_logout_with_id_token_hint incorrectly used the logout endpoint as redirect URI.
  • Session cookies are managed per service, not per route.
⁠Build Improvements
  • Added Dockerfile-quick for rapid rebuilds (make build-quick) after source updates.
  • Integration tests now use this quick image via docker-compose.
⁠Session Storage Configuration
  • Added session storage configuration to kong/templates/nginx_kong.lua.
  • OIDC plugin now passes these configurations to OpenResty.

Tag summary

Content type

Image

Digest

sha256:9a4386f31…

Size

265.1 MB

Last updated

6 months ago

docker pull cnapcloud/kong-oidc:3.9.1