This project demonstrates the ability to use Postgres as user storage provider of Keycloak with cloud-native runtime configuration support and separated database architecture.
Important: This project now uses separated databases for better security and maintainability:
- Keycloak Internal Database: Stores realms, clients, tokens, sessions (Port 5433)
- User Storage Database: Contains your external user data for federation (Port 5434)
- β Runtime Configuration: Environment variables read at runtime (no build-time injection)
- β Cloud Ready: Native support for environment-based configuration
- β Docker Hub Compatible: Generic images that work across all environments
- β 12-Factor App Compliant: Follows modern cloud-native principles
- β CI/CD Friendly: "Build once, deploy everywhere" approach
- β
View-Based Access: Uses
v_oidc_usersview for secure, read-only data access - β Read-Only Operations: All write operations (INSERT, UPDATE, DELETE) are disabled
- β
Minimal Permissions: Dedicated
oidc_userwith SELECT-only database permissions - β Column Filtering: Only OIDC-required fields exposed through database view
- β User Validation: Only validated users accessible through OIDC authentication
The following software is required to work build it locally:
- Git 2.2.1 or later
- Docker Engine or Docker Desktop 1.9 or later
- Maven 3.8.5 or later
- Java 17 or later
See the links above for installation instructions on your platform. You can verify the versions are installed and running:
$ git --version
$ curl -V
$ mvn -version
$ docker --version
$ java --version
# Environment variables for secure view-based access
DB_USER=oidc_user
DB_PASSWORD=your_secure_password
DB_AUTHUSER_TABLE=v_oidc_usersBenefits:
- Enhanced security through PostgreSQL view filtering
- Read-only access prevents accidental data modification
- Only validated users are accessible through OIDC
- Minimal database permissions for the application user
Before running the OBP Keycloak Provider, ensure you have the following set up:
The application requires two PostgreSQL databases with properly configured users:
-
Keycloak Internal Database - Run the setup script to create the keycloak user:
# See database/setup-keycloak-user.sql for the complete setup script psql -U postgres -h localhost -f database/setup-keycloak-user.sql -
User Storage Database - OBP-API database schema
- PostgreSQL 12+ running and accessible
- Docker and Docker Compose (for containerized deployment)
- Maven 3.6+ (for building from source)
- Java 11+ (for building from source)
Postgres - database for which we want to store User Federation.
Keycloak - KC container with custom certificate, for use over https. The container is described in Dockerfile.
The project includes GitHub Actions workflows for automated builds and deployments:
- Automated container builds on pushes to main branch
- Multi-architecture support with alternative Dockerfiles
- Dependency updates via Dependabot
- Container signing with Cosign for security
The project includes a comprehensive OBP Theme that transforms Keycloak's login experience to match the Open Bank Project Portal design system:
- Modern Dark Theme: Elegant glassmorphism UI with backdrop blur effects
- OBP Branding: Official logos, colors, and typography (Plus Jakarta Sans)
- Portal Design Consistency: Matches OBP Portal's visual identity and user experience
- OKLCH Color System: Modern color palette with primary (dark blue/gray) and secondary (teal/green) colors
- Responsive Design: Mobile-first approach optimized for all devices
- Accessibility Features: WCAG 2.1 compliance with high contrast support
- Internationalization: Multi-language support with customizable messages
The project supports two deployment modes:
- CI/CD Deployment (always build & replace - automated environments):
# Standard CI/CD deployment $ ./development/run-local-postgres-cicd.sh # Themed CI/CD deployment $ ./development/run-local-postgres-cicd.sh --themed
themes/obp/
βββ theme.properties # Theme configuration
βββ login/ # Login theme files
β βββ login.ftl # Custom login template
β βββ messages/ # Internationalization
β β βββ messages_en.properties # English messages
β βββ resources/ # Static resources
β βββ css/
β β βββ styles.css # Main stylesheet
β βββ img/ # OBP logos and assets
β βββ obp_logo.png
β βββ logo2x-1.png
β βββ favicon.png
After deploying with --themed, activate the OBP theme:
- Access Admin Console: https://localhost:8443/admin
- Go to Realm Settings > Themes
- Set Login Theme to "obp"
- Save changes
Complete Documentation: See the theme structure and activation sections below for comprehensive theming guide, customization options, and development workflow.
Validate your themed deployment setup by running the deployment script:
$ ./development/run-local-postgres-cicd.sh --themedThis script checks all prerequisites, validates theme files, and ensures proper configuration.
The database connection and Keycloak settings are now configured using runtime environment variables instead of build-time configuration. This enables cloud-native deployments with Docker Hub hosted images, and modern CI/CD pipelines.
Complete Documentation:
- docs/CICD_DEPLOYMENT.md - CI/CD deployment guide
- env.sample - Environment configuration reference
-
Copy and configure environment variables:
$ cp env.sample .env $ nano .env # Edit with your actual configuration -
Validate your configuration:
$ ./development/run-local-postgres-cicd.sh
-
Run the application:
# CI/CD deployment (always build & replace) $ ./development/run-local-postgres-cicd.sh --themed -
Test themed deployment (optional):
$ ./development/run-local-postgres-cicd.sh --themed
Note: For local PostgreSQL deployments, the
--validateflag automatically runs validation checks during startup.
-
Copy the example environment file:
$ cp env.sample .env
-
Edit the
.envfile with your actual configuration values:# Keycloak Admin Configuration KEYCLOAK_ADMIN=your-admin KEYCLOAK_ADMIN_PASSWORD=your-admin-password # Keycloak's Internal Database Configuration KC_DB_USERNAME=keycloak KC_DB_PASSWORD=secure-keycloak-password # User Storage Database Configuration DB_NAME=obp_mapped DB_USER=oidc_user DB_PASSWORD=secure-user-storage-password DB_PORT=5432
-
Validate your configuration (recommended):
$ ./development/run-local-postgres-cicd.sh
This script will:
- Validate all required variables are set
- Check database connectivity
- Build and deploy the application
- Provide clear success/failure feedback
Documentation Resources:
- env.sample: Complete environment variable reference with examples and security notes
- docs/CICD_DEPLOYMENT.md: CI/CD-style deployment guide for automated environments
- development/README.md: Development tools and scripts documentation
- Available scripts: Only 3 development scripts are included (see development directory)
| Variable | Default | Description |
|---|---|---|
| Keycloak Admin | ||
KEYCLOAK_ADMIN |
admin |
Keycloak admin username |
KEYCLOAK_ADMIN_PASSWORD |
admin |
Keycloak admin password |
| Keycloak Database | ||
KC_DB_USERNAME |
keycloak |
Keycloak's internal database username |
KC_DB_PASSWORD |
keycloak_changeme |
Keycloak's internal database password |
KC_DB_URL |
jdbc:postgresql://keycloak-postgres:5432/keycloak |
Keycloak's internal database URL |
| User Storage Database | ||
DB_URL |
jdbc:postgresql://user-storage-postgres:5432/obp_mapped |
User storage database URL |
| Port Configuration | ||
KC_DB_PORT |
5433 |
Keycloak database external port |
DB_PORT |
5432 |
User storage database external port |
DB_USER |
oidc_user |
User storage database username |
DB_PASSWORD |
changeme |
User storage database password |
DB_AUTHUSER_TABLE |
v_oidc_users |
View/table name for user authentication data |
| Configuration | ||
KC_HOSTNAME_STRICT |
false |
Hostname strict mode |
HIBERNATE_DDL_AUTO |
validate |
Schema validation mode for user storage |
Docker setup uses Keycloak in container with external PostgreSQL for OBP user federation:
-
Use configuration with external PostgreSQL:
$ cp .env.external-postgres .env $ # Edit .env with your database settings $ docker-compose up -
Required setup:
# External PostgreSQL must have: DB_USER=oidc_user DB_PASSWORD=your_password DB_DRIVER=org.postgresql.Driver DB_DIALECT=org.hibernate.dialect.PostgreSQLDialect OBP_AUTHUSER_PROVIDER=your_provider
The development/ directory contains local development scripts:
- Deployment:
./development/run-local-postgres-cicd.sh- Main deployment script (with --themed option) - Management:
./development/manage-container.sh- Interactive container management
See development/README.md for complete documentation of all development tools.
The project provides two focused deployment approaches:
| Method | Use Case | Build Strategy | Best For |
|---|---|---|---|
CI/CD (run-local-postgres-cicd.sh) |
Automated pipelines | Always rebuild | CI/CD, production deployments |
# Standard deployment without themes
./development/run-local-postgres-cicd.shFeatures:
- Conditional rebuilds for faster iteration
- Comprehensive validation and testing
- Interactive feedback and guidance
- Container management helpers
# Automated, reproducible deployments (always fresh build)
./development/run-local-postgres-cicd.sh --themed
# Standard CI/CD deployment
./development/run-local-postgres-cicd.shFeatures:
- Always builds from scratch (no caching issues)
- JAR checksum-based cache invalidation
- Fail-fast error handling
- Structured pipeline output
- Health checks with timeout
# Manage running containers interactively
./development/manage-container.shπ Detailed Guides:
- docs/CICD_DEPLOYMENT.md - Complete CI/CD documentation
The project supports cloud-native deployment patterns:
-
Runtime Configuration (Recommended - Cloud-Native):
# Build once (no environment variables needed) $ mvn clean package $ docker build -t obp-keycloak-provider . # Deploy anywhere with runtime config $ docker run -e KC_DB_URL="jdbc:postgresql://keycloak-host:5432/keycloak" \ -e KC_DB_USERNAME="keycloak_user" \ -e KC_DB_PASSWORD="keycloak_password" \ -e DB_URL="jdbc:postgresql://user-storage-host:5432/obp_mapped" \ -e DB_USER="obp_user" \ -e DB_PASSWORD="obp_password" \ obp-keycloak-provider
-
Environment Variables Deployment:
$ export DB_URL="jdbc:postgresql://localhost:5432/obp_mapped" $ export DB_USER="obp" $ export DB_PASSWORD="obp_password" $ docker run --env-file .env obp-keycloak-provider
-
Docker Compose (Runtime Config):
$ docker-compose -f docker-compose.runtime.yml up
-
CI/CD builds using GitHub Actions workflows:
- Single generic build for all environments
- Container signing and publishing to Docker Hub
- Multi-architecture support with runtime configuration
When you run the deployment scripts, they start the Keycloak container and follow the logs. When you press Ctrl+C, the script exits but the container continues running in the background.
After pressing Ctrl+C:
- The container remains accessible at http://localhost:8000 and https://localhost:8443
- Use
./development/manage-container.shfor an interactive container management menu - Or use these direct commands:
- View logs:
docker logs -f obp-keycloak - Stop container:
docker stop obp-keycloak - Remove container:
docker rm obp-keycloak - Stop and remove:
docker stop obp-keycloak && docker rm obp-keycloak
- View logs:
Warning: I recommend using your own database, cause not all systems will have a database at
localhostavailable to thedockercontainer.
For PostgreSQL setup, please refer to the main deployment scripts or set up your own database instance.
The system now uses two separate databases:
- Keycloak's Internal Database: Stores realms, clients, tokens, and Keycloak's own data (accessible on localhost:5433)
- User Storage Database: Contains your external user data that Keycloak federates (accessible on localhost:5434)
Important: Due to recent fixes, the user storage database now runs on port 5434 instead of 5432 to avoid conflicts with system PostgreSQL installations.
For the User Storage Database setup, use the official OBP-API SQL scripts:
π IMPORTANT: Use the official OBP-API repository scripts as the source of truth. This avoids code duplication and ensures you have the latest, maintained SQL scripts.
Official Setup Process:
-
Clone/Download OBP-API Repository:
- Repository: https://github.com/OpenBankProject/OBP-API
- Navigate to:
obp-api/src/main/scripts/sql/OIDC/
-
Run Official Setup Script:
cd obp-api/src/main/scripts/sql/OIDC/ psql -d your_obp_database \i give_read_access_to_users.sql
What the Official Scripts Do:
- β
Create
v_oidc_usersview joiningauthuserandresourceusertables - β
Create
oidc_userrole with read-only permissions - β Grant appropriate SELECT permissions on the view
- β Include security settings and error handling
- β Only expose validated users for security
Keycloak Provider Features:
- β
User authentication and login via the
v_oidc_usersview - β User profile viewing (read-only access)
- β Password validation
- β Secure federation with existing OBP user data
- π΄ User creation/updates/deletion (read-only by design)
Why Use Official Scripts:
- Always up-to-date with OBP-API changes
- Maintained by the OBP development team
- Proper security configurations included
- Avoids documentation drift and code duplication
For detailed setup instructions, see the database/README.md file and the official OBP-API repository.
KC is deployed in a custom container.
To deploy the KC container, I created a Dockerfile file in which :
- I create a certificate for
httpsaccess - I add a provider
obp-keycloak-provider
Build once, deploy everywhere with runtime configuration:
# Build the provider (no environment variables needed)
$ mvn clean package
# Run with CI/CD deployment
$ ./development/run-local-postgres-cicd.sh --themedFor compatibility, you can still use the legacy build script:
$ ./development/run-local-postgres-cicd.shNote: The legacy approach uses build-time configuration which is not recommended for production deployments. Use the cloud-native approach for Docker Hub deployments.
After launching, go to https://localhost:8443 in your browser. To log in to KC, use admin credentials :
user : admin
pass : adminClick the User federation tab .
The provider obp-keycloak-provider is in list of providers.
# Pull generic image
docker pull your-org/obp-keycloak-provider:latest
# Run with environment-specific configuration
docker run -e KC_DB_URL="jdbc:postgresql://keycloak-prod-db:5432/keycloak" \
-e KC_DB_USERNAME="keycloak_prod_user" \
-e KC_DB_PASSWORD="secure_keycloak_password" \
-e DB_URL="jdbc:postgresql://user-storage-prod-db:5432/obp" \
-e DB_USER="obp_prod_user" \
-e DB_PASSWORD="secure_user_storage_password" \
your-org/obp-keycloak-provider:latest# Deploy and validate the setup
./development/run-local-postgres-cicd.shThe following critical issues have been resolved:
- Fixed JDBC URL Configuration: Corrected malformed
KC_DB_URLdefault value indocker-compose.runtime.yml - Resolved Port Conflicts: Changed user-storage-postgres to port 5434 to avoid conflicts with system PostgreSQL
- Fixed SQL Syntax Error: Removed incomplete SQL statement in database initialization script
- Updated Environment Variables: All configuration now properly supports the separated database architecture
- Environment Configuration - Environment variable reference
- CI/CD Deployment - Automated deployment guide for pipelines
- Docker Compose - Runtime configuration example
