Skip to main content

Keycloak readOnlyRootFilesystem Implementation

Overview

This document describes the implementation of readOnlyRootFilesystem: 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

With KC_HTTP_RELATIVE_PATH=/authn, health checks use:

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
IMPORTANT: Do NOT mount emptyDir at /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

  • docker/Dockerfile.keycloak - Optimized image build
  • .github/workflows/build-keycloak-image.yaml - CI/CD pipeline
  • deployments/base/keycloak-deployment.yaml - Base deployment
  • deployments/base/.trivyignore - Security scan suppressions
  • docker-compose.test.yml - Test environment parity

Last Updated: 2025-12-08 Status: ✅ Implemented Owner: DevOps/Security Team Priority: Complete (Security Hardening)