Aller au contenu

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 :

  1. Configuration > Authentication > Auth Mode : OIDC
  2. 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 :

https://auth.example.com/realms/organization/protocol/saml/descriptor

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