Keycloak readOnlyRootFilesystem Implementation
Overview
This document describes the implementation ofreadOnlyRootFilesystem: true for Keycloak pods using a pre-optimized GHCR image. This security hardening prevents filesystem modifications at runtime, reducing attack surface.
Current Status
Date: 2025-12-08 Status: ✅ IMPLEMENTED -readOnlyRootFilesystem: true enabled
Image: ghcr.io/vishnu2kmohan/keycloak-optimized:26.4.2
File: deployments/base/keycloak-deployment.yaml
Solution Summary
Approach: Pre-Built Optimized Keycloak Image
The solution uses a custom Keycloak image built via GitHub Actions that pre-compiles Quarkus at build time, eliminating the need for JIT compilation at runtime. Key Benefits:- ✅
readOnlyRootFilesystem: true- Full security hardening - ✅ Faster container startup (no runtime augmentation)
- ✅ Matches docker-compose.test.yml for dev/prod parity
- ✅ Reduced attack surface
Architecture
Implementation Details
Dockerfile (docker/Dockerfile.keycloak)
Kubernetes Deployment (deployments/base/keycloak-deployment.yaml)
Health Check Paths
WithKC_HTTP_RELATIVE_PATH=/authn, health checks use:
| Probe | Path | Purpose |
|---|---|---|
| startupProbe | /authn/health/started | Container initialization |
| livenessProbe | /authn/health/live | Process alive check |
| readinessProbe | /authn/health/ready | Ready to serve traffic |
Security Controls
Pod Security Context
Container Security Context
EmptyDir Volume Isolation
Writable paths are isolated to ephemeral emptyDir volumes:/tmp- Temporary files/var/tmp- Additional temporary storage/opt/keycloak/data/tmp- Keycloak cache directory/opt/keycloak/data- Keycloak work directory/opt/keycloak/providers- Custom provider JARs/opt/keycloak/themes- Custom themes
/opt/keycloak/lib - this overwrites Quarkus runtime JARs and causes ClassNotFoundException.
GitHub Actions Workflow
Image is built automatically via.github/workflows/build-keycloak-image.yaml:
Verification
Test Read-Only Filesystem
Test Health Endpoints
Test Admin Console
Access via Traefik gateway:Troubleshooting
Issue: Container CrashLoopBackOff
Symptoms: Pod fails to start with Quarkus errors Cause: Using stock Keycloak image without--optimized flag
Solution: Ensure using GHCR optimized image:
Issue: ClassNotFoundException
Symptoms: Java class loading errors at startup Cause: emptyDir mounted at/opt/keycloak/lib overwrites JAR files
Solution: Remove /opt/keycloak/lib volume mount. Only mount:
/opt/keycloak/data/opt/keycloak/providers/opt/keycloak/themes
Issue: Health Check Failures
Symptoms: Pods never become ready Cause: Wrong health check paths (missing/authn prefix)
Solution: Update probe paths:
References
- Keycloak Server Installation
- Keycloak Containers
- Quarkus Native Images
- Kubernetes Pod Security Standards
Related Files
docker/Dockerfile.keycloak- Optimized image build.github/workflows/build-keycloak-image.yaml- CI/CD pipelinedeployments/base/keycloak-deployment.yaml- Base deploymentdeployments/base/.trivyignore- Security scan suppressionsdocker-compose.test.yml- Test environment parity
Last Updated: 2025-12-08 Status: ✅ Implemented Owner: DevOps/Security Team Priority: Complete (Security Hardening)