Integration¶
Principe général¶
Chaque service du catalogue s'authentifie contre Keycloak via un client OIDC dedie. Le flux standard est :
graph LR
User["Utilisateur"] --> Service --> KC["Redirection vers Keycloak"]
KC --> Login["Login + MFA"]
Login --> Code["Code d'autorisation"]
Code --> Token["Token JWT"]
Token --> Svc2["Service"] --> Session Convention de nommage des clients¶
| Élément | Format | Exemple |
|---|---|---|
| Client ID | svc-<nom-du-service> | svc-gitea |
| Redirect URI | https://<fqdn>/auth/callback | https://git.example.com/user/oauth2/keycloak/callback |
| Scope | openid profile email groups | — |
Créer un client OIDC generique¶
# Modele de creation d'un client OIDC
kcadm.sh create clients -r organization \
-s clientId=svc-example \
-s enabled=true \
-s protocol=openid-connect \
-s publicClient=false \
-s 'redirectUris=["https://example.com/callback"]' \
-s 'webOrigins=["https://example.com"]' \
-s directAccessGrantsEnabled=false \
-s standardFlowEnabled=true \
-s serviceAccountsEnabled=false \
-s 'defaultClientScopes=["openid","profile","email"]'
Clients confidentiels uniquement
Toujours utiliser publicClient=false pour les services backend. Les clients publics (SPA sans backend) necessitent PKCE en complement.
Gitea (gestion du code source)¶
Configuration dans Keycloak¶
kcadm.sh create clients -r organization \
-s clientId=svc-gitea \
-s enabled=true \
-s protocol=openid-connect \
-s publicClient=false \
-s 'redirectUris=["https://git.example.com/user/oauth2/keycloak/callback"]' \
-s 'webOrigins=["https://git.example.com"]' \
-s standardFlowEnabled=true \
-s 'defaultClientScopes=["openid","profile","email","groups"]'
Configuration dans Gitea (app.ini)¶
[oauth2]
ENABLE = true
[service]
ALLOW_ONLY_EXTERNAL_REGISTRATION = true
DISABLE_REGISTRATION = false
; A configurer via l'interface admin de Gitea :
; Authentication Sources > Add OAuth2
; Provider: OpenID Connect
; Client ID: svc-gitea
; Client Secret: <genere par Keycloak>
; OpenID Connect Auto Discovery URL:
; https://auth.example.com/realms/organization/.well-known/openid-configuration
; Scopes: openid profile email groups
Mapper les équipes Gitea sur les groupes Keycloak¶
Ajouter un mapper dans le client svc-gitea :
| Parametre | Valeur |
|---|---|
| Mapper Type | Group Membership |
| Name | gitea-groups |
| Token Claim Name | groups |
| Full group path | OFF |
| Add to ID token | ON |
| Add to access token | ON |
Grafana (observabilité)¶
Configuration dans Keycloak¶
kcadm.sh create clients -r organization \
-s clientId=svc-grafana \
-s enabled=true \
-s protocol=openid-connect \
-s publicClient=false \
-s 'redirectUris=["https://grafana.example.com/login/generic_oauth"]' \
-s 'webOrigins=["https://grafana.example.com"]' \
-s standardFlowEnabled=true \
-s 'defaultClientScopes=["openid","profile","email","groups"]'
Configuration dans Grafana (grafana.ini)¶
[auth.generic_oauth]
enabled = true
name = Keycloak
allow_sign_up = true
client_id = svc-grafana
client_secret = ${GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET}
scopes = openid profile email groups
auth_url = https://auth.example.com/realms/organization/protocol/openid-connect/auth
token_url = https://auth.example.com/realms/organization/protocol/openid-connect/token
api_url = https://auth.example.com/realms/organization/protocol/openid-connect/userinfo
role_attribute_path = contains(groups[*], 'grafana-admin') && 'Admin' || contains(groups[*], 'grafana-editor') && 'Editor' || 'Viewer'
Mapping des rôles Grafana
L'expression role_attribute_path utilise JMESPath pour mapper les groupes Keycloak aux rôles Grafana. Créer les groupes grafana-admin, grafana-editor dans Keycloak et y affecter les utilisateurs.
Guacamole (accès distant)¶
Configuration dans Keycloak¶
kcadm.sh create clients -r organization \
-s clientId=svc-guacamole \
-s enabled=true \
-s protocol=openid-connect \
-s publicClient=false \
-s 'redirectUris=["https://remote.example.com/guacamole/*"]' \
-s 'webOrigins=["https://remote.example.com"]' \
-s standardFlowEnabled=true
Configuration dans Guacamole (guacamole.properties)¶
# OpenID Connect
openid-authorization-endpoint=https://auth.example.com/realms/organization/protocol/openid-connect/auth
openid-jwks-endpoint=https://auth.example.com/realms/organization/protocol/openid-connect/certs
openid-issuer=https://auth.example.com/realms/organization
openid-client-id=svc-guacamole
openid-redirect-uri=https://remote.example.com/guacamole/
openid-scope=openid profile email
openid-username-claim-type=preferred_username
ArgoCD (déploiement continu)¶
Configuration dans Keycloak¶
kcadm.sh create clients -r organization \
-s clientId=svc-argocd \
-s enabled=true \
-s protocol=openid-connect \
-s publicClient=false \
-s 'redirectUris=["https://argocd.example.com/auth/callback"]' \
-s 'webOrigins=["https://argocd.example.com"]' \
-s standardFlowEnabled=true \
-s 'defaultClientScopes=["openid","profile","email","groups"]'
Configuration dans ArgoCD (argocd-cm ConfigMap)¶
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Keycloak
issuer: https://auth.example.com/realms/organization
clientID: svc-argocd
clientSecret: $oidc.keycloak.clientSecret
requestedScopes:
- openid
- profile
- email
- groups
RBAC ArgoCD base sur les groupes Keycloak¶
# argocd-rbac-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.csv: |
g, argocd-admin, role:admin
g, platform-team, role:admin
g, developers, role:readonly
policy.default: role:readonly
Nextcloud (collaboration)¶
Configuration dans Keycloak¶
kcadm.sh create clients -r organization \
-s clientId=svc-nextcloud \
-s enabled=true \
-s protocol=openid-connect \
-s publicClient=false \
-s 'redirectUris=["https://cloud.example.com/apps/sociallogin/custom_oidc/keycloak"]' \
-s 'webOrigins=["https://cloud.example.com"]' \
-s standardFlowEnabled=true
Configuration dans Nextcloud¶
Installer l'application Social Login depuis le store Nextcloud, puis configurer :
| Parametre | Valeur |
|---|---|
| Provider | Custom OpenID Connect |
| Internal name | keycloak |
| Title | Connexion SSO |
| Authorize URL | https://auth.example.com/realms/organization/protocol/openid-connect/auth |
| Token URL | https://auth.example.com/realms/organization/protocol/openid-connect/token |
| User info URL | https://auth.example.com/realms/organization/protocol/openid-connect/userinfo |
| Client ID | svc-nextcloud |
| Client Secret | <genere par Keycloak> |
| Scope | openid profile email |
Harbor (registre d'images)¶
Configuration dans Keycloak¶
kcadm.sh create clients -r organization \
-s clientId=svc-harbor \
-s enabled=true \
-s protocol=openid-connect \
-s publicClient=false \
-s 'redirectUris=["https://registry.example.com/c/oidc/callback"]' \
-s 'webOrigins=["https://registry.example.com"]' \
-s standardFlowEnabled=true \
-s 'defaultClientScopes=["openid","profile","email","groups"]'
Configuration dans Harbor¶
Via l'interface d'administration de Harbor :
- Configuration > Authentication > Auth Mode : OIDC
- Renseigner les parametres :
| Parametre | Valeur |
|---|---|
| OIDC Provider Name | Keycloak |
| OIDC Endpoint | https://auth.example.com/realms/organization |
| OIDC Client ID | svc-harbor |
| OIDC Client Secret | <genere par Keycloak> |
| OIDC Scope | openid,profile,email,groups |
| Group Claim Name | groups |
| OIDC Admin Group | harbor-admin |
| Automatic onboarding | Enabled |
Fédération LDAP¶
Pour les organisations qui conservent un annuaire LDAP existant, Keycloak peut agreger plusieurs sources d'identités.
Architecture de fédération¶
graph TD
AD["Active Directory"] -->|LDAPS| KC
LDAP["OpenLDAP<br/>(legacy)"] -->|LDAPS| KC
Local["Base locale<br/>Keycloak"] --> KC
KC["Keycloak<br/>Federation User Storage SPI<br/>Priority: 1. AD 2. OpenLDAP 3. DB"] Priorité des federations
Si un utilisateur existe dans plusieurs sources, Keycloak utilise la première source qui répond. Définir les priorites pour eviter les conflits.
SAML pour les services legacy¶
Certains services ne supportent que SAML 2.0. Keycloak peut servir de bridge OIDC ↔ SAML.
Créer un client SAML¶
kcadm.sh create clients -r organization \
-s clientId=https://legacy.example.com/saml/metadata \
-s enabled=true \
-s protocol=saml \
-s 'attributes.saml.assertion.signature=true' \
-s 'attributes.saml.server.signature=true' \
-s 'attributes.saml_name_id_format=email' \
-s 'redirectUris=["https://legacy.example.com/saml/acs"]'
Le metadata SAML de Keycloak est accessible a :
SCIM provisioning¶
Le provisioning SCIM permet de synchroniser automatiquement les utilisateurs et groupes vers les applications.
Flux de provisioning¶
graph LR
A[RH: creation employe] --> B[Keycloak: nouveau user]
B --> C[SCIM: POST /Users]
C --> D[Gitea: compte cree]
C --> E[Grafana: compte cree]
C --> F[Nextcloud: compte cree]
B --> G[SCIM: PATCH /Users]
G --> H[Mise a jour dans toutes les apps]
B --> I[SCIM: DELETE /Users]
I --> J[Desactivation dans toutes les apps] SCIM dans Keycloak
Le support SCIM dans Keycloak necessite une extension tierce (par exemple scim-for-keycloak). Vérifier la compatibilité avec la version de Keycloak déployée. Authentik propose le SCIM de manière native si cette fonctionnalité est critique.
Recapitulatif des clients¶
| Service | Client ID | Protocole | Redirect URI |
|---|---|---|---|
| Gitea | svc-gitea | OIDC | /user/oauth2/keycloak/callback |
| Grafana | svc-grafana | OIDC | /login/generic_oauth |
| Guacamole | svc-guacamole | OIDC | /guacamole/ |
| ArgoCD | svc-argocd | OIDC | /auth/callback |
| Nextcloud | svc-nextcloud | OIDC | /apps/sociallogin/custom_oidc/keycloak |
| Harbor | svc-harbor | OIDC | /c/oidc/callback |
| Legacy app | https://legacy.example.com/... | SAML | /saml/acs |