Setup Authentication to Keycloak

I really struggle a lot to get this working. All the guides on the internet are referring to very old versions. I want to add multiple users in keycloak. They can login to keycloak with username/password or with their google account. In keycloak I want to specify which user can access which resources.

This is my docker compose file so far:

services:
  traefik:
    image: traefik  # Specifies the Docker image for Traefik, a reverse proxy and load balancer.
    container_name: traefik  # Names the container as "traefik".
    command:
      - "--log.level=DEBUG"  # Sets the logging level to DEBUG for detailed logs.
      - "--entrypoints.web.address=:80"  # Defines an entry point for HTTP traffic on port 80.
      - "--entrypoints.websecure.address=:443"  # Defines an entry point for HTTPS traffic on port 443.
      - "--providers.docker=true"  # Enables Traefik to use Docker as a provider for configuration.
      - "--providers.docker.exposedbydefault=false"  # Ensures services are not exposed by default unless explicitly labeled.
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"  # Enables TLS challenge for Let's Encrypt certificates.
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"  # Specifies the email address for Let's Encrypt notifications.
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"  # Sets the storage location for Let's Encrypt certificate data.
      - "--api.insecure=true"  # Enables the Traefik API on an insecure endpoint (not recommended for production).
    ports:
      - "80:80"  # Maps port 80 on the host to port 80 in the container for HTTP traffic.
      - "443:443"  # Maps port 443 on the host to port 443 in the container for HTTPS traffic.
      - "8080:8080"  # Maps port 8080 on the host to port 8080 in the container for the Traefik dashboard/API.
    volumes:
      - /mnt/docker/remotework/traefik/letsencrypt:/letsencrypt  # Mounts the Let's Encrypt storage directory on the host into the container.
      - /var/run/docker.sock:/var/run/docker.sock:ro  # Mounts the Docker socket as read-only to allow Traefik to interact with Docker.
    labels:
      traefik.http.middlewares.keycloak.forwardauth.address: "http://keycloak:8080/realms/master/protocol/openid-connect/userinfo
      traefik.http.middlewares.keycloak.forwardauth.trustForwardHeader: true  # Allows Traefik to trust the Forwarded headers.
      traefik.http.middlewares.keycloak.forwardauth.authResponseHeaders: Authorization  # Specifies the headers to pass in the response after authentication.
      traefik.enable: true  # Explicitly enables Traefik to handle this service.

  whoami1:
    image: traefik/whoami  # Uses a simple whoami service to verify routing.
    container_name: whoami1  # Names the container as "whoami1".
    labels:
      traefik.enable: true  # Enables Traefik to handle this service.
      traefik.http.routers.whoami1.rule: Host(`whoami1.example.com`)  # Routes requests with this hostname to the service.
      traefik.http.routers.whoami1.entrypoints: websecure  # Associates this router with the secure HTTPS entry point.
      traefik.http.routers.whoami1.tls: true  # Enables TLS for this router.
      traefik.http.routers.whoami1.tls.certresolver: letsencrypt  # Specifies Let's Encrypt as the certificate resolver for this service.
      traefik.http.routers.whoami1.middlewares: keycloak  # Uses the Keycloak ForwardAuth middleware for this service.
      traefik.http.services.whoami1.loadbalancer.server.port: 80  # Sets the internal port of the service to 80.

  whoami2:
    image: traefik/whoami  # Uses a simple whoami service to verify routing.
    container_name: whoami2  # Names the container as "whoami2".
    labels:
      traefik.enable: true  # Enables Traefik to handle this service.
      traefik.http.routers.whoami2.rule: Host(`whoami2.example.com`)  # Routes requests with this hostname to the service.
      traefik.http.routers.whoami2.entrypoints: websecure  # Associates this router with the secure HTTPS entry point.
      traefik.http.routers.whoami2.tls: true  # Enables TLS for this router.
      traefik.http.routers.whoami2.tls.certresolver: letsencrypt  # Specifies Let's Encrypt as the certificate resolver for this service.
      traefik.http.routers.whoami2.middlewares: keycloak  # Uses the Keycloak ForwardAuth middleware for this service.
      traefik.http.services.whoami2.loadbalancer.server.port: 80  # Sets the internal port of the service to 80.

  keycloak:
    image: quay.io/keycloak/keycloak  # Uses the official Keycloak image from Quay.io.
    container_name: keycloak  # Names the container as "keycloak".
    environment:
      KC_DB: dev-file  # Sets the database mode to dev-file for non-production use.
      KC_HOSTNAME: auth.example.com  # Specifies the hostname for Keycloak.
      KC_LOG: console  # Configures logging to the console.
      KC_PROXY_HEADERS: xforwarded # Tells Keycloak where to find the real IP of the HTTP-Client provided by reverse proxy.
      KC_HOSTNAME_STRICT: false  # Disables strict hostname verification.
      KC_HTTP_ENABLED: true  # Enables HTTP for Keycloak.
      PROXY_ADDRESS_FORWARDING: true  # Allows Keycloak to trust the Forwarded headers from the proxy.
    command:
      - start
    labels:
      traefik.enable: true  # Enables Traefik to handle this service.
      traefik.http.routers.keycloak.rule: Host(`auth.example.com`)  # Routes requests with this hostname to the Keycloak service.
      traefik.http.services.keycloak.loadbalancer.server.port: 8080  # Sets the internal port of the Keycloak service to 8080.
      traefik.http.routers.keycloak.entrypoints: websecure  # Associates this router with the secure HTTPS entry point.
      traefik.http.routers.keycloak.tls: true  # Enables TLS for this router.
      traefik.http.routers.keycloak.tls.certresolver: letsencrypt  # Specifies Let's Encrypt as the certificate resolver for Keycloak.
    volumes:
      - /mnt/docker/remotework/keycloak/data:/opt/keycloak/data  # Mounts the data directory for Keycloak from the host to the container.
    tmpfs:
      - /opt/keycloak/data/tmp:mode=777,size=8G  # Creates a temporary file system in memory for Keycloak's temporary data.
    ports:
      - 8088:8080  # Maps port 8088 on the host to port 8080 in the container for Keycloak.

I can't believe that this small task is really so difficult. Some guides say I need a client to be configured in Keycloak, some other guides say it is not necessary. I have really headegg because of this. There is not one single working example.

Well, I would enable Traefik debug log, it hopefully tells you what forwardauth is doing.

And according to keycloak doc you need a realm and a clientid.

Update: Internet search only shows solutions with a forwardauth proxy, so it seems Keycloak does not directly support Traefik forwardauth (doc).

Zitadel also does not support forward auth (without a proxy), but Authentik does.

But the traefik docs say nothing about where to specify client_id and client_secret I only found this one label specifying the url of keycloak.

Traefik ForwardAuth and Keycloak seem not to be compatible. You need an additional proxy service (maybe bad naming here, not Traefik) to translate the two API.

okay let's keep it more simple: Which authentication methods is the integrated middleware inside traefik compatible? I mean I don't see any documentation what settings this middleware expects (besides the address) and what it is expecting as a response. Without this knowledge I cannot find out if keycloak is compatible and if not, what I can use instead.

For an example can the forwardauth middleware inside traefik directly authenticate to google via oauth?

Check the Traefik ForwardAuth docs:

The ForwardAuth middleware delegates authentication to an external service. If the service answers with a 2XX code, access is granted, and the original request is performed. Otherwise, the response from the authentication server is returned.

If you want oauth, you need a translator/proxy, search for "forwardauth oauth".