OpenID Connect
Semaphore prend en charge l'authentification via OpenID Connect (OIDC).
Liens :
- Configuration GitHub
- Configuration Google
- Configuration GitLab
- Configuration Authelia
- Configuration Authentik
- Configuration Keycloak
- Configuration Okta
- Configuration PingFederate
- Configuration Azure
- Configuration Zitadel
- Configuration Pocket-ID
Exemple de configuration d'un fournisseur SSO :
{
"oidc_providers": {
"mysso": {
"display_name": "Sign in with MySSO",
"color": "orange",
"icon": "login",
"provider_url": "https://mysso-provider.com",
"client_id": "***",
"client_secret": "***",
"redirect_url": "https://your-domain.com/api/auth/oidc/mysso/redirect"
}
}
}
Configuration via une variable d'environnement
Lors d'une exécution dans des conteneurs, il peut être pratique de configurer les fournisseurs à l'aide d'une seule variable d'environnement :
SEMAPHORE_OIDC_PROVIDERS='{
"github": {
"client_id": "***",
"client_secret": "***"
}
}'
Cette valeur doit être une chaîne JSON valide correspondant à la structure oidc_providers ci-dessus.
Toutes les options d'un fournisseur SSO :
| Paramètre | Description |
|---|---|
display_name | Nom du fournisseur affiché sur l'écran de connexion. |
icon | Icône MDI affichée devant le nom du fournisseur sur l'écran de connexion. |
color | Nom du fournisseur affiché sur l'écran de connexion. |
client_id | ID client du fournisseur. |
client_id_file | Chemin du fichier dans lequel est stocké l'ID client du fournisseur. A une priorité inférieure à client_id. |
client_secret | Secret client du fournisseur. |
client_secret_file | Chemin du fichier dans lequel est stocké le secret client du fournisseur. A une priorité inférieure à client_secret. |
redirect_url | |
provider_url | |
scopes | |
username_claim | Expression de claim du nom d'utilisateur*. |
email_claim | Expression de claim de l'e-mail*. |
name_claim | Expression de claim du nom de profil*. |
groups_claim | Nom du claim du jeton qui contient les groupes de l'utilisateur. Utilisé par les mappages de groupe. |
order | Position du bouton du fournisseur sur l'écran de connexion. |
allow_idp_initiated | Active la connexion initiée par l'IdP pour ce fournisseur. Par défaut false. |
return_via_state | Transmet le chemin de retour post-connexion via le paramètre OAuth state plutôt que via l'URL de redirection. Par défaut true. |
endpoint.issuer | |
endpoint.auth | |
endpoint.token | |
endpoint.userinfo | |
endpoint.jwks | |
endpoint.algorithms |
*Expression de claim
Exemple d'expression de claim :
email | {{ .username }}@your-domain.com
Semaphore tente d'abord de récupérer le champ email. S'il est vide, l'expression qui suit est évaluée.
L'expression "username_claim": "|" génère un username aléatoire pour chaque utilisateur qui se connecte via le fournisseur.
Rôles de projet à partir des groupes Enterprise
Les mappages de groupe sont disponibles dans l'édition Semaphore Enterprise.
Un mappage de groupe donne un rôle de projet à chaque utilisateur d'un groupe du fournisseur d'identité. Par exemple, un mappage peut donner aux membres du groupe devops le rôle Manager dans le projet Infrastructure.
Envoyer les groupes dans le jeton
Donnez à groups_claim le nom du claim qui contient les groupes de l'utilisateur. Sans ce paramètre, les connexions via le fournisseur ne modifient pas les rôles issus des mappages de groupe.
Les groupes doivent figurer dans le jeton d'identité (ID token). Beaucoup de fournisseurs d'identité, par exemple Dex, n'envoient les groupes que si Semaphore demande le scope groups :
{
"oidc_providers": {
"dex": {
"display_name": "Sign in with Dex",
"provider_url": "https://dex.your-domain.com",
"client_id": "***",
"client_secret": "***",
"redirect_url": "https://your-domain.com/api/auth/oidc/dex/redirect",
"scopes": ["openid", "email", "profile", "groups"],
"groups_claim": "groups"
}
}
}
Créer un mappage de groupe
- Ouvrez le menu d'administration en bas à gauche et sélectionnez Group mappings.
- Sélectionnez New mapping.
- Choisissez le fournisseur, saisissez le nom du groupe, puis choisissez le projet et le rôle.
- Sélectionnez Enregistrer.
Le nom du groupe doit correspondre exactement au nom présent dans le jeton, y compris les majuscules et les minuscules. Pour changer un mappage de groupe, supprimez ce mappage et créez-en un nouveau.
Semaphore met à jour les rôles issus des mappages de groupe à chaque connexion de l'utilisateur via le fournisseur. Un utilisateur qui quitte un groupe garde le rôle jusqu'à sa prochaine connexion. Pour que ces changements prennent effet plus tôt, limitez la durée des sessions avec auth.max_session_life_hours.
Connexion initiée par l'IdP
Par défaut, Semaphore ne prend en charge que la connexion initiée par le SP : l'utilisateur ouvre Semaphore, clique sur le bouton du fournisseur et est redirigé vers le fournisseur d'identité (IdP).
Avec la connexion initiée par l'IdP, le parcours peut au contraire commencer chez le fournisseur d'identité — par exemple en cliquant sur la tuile Semaphore dans le tableau de bord Okta, dans My Apps d'Azure ou dans un lanceur d'applications Keycloak / Authentik.
Semaphore implémente cela à l'aide du mécanisme standard Third-Party Initiated Login (OpenID Connect Core 1.0 §4). L'IdP redirige le navigateur vers une Initiate Login URI dédiée, puis Semaphore démarre un flux Authorization Code classique. L'authentification proprement dite reste un échange de code complet et sécurisé — Semaphore n'accepte jamais de token non sollicité.
Activation
Définissez allow_idp_initiated à true pour le fournisseur :
{
"oidc_providers": {
"mysso": {
"display_name": "Sign in with MySSO",
"provider_url": "https://mysso-provider.com",
"client_id": "***",
"client_secret": "***",
"redirect_url": "https://your-domain.com/api/auth/oidc/mysso/redirect",
"allow_idp_initiated": true
}
}
}
Configurer le fournisseur d'identité
Dans votre IdP, définissez l'Initiate Login URI de l'application à :
https://your-domain.com/api/auth/oidc/<provider-id>/initiate
où <provider-id> est la clé sous oidc_providers (par exemple mysso).
L'IdP doit envoyer le paramètre iss (issuer) à ce point de terminaison ; Semaphore rejette les requêtes dont le iss ne correspond pas
au fournisseur configuré. Le paramètre facultatif login_hint est transmis à l'IdP, et un paramètre facultatif target_link_uri
définit la page à ouvrir après la connexion (il doit pointer vers Semaphore, sinon il est ignoré).
Remarques propres à certains fournisseurs :
- Okta — définissez Login initiated by à Either Okta or App (ou App Only) et renseignez l'Initiate login URI. Okta
envoie à la fois
issettarget_link_uri. - Keycloak / Authentik / Ping / OneLogin — définissez l'URL de lancement / d'accueil de l'application à l'Initiate Login URI.
- Azure AD / Entra — My Apps utilise une URL de démarrage initiée par le SP et n'envoie pas toujours
iss; faites plutôt pointer l'URL de démarrage vershttps://your-domain.com/api/auth/oidc/<provider-id>/login.
Sécurité
- La connexion initiée par l'IdP est désactivée par défaut et doit être activée pour chaque fournisseur.
- Le paramètre
issest validé par rapport à l'issuer configuré afin d'éviter toute confusion entre fournisseurs. target_link_urin'est accepté que s'il pointe vers Semaphore (pas de redirection ouverte).- Le flux passe par l'échange Authorization Code complet avec un
stateCSRF et unnonce, de sorte qu'un token capturé ou rejoué ne peut pas être utilisé pour se connecter.
Écran de connexion
Pour chacun des fournisseurs configurés, un bouton de connexion supplémentaire est ajouté à la page de connexion :
