Keycloak est la solution open source de référence pour la gestion des identités et des accès (IAM) : authentification unique (SSO), OpenID Connect, OAuth 2.0, SAML 2.0, fédération d’identités, MFA, gestion fine des rôles… Dans cet article, on déroule une installation complète et durable de Keycloak sur une Debian 13 (Trixie) fraîche, avec une base PostgreSQL, un reverse proxy Nginx qui termine le TLS via Let’s Encrypt, et un service systemd pour un démarrage automatique et robuste.

La version cible ici est Keycloak 26.7.0, certifiée avec OpenJDK 21 — qui est justement la version d’OpenJDK fournie en standard par Debian 13. Adaptez le numéro de version si une release plus récente est disponible.

Architecture cible

On vise une installation « bare metal » (pas de conteneur) où chaque composant a un rôle clair :

  • Nginx écoute sur les ports 80/443, termine le TLS et relaie les requêtes vers Keycloak.
  • Keycloak tourne en local sur 127.0.0.1:8080 (HTTP), jamais exposé directement à Internet.
  • PostgreSQL stocke realms, utilisateurs, clients et sessions.
  • systemd supervise le processus Keycloak (démarrage auto, redémarrage sur échec).

Prérequis : un serveur Debian 13 à jour, un accès root (ou sudo), un nom de domaine pointant vers le serveur (ici keycloak.example.com) et les ports 80/443 ouverts. Comptez au minimum 2 Go de RAM.

Étape 1 — Préparer le système

On met le système à jour et on installe quelques utilitaires de base :

apt update && apt upgrade -y
apt install -y curl wget gnupg tar

On crée ensuite un utilisateur système dédié, sans shell de connexion, qui fera tourner Keycloak (principe de moindre privilège) :

groupadd -r keycloak
useradd -r -g keycloak -d /opt/keycloak -s /usr/sbin/nologin keycloak

Étape 2 — Installer Java (OpenJDK 21)

Keycloak 26 est certifié avec OpenJDK 17 et 21. Debian 13 fournit directement OpenJDK 21 :

apt install -y openjdk-21-jdk
java -version

La commande java -version doit afficher une version 21.x. Si plusieurs JDK sont installés, sélectionnez le bon avec update-alternatives --config java.

Étape 3 — Installer et configurer PostgreSQL

On installe PostgreSQL et on l’active au démarrage :

apt install -y postgresql postgresql-contrib
systemctl enable --now postgresql

On crée ensuite la base et l’utilisateur dédiés à Keycloak. Remplacez le mot de passe par une valeur forte :

sudo -u postgres psql -c "CREATE DATABASE keycloak;"
sudo -u postgres psql -c "CREATE USER keycloak WITH ENCRYPTED PASSWORD 'ChangeMe_DbStrongPassword';"
sudo -u postgres psql -c "ALTER DATABASE keycloak OWNER TO keycloak;"
sudo -u postgres psql -d keycloak -c "GRANT ALL ON SCHEMA public TO keycloak;"

Le GRANT ALL ON SCHEMA public est indispensable depuis PostgreSQL 15 : sans lui, Keycloak ne pourra pas créer ses tables lors de la première migration Liquibase.

Étape 4 — Télécharger et installer Keycloak

On récupère l’archive officielle depuis GitHub, on l’extrait dans /opt et on ajuste les droits :

cd /opt
curl -LO https://github.com/keycloak/keycloak/releases/download/26.7.0/keycloak-26.7.0.tar.gz
tar xzf keycloak-26.7.0.tar.gz
mv keycloak-26.7.0 keycloak
chown -R keycloak:keycloak /opt/keycloak
rm -f keycloak-26.7.0.tar.gz

L’arborescence de Keycloak se trouve désormais dans /opt/keycloak : bin/ (scripts), conf/ (configuration), data/ (données locales), providers/ (extensions).

Étape 5 — Configurer Keycloak

Toute la configuration « statique » se centralise dans le fichier /opt/keycloak/conf/keycloak.conf. Éditez-le :

nano /opt/keycloak/conf/keycloak.conf

Et renseignez le contenu suivant (adaptez le domaine et le mot de passe DB) :

# --- Base de donnees ---
db=postgres
db-username=keycloak
db-password=ChangeMe_DbStrongPassword
db-url=jdbc:postgresql://localhost:5432/keycloak

# --- Hostname public (vu par les navigateurs) ---
hostname=https://keycloak.example.com

# --- Keycloak derriere un reverse proxy qui termine le TLS ---
proxy-headers=xforwarded
http-enabled=true
http-host=127.0.0.1
http-port=8080

# --- Cache (mono-noeud) ---
cache=local

# --- Health & metrics (port de management 9000) ---
health-enabled=true
metrics-enabled=true

Points clés de cette configuration :

  • hostname doit correspondre exactement à l’URL publique servie par Nginx (sinon boucles de redirection et liens cassés).
  • proxy-headers=xforwarded indique à Keycloak de faire confiance aux entêtes X-Forwarded-* envoyées par Nginx.
  • http-host=127.0.0.1 lie Keycloak au loopback : il n’est joignable que par le reverse proxy local.

Étape 6 — Construire l’image optimisée

Keycloak recommande une phase de build qui pré-compile la configuration (fournisseur de base de données, fonctionnalités activées) pour un démarrage rapide en production :

cd /opt/keycloak
sudo -u keycloak bin/kc.sh build

Une fois le build terminé, on démarrera Keycloak avec l’option --optimized pour qu’il réutilise cette configuration compilée sans la recalculer.

Étape 7 — Reverse proxy Nginx + HTTPS Let’s Encrypt

On installe Nginx et Certbot :

apt install -y nginx certbot python3-certbot-nginx

On crée le fichier de site /etc/nginx/sites-available/keycloak.conf :

nano /etc/nginx/sites-available/keycloak.conf

Avec ce contenu (bloc HTTP simple, Certbot ajoutera automatiquement le bloc HTTPS) :

server {
    listen 80;
    server_name keycloak.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;
        proxy_set_header X-Forwarded-Port  443;
    }
}

On active le site, on teste la configuration et on recharge Nginx :

ln -s /etc/nginx/sites-available/keycloak.conf /etc/nginx/sites-enabled/keycloak.conf
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx

On obtient enfin le certificat TLS : Certbot détecte le bloc server, ajoute la configuration SSL et met en place la redirection HTTP vers HTTPS :

certbot --nginx -d keycloak.example.com --redirect --agree-tos -m admin@example.com

Étape 8 — Service systemd

Pour que Keycloak démarre automatiquement et redémarre en cas de plantage, on crée une unité systemd /etc/systemd/system/keycloak.service :

nano /etc/systemd/system/keycloak.service

Avec le contenu suivant. Les deux variables KC_BOOTSTRAP_ADMIN_* servent uniquement à créer un compte administrateur temporaire au tout premier démarrage — on les retirera juste après :

[Unit]
Description=Keycloak Identity and Access Management
Requires=network-online.target postgresql.service
After=network-online.target postgresql.service

[Service]
User=keycloak
Group=keycloak
WorkingDirectory=/opt/keycloak
# Admin temporaire (a supprimer apres le premier login)
Environment=KC_BOOTSTRAP_ADMIN_USERNAME=admin
Environment=KC_BOOTSTRAP_ADMIN_PASSWORD=ChangeMe_AdminPassword
ExecStart=/opt/keycloak/bin/kc.sh start --optimized
Restart=on-failure
RestartSec=10
LimitNOFILE=102642
TimeoutStartSec=600

[Install]
WantedBy=multi-user.target

On recharge systemd, on active et on démarre le service, puis on suit les logs :

systemctl daemon-reload
systemctl enable --now keycloak
systemctl status keycloak
journalctl -u keycloak -f

Au premier démarrage, Keycloak exécute la migration de schéma sur PostgreSQL (peut prendre quelques dizaines de secondes) puis affiche Keycloak ... started dans les logs.

Étape 9 — Premier login et compte admin définitif

Ouvrez https://keycloak.example.com/admin dans un navigateur et connectez-vous avec le compte temporaire (admin / ChangeMe_AdminPassword).

Ce compte issu de KC_BOOTSTRAP_ADMIN_* est temporaire : créez immédiatement un vrai administrateur dans le realm master (menu Users puis Add user, en lui affectant le rôle admin), puis retirez les deux lignes Environment=KC_BOOTSTRAP_ADMIN_* de l’unité systemd et rechargez :

nano /etc/systemd/system/keycloak.service
systemctl daemon-reload
systemctl restart keycloak

Étape 10 — Vérification

On contrôle que tout répond correctement :

systemctl is-active keycloak
curl -I https://keycloak.example.com/
curl -s http://127.0.0.1:9000/health/ready

La sonde de santé /health/ready (exposée sur le port de management 9000, en local) doit renvoyer un statut UP. La commande curl -I sur l’URL publique doit retourner un code HTTP 200 ou une redirection vers la page de login.

Aller plus loin (1) — Déclarer un premier client OIDC

Règle d’or : ne touchez jamais au realm master (réservé à l’administration de Keycloak). Créez toujours un realm dédié à vos applications. On crée ici un realm mon-app puis un client OpenID Connect confidentiel.

En ligne de commande, on s’authentifie au CLI admin et on crée le realm :

cd /opt/keycloak
sudo -u keycloak bin/kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
sudo -u keycloak bin/kcadm.sh create realms -s realm=mon-app -s enabled=true

La création du client se fait ensuite le plus simplement depuis la console d’administration (Clients puis Create client) :

  1. Client type : OpenID Connect ; Client ID : mon-app-web.
  2. Activez Client authentication (client confidentiel) et le Standard flow (Authorization Code).
  3. Valid redirect URIs : https://app.example.com/*
  4. Web origins : https://app.example.com
  5. Dans l’onglet Credentials, récupérez le Client secret à reporter dans la configuration de votre application.

Votre application n’a plus qu’à consommer les endpoints OIDC exposés par le realm, découvrables via le document well-known :

curl -s https://keycloak.example.com/realms/mon-app/.well-known/openid-configuration

On y trouve notamment authorization_endpoint, token_endpoint, userinfo_endpoint et jwks_uri à renseigner (ou à laisser découvrir automatiquement) côté client.

Aller plus loin (2) — Fédérer un annuaire LDAP / Active Directory

Plutôt que de recréer vos comptes dans Keycloak, vous pouvez fédérer un annuaire existant (OpenLDAP, Active Directory) : les utilisateurs s’authentifient avec leurs identifiants d’entreprise, Keycloak restant le point d’entrée SSO.

Avant de configurer, validez la connectivité vers l’annuaire depuis le serveur (le paquet ldap-utils fournit ldapsearch) :

apt install -y ldap-utils
ldapsearch -x -H ldaps://ldap.example.com:636 -D "cn=keycloak,ou=services,dc=example,dc=com" -W -b "dc=example,dc=com" "(objectClass=person)" cn

Dans la console d’administration, positionnez-vous sur le realm mon-app, puis User federation et Add LDAP provider. Les champs essentiels :

  • Vendor : Active Directory ou Other (OpenLDAP).
  • Connection URL : ldaps://ldap.example.com:636 (privilégiez LDAPS ou STARTTLS).
  • Bind type : simple, avec un Bind DN de service (ex. cn=keycloak,ou=services,dc=example,dc=com) et son mot de passe.
  • Users DN : la base de recherche des comptes, ex. ou=users,dc=example,dc=com.
  • Username LDAP attribute : uid (OpenLDAP) ou sAMAccountName (Active Directory).
  • Edit mode : READ_ONLY pour ne jamais modifier l’annuaire source, ou WRITABLE pour propager les changements.

Cliquez sur Test connection puis Test authentication, sauvegardez, et lancez un Sync all users. Les utilisateurs de l’annuaire apparaissent alors dans Users et peuvent se connecter au SSO. Ajoutez au besoin des mappers pour rapatrier groupes et attributs (email, nom, rôles).

Points de vigilance

  • Pare-feu : n’exposez QUE les ports 80 et 443. Les ports 8080 (HTTP interne) et 9000 (management/health) doivent rester sur 127.0.0.1.
  • hostname : toute incohérence entre hostname et l’URL réelle provoque des erreurs « Invalid redirect » ou des assets non chargés.
  • Java : restez sur OpenJDK 21 (certifié). Évitez les versions plus récentes non supportées en production.
  • Sauvegardes : sauvegardez régulièrement la base PostgreSQL (pg_dump) — c’est là que vivent tous vos realms et utilisateurs.
  • Mots de passe : changez impérativement ChangeMe_DbStrongPassword et ChangeMe_AdminPassword par des secrets robustes.
  • Cluster : pour de la haute disponibilité multi-nœuds, remplacez cache=local par cache=ispn et configurez la découverte Infinispan.

Récapitulatif des commandes

# Systeme + utilisateur dedie
apt update && apt upgrade -y
apt install -y curl wget gnupg tar openjdk-21-jdk
groupadd -r keycloak
useradd -r -g keycloak -d /opt/keycloak -s /usr/sbin/nologin keycloak

# PostgreSQL
apt install -y postgresql postgresql-contrib
systemctl enable --now postgresql
sudo -u postgres psql -c "CREATE DATABASE keycloak;"
sudo -u postgres psql -c "CREATE USER keycloak WITH ENCRYPTED PASSWORD 'ChangeMe_DbStrongPassword';"
sudo -u postgres psql -c "ALTER DATABASE keycloak OWNER TO keycloak;"
sudo -u postgres psql -d keycloak -c "GRANT ALL ON SCHEMA public TO keycloak;"

# Keycloak
cd /opt
curl -LO https://github.com/keycloak/keycloak/releases/download/26.7.0/keycloak-26.7.0.tar.gz
tar xzf keycloak-26.7.0.tar.gz && mv keycloak-26.7.0 keycloak
chown -R keycloak:keycloak /opt/keycloak
sudo -u keycloak /opt/keycloak/bin/kc.sh build

# Reverse proxy + TLS
apt install -y nginx certbot python3-certbot-nginx
nginx -t && systemctl reload nginx
certbot --nginx -d keycloak.example.com --redirect --agree-tos -m admin@example.com

# Service
systemctl daemon-reload
systemctl enable --now keycloak

Voir aussi

Pour alimenter Keycloak avec un annuaire d’entreprise et fédérer vos comptes, consultez l’article Mettre en place OpenLDAP sur Debian 13 : administration en ligne de commande (et WebUI en option).

Conclusion

Vous disposez maintenant d’une instance Keycloak 26 propre, sécurisée derrière Nginx en HTTPS, adossée à PostgreSQL et supervisée par systemd sur Debian 13. C’est une base solide pour brancher vos applications en OpenID Connect ou SAML, activer le MFA, créer des realms dédiés par projet, ou fédérer un annuaire LDAP/Active Directory. Prochaine étape naturelle : créer votre premier realm applicatif et y déclarer un client, sans jamais toucher au realm master réservé à l’administration.