Kitezh is an OAuth2 and OpenID Connect identity platform built with Spring Boot 4.1, Java 25, and Spring Security 7. The published Docker image is a statically linked GraalVM native executable available for linux/amd64 and linux/arm64.
The image includes the authorization server, localized login and consent pages, the Administration Console, and the Account Console. It listens on port 9090 by default.
docker pull suayb/kitezh:latest
Official links:
The latest image is a multi-architecture manifest. Docker selects the matching linux/amd64 or linux/arm64 image for the host automatically.
The latest tag is published to Docker Hub only by validated v* releases after the native builds pass. Each release also publishes immutable architecture tags such as 0.1.0-amd64 and 0.1.0-arm64, plus the versioned multi-architecture tag 0.1.0. The image is suitable for local evaluation and deployments; configure an external PostgreSQL database before using it outside local testing.
From a Kitezh checkout, the prebuilt image can be started with PostgreSQL and the separate Liquibase migration container:
docker compose -f src/main/docker/app.yml up -d
Kitezh is available at http://localhost:9090. Check readiness with:
curl http://localhost:9090/actuator/health/readiness
Stop the stack with:
docker compose -f src/main/docker/app.yml down
The Compose fixture is for development. PostgreSQL data is ephemeral unless the commented volume in src/main/docker/postgresql.yml is enabled.
The published image is built with the prod profile and requires PostgreSQL settings:
docker run --rm -p 9090:9090 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/kitezh \
-e SPRING_DATASOURCE_USERNAME=appuser \
-e SPRING_DATASOURCE_PASSWORD=appuser \
-e APP_AUTHORIZATIONSERVER_ISSUER=http://localhost:9090 \
suayb/kitezh:latest
Kitezh runs Liquibase migrations on startup. Set SPRING_LIQUIBASE_DROP_FIRST=true only for an intentionally disposable demo database because it removes existing objects before applying the changelog.
Open the following URLs after the application starts:
| Console | URL | Seeded users | Scope |
|---|---|---|---|
| Administration | http://localhost:9090/admin | admin/admin | admin-api plus the required administrative authority |
| Account | http://localhost:9090/account | admin/admin, user/user, user2/user2, user3/user3, user4/user4, user5/user5, user6/user6 | account-api |
Both consoles use Authorization Code + PKCE, refresh-token rotation, and OIDC logout. The issuer and redirect URIs must use the same public address when the image is exposed through another hostname.
The public demo is available at kitezh.onrender.com.
Fetch provider metadata and public signing keys:
curl http://localhost:9090/.well-known/openid-configuration
curl http://localhost:9090/.well-known/oauth-authorization-server
curl http://localhost:9090/oauth2/jwks
Request a client-credentials token with the seeded client:
curl -u demo-client:demo-secret \
-H 'Accept-Language: en' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d grant_type=client_credentials \
-d scope=openid \
http://localhost:9090/oauth2/token
Inspect or revoke a token:
TOKEN=$(curl -s -u demo-client:demo-secret \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d grant_type=client_credentials \
-d scope=openid \
http://localhost:9090/oauth2/token | jq -r '.access_token')
curl -u demo-client:demo-secret \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d token="${TOKEN}" \
http://localhost:9090/oauth2/introspect
curl -u demo-client:demo-secret \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d token="${TOKEN}" \
-d token_type_hint=access_token \
http://localhost:9090/oauth2/revoke
The seeded ciba-client supports the CIBA grant with poll delivery. The seeded demo-client also includes token exchange and CIBA grant types.
The most relevant environment variables are:
| Variable | Default | Purpose |
|---|---|---|
SPRING_PROFILES_ACTIVE | prod in the published image | Select the Spring profile |
SERVER_PORT | 9090 | HTTP listen port; Render sets this to 10000 |
SPRING_DATASOURCE_URL | jdbc:postgresql://localhost:5432/kitezh in prod | PostgreSQL JDBC URL |
SPRING_DATASOURCE_USERNAME | none in prod | Database username |
SPRING_DATASOURCE_PASSWORD | none in prod | Database password |
SPRING_LIQUIBASE_ENABLED | true | Enable Liquibase migrations |
SPRING_LIQUIBASE_DROP_FIRST | false | Drop database objects before migration; use only for disposable demos |
APP_AUTHORIZATIONSERVER_ISSUER | https://kitezh.local | Public OAuth2/OIDC issuer |
APP_DPOP_NONCE_REQUIRED | false | Require DPoP nonce validation |
MANAGEMENT_OPENTELEMETRY_ENABLED | false | Enable OpenTelemetry resource/export configuration |
MANAGEMENT_TRACING_EXPORT_ENABLED | false | Enable trace export |
MANAGEMENT_TRACING_EXPORT_OTLP_ENABLED | false | Enable OTLP trace export |
MANAGEMENT_LOGGING_EXPORT_OTLP_ENABLED | false | Enable OTLP log export |
MANAGEMENT_OTLP_METRICS_EXPORT_ENABLED | false | Enable OTLP metric export |
MANAGEMENT_OPENTELEMETRY_TRACING_EXPORT_OTLP_ENDPOINT | empty | OTLP trace endpoint |
MANAGEMENT_OPENTELEMETRY_LOGGING_EXPORT_OTLP_ENDPOINT | empty | OTLP log endpoint |
MANAGEMENT_OTLP_METRICS_EXPORT_URL | empty | OTLP metric endpoint |
MANAGEMENT_TRACING_SAMPLING_PROBABILITY | 1.0 | Trace sampling probability |
Keep OTLP authorization headers and database credentials in deployment secrets. Do not commit them to the repository or bake them into the image.
Social providers are configured from Administration → Settings → Login. The provider enablement, Client ID, and Client Secret are stored in the database; secrets are encrypted before persistence. Keep SOCIAL_LOGIN_ENCRYPTION_KEY stable across restarts and deployments. Provider credentials are intentionally not read from application YAML or environment variables.
The callback URI is https://<public-host>/login/oauth2/code/{registrationId}. Register the exact callback URI with each provider.
GET /actuator/health
GET /actuator/health/liveness
GET /actuator/health/readiness
GET /actuator/metrics
GET /actuator/prometheus
Kitezh exposes liveness and readiness probes with the database included in readiness. Management endpoints should remain private to the cluster or deployment platform.
The Render Blueprint in render.yaml deploys the same Docker Hub image with:
docker.io/suayb/kitezh:latest/actuator/health/readiness10000 through SERVER_PORTThe GitHub Actions workflow builds amd64 and arm64 native images with GraalVM, publishes versioned architecture-specific tags through Jib, combines them into the latest and versioned multi-arch manifests for v* tags, and optionally triggers the matching Render Deploy Hook.
Build the native executable:
./mvnw -Pprod,native -DskipTests native:compile
Build a local native image with Jib:
./mvnw -Pprod,native -DskipTests jib:dockerBuild \
-Djib-maven-plugin.architecture=amd64 \
-Djib.to.image=kitezh:latest
The CI publish command uses the Docker Hub repository and tag below:
docker.io/suayb/kitezh:latest
latest tag selects the linux/amd64 or linux/arm64 image automatically; versioned architecture-specific tags are available as <version>-amd64 and <version>-arm64.prod,native image.Content type
Image
Digest
sha256:b0f69b409…
Size
54.3 MB
Last updated
about 14 hours ago
docker pull suayb/kitezh