Aller au contenu principal

Authentification unique OIDC

fremforge prend en charge OpenID Connect (OIDC) pour l’authentification unique. OIDC est le protocole d’authentification unique que prend en charge fremforge. Tous les grands IdP (Entra, Okta, Google Workspace, Auth0, Authentik, Keycloak) prennent OIDC en charge nativement. Le cycle de vie des clés de signature est automatique grâce aux points de terminaison de découverte OIDC et JWKS.

OIDC est le seul protocole d’authentification unique que propose fremforge aujourd’hui. SAML n’est pas encore disponible ; Microsoft Entra ID et ADFS prennent tous deux en charge OIDC.

Configuration

Étape 1 : vérifier un domaine

Administration de l’organisation → SSO → Domaines vérifiés (dépliez la section repliée) → ajoutez votre domaine de messagerie (par ex. acme.com). Prouvez que vous le contrôlez de l’une des façons suivantes :

  • Enregistrement DNS TXT : ajoutez _fremforge-verification=<token> au DNS de votre domaine, puis cliquez sur Vérifier maintenant.
  • Fichier HTTP : servez le jeton à l’adresse https://acme.com/.well-known/fremforge-verification, puis cliquez sur Vérifier maintenant.

La vérification du domaine est obligatoire avant d’enregistrer une source d’authentification. Vous ne le faites qu’une fois.

Étape 2 : créer une application OAuth 2.0 dans votre IdP

fremforge a besoin de trois valeurs provenant de votre IdP : le Client ID, le Client Secret et l’URL de l’émetteur (aussi appelée racine de l’URL de découverte OIDC). Configurez votre IdP comme suit.

Okta

  1. Applications → Create App Integration → OIDC, Web Application.
  2. Sign-in redirect URIs : https://frem.sh/user/oauth2/<auth-source-name>/callback
  3. Sign-out redirect URIs : https://frem.sh/<your-org>/logout (facultatif mais recommandé)
  4. Assignments : attribuez l’application aux groupes ou aux utilisateurs qui doivent avoir accès à fremforge.
  5. Copiez le Client ID, le Client Secret et le domaine Okta (par ex. https://acme.okta.com).
    • URL de l’émetteur = https://acme.okta.com (ou https://acme.okta.com/oauth2/default pour les serveurs d’autorisation personnalisés)

Microsoft Entra (Azure AD)

  1. App registrations → New registration, nom « fremforge », types de comptes pris en charge = locataire unique.
  2. Redirect URI : Web → https://frem.sh/user/oauth2/<auth-source-name>/callback
  3. Certificates & secrets → New client secret, copiez immédiatement la Value (affichée une seule fois).
  4. Overview : copiez l’Application (client) ID et le Directory (tenant) ID.
    • URL de l’émetteur = https://login.microsoftonline.com/<tenant-id>/v2.0
  5. Token configuration → Add groups claim, sélectionnez Security groups. Cela renseigne le claim groups utilisé pour la correspondance avec les équipes fremforge.
  6. API permissions : vérifiez que openid, profile et email sont accordés (ils le sont par défaut).

ADFS

ADFS sur Windows Server 2016 et versions ultérieures est un fournisseur OpenID Connect.

  1. AD FS Management → Application Groups → Add Application Group, nom « fremforge », modèle Server application (sous Standalone applications) ou Server application accessing a web API.
  2. Copiez le Client Identifier. Redirect URI : https://frem.sh/user/oauth2/<auth-source-name>/callback.
  3. Configure Application Credentials → Generate a shared secret, copiez-le (affiché une seule fois).
  4. Accordez les scopes openid, profile et email, et ajoutez des règles de transformation d’émission qui placent email et name (et un claim de groupes, si vous faites correspondre des équipes) dans le jeton d’identité.
    • URL de l’émetteur = https://<your-adfs-host>/adfs (découverte à l’adresse https://<your-adfs-host>/adfs/.well-known/openid-configuration)

La vérification MFA OIDC n’a pas encore été testée avec ADFS. Activez-la d’abord pour un utilisateur de test et vérifiez que la connexion réussit.

Google Workspace

  1. Google Cloud Console → APIs & Services → Credentials → Create credentials → OAuth client ID.
  2. Type d’application : Web application.
  3. Authorised redirect URIs : https://frem.sh/user/oauth2/<auth-source-name>/callback
  4. Copiez le Client ID et le Client Secret.
    • URL de l’émetteur = https://accounts.google.com
  5. Dans Google Workspace Admin → Security → API controls → Domain-wide delegation, limitez le consentement OAuth à votre domaine, pour que seuls les membres de l’espace de travail puissent s’authentifier.

Authentik

  1. Applications → Providers → Create → OAuth2/OpenID Connect Provider.
  2. Redirect URIs : https://frem.sh/user/oauth2/<auth-source-name>/callback
  3. Signing Key : sélectionnez votre certificat de signature Authentik.
  4. Copiez le Client ID, le Client Secret et l’OpenID Configuration URL (retirez /.well-known/openid-configuration : l’URL de l’émetteur est la racine, par ex. https://sso.acme.internal/application/o/<slug>/).
  5. Créez une Application et liez-la au provider ; définissez l’URL de lancement sur frem.sh/user/login?redirect_to=/<your-org>.

Keycloak

  1. Your Realm → Clients → Create client.
  2. Client type : OpenID Connect. Client ID : fremforge.
  3. Valid redirect URIs : https://frem.sh/user/oauth2/<auth-source-name>/callback
  4. Onglet Credentials : copiez le Client Secret.
    • URL de l’émetteur = https://keycloak.acme.internal/realms/<your-realm>

Auth0 / Okta Customer Identity Cloud

  1. Applications → Create Application → Regular Web Application.
  2. Allowed Callback URLs : https://frem.sh/user/oauth2/<auth-source-name>/callback
  3. Allowed Logout URLs : https://frem.sh/<your-org>/logout
  4. Settings : copiez Domain, Client ID et Client Secret.
    • URL de l’émetteur = https://<your-auth0-domain>/

Étape 3 : enregistrer le fournisseur dans fremforge

  1. Administration de l’organisation → SSO, descendez jusqu’à Ajouter une source SSO, cliquez sur Start wizard (ouvre /_admin/sso/wizard/start).
  2. Choisissez OpenID Connect comme type de source et continuez.
  3. Renseignez :
    • Nom affiché : affiché sur le bouton de la page de connexion, par ex. « Se connecter avec Okta ».
    • Client ID et Client Secret de l’étape 2.
    • URL de l’émetteur : fremforge récupère <issuer>/.well-known/openid-configuration pour découvrir automatiquement les points de terminaison.
  4. Attribute mapping (les valeurs par défaut facultatives conviennent à la plupart des IdP) :
    • claim email → adresse e-mail fremforge (par défaut : email)
    • claim username → nom d’utilisateur Forgejo (par défaut : preferred_username → à défaut, email)
    • claim display_name → nom complet (par défaut : name)
  5. Parcourez les écrans de vérification et de confirmation de l’assistant. fremforge effectue une récupération de découverte et valide la connectivité avant d’enregistrer.

Une fois l’enregistrement effectué, un bouton Se connecter avec <name> apparaît sur la page de connexion de votre organisation, à l’adresse frem.sh/user/login?redirect_to=/<your-org>.

Via l’API REST

La source d’authentification OIDC peut être enregistrée par programme, ce qui est utile pour scripter le provisionnement d’organisations ou piloter la configuration depuis la CI. C’est le même provisionOidcAuthSource que celui qu’exécute l’assistant d’administration.

  • Vérifiez d’abord un domaine POST /_app/api/v1/orgs/:slug/sso/domains corps : { "domain": "acme.com" } puis POST /_app/api/v1/orgs/:slug/sso/domains/:id/verify
  • Enregistrez la source OIDC POST /_app/api/v1/orgs/:slug/sso le corps inclut type: "oidc", issuer_url, client_id, client_secret
  • Mettez à jour la correspondance groupe → équipe PUT /_app/api/v1/orgs/:slug/sso corps : { "id": "...", "group_team_map": { ... } }
  • Listez les sources GET /_app/api/v1/orgs/:slug/sso

Nécessite un jeton d’accès personnel (PAT) avec le scope sso:write :

curl -X POST \
  -H "Authorization: Bearer ${FREMFORGE_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "acme-okta",
    "type": "oidc",
    "issuer_url": "https://acme.okta.com",
    "client_id": "0oa1abc...",
    "client_secret": "s3cr3t..."
  }' \
  https://frem.sh/_app/api/v1/orgs/acme/sso

Consultez la référence de l’API REST publique pour la spécification OpenAPI complète.

Ce qui se passe à la connexion

  1. L’utilisateur clique sur Se connecter avec <name> à l’adresse frem.sh/user/login?redirect_to=/<your-org>.
  2. fremforge redirige vers le point de terminaison d’autorisation de votre IdP avec scope=openid email profile.
  3. L’utilisateur s’authentifie auprès de l’IdP (MFA imposée par l’IdP, pas par fremforge).
  4. L’IdP redirige vers frem.sh/user/oauth2/<auth-source-name>/callback avec un code d’autorisation.
  5. fremforge échange le code contre des jetons, valide la signature du jeton d’identité à l’aide du JWKS de l’IdP, extrait les claims d’adresse e-mail et de nom d’utilisateur, et crée ou met à jour l’utilisateur Forgejo.
  6. Si Require SSO est activé (Administration de l’organisation → SSO → Politiques), la connexion directe par mot de passe est bloquée. Seul le parcours par l’IdP fonctionne.

Exiger le SSO

Administration de l’organisation → SSO → Politiques → Require SSO for all members ; une fois cette option activée :

  • Les membres existants doivent se réauthentifier via l’IdP lors de leur prochaine connexion.
  • Les PAT et les clés SSH restent valides comme moyens d’authentification, mais lorsque Require SSO est activé, la session IdP est revalidée toutes les 15 minutes lors des opérations Git. Un utilisateur désactivé dans l’IdP perd donc l’accès en push/pull dans les 15 minutes, même si sa clé SSH est toujours enregistrée. Aucune révocation séparée des clés n’est nécessaire.
  • Les nouvelles invitations de membres aboutissent à des comptes uniquement SSO.

Associer à SCIM pour gérer tout le cycle de vie

OIDC gère l’authentification. Pour automatiser le provisionnement et le déprovisionnement des utilisateurs (créer les comptes à l’embauche, les désactiver au départ, synchroniser l’appartenance aux groupes), associez OIDC au provisionnement SCIM 2.0.

La plupart des IdP d’entreprise (Okta, Entra) prennent en charge OIDC et SCIM simultanément. La configuration type :

  1. Configurez OIDC pour que les membres puissent se connecter via l’IdP.
  2. Activez SCIM pour que l’IdP pousse automatiquement les modifications d’utilisateurs et de groupes.
  3. Activez Require SSO. Avec SCIM actif, déprovisionner l’utilisateur dans l’IdP bloque immédiatement son accès à fremforge.

Rotation des jetons

fremforge met en cache le JWKS (les clés de signature) de l’IdP et le rafraîchit selon un calendrier ainsi qu’en cas d’échec de validation d’une signature. La rotation des clés côté IdP (par ex. la rotation automatique des clés d’Okta) est gérée de façon transparente. Aucune action manuelle n’est requise.

Si vous faites tourner le Client Secret dans l’IdP :

La carte de la source d’authentification dans Administration de l’organisation → SSO n’a pas de champ pour le Client Secret, et une source d’authentification ne peut plus être modifiée après sa création. Pour changer le secret, contactez support@frem.sh avant de révoquer l’ancien dans l’IdP : nous le mettons à jour pour vous, et la connexion continue de fonctionner.

Désactiver OIDC

Pour arrêter la connexion par OIDC, retirez la source d’authentification : Administration de l’organisation → SSO → <source d’authentification> → Retirer. La connexion par cette source s’arrête immédiatement. Si aucun membre ne s’est encore connecté par elle, elle est supprimée ; sinon, fremforge en conserve une copie désactivée et renommée pour que leurs comptes restent. Leurs comptes, sessions et jetons d’accès ne sont pas révoqués : pour couper cet accès, retirez ces membres de l’organisation ou déprovisionnez-les via SCIM. Les utilisateurs qui n’avaient que la voie OIDC se rabattent sur l’e-mail et le mot de passe (si un mot de passe local est défini) ou ne peuvent plus se connecter ; assurez-vous donc d’abord qu’un propriétaire de secours peut encore se connecter avec un mot de passe local. Si le retrait échoue, la console l’indique, rien n’est modifié et la connexion par la source continue de fonctionner.

Il n’existe pas d’interrupteur pour désactiver une source d’authentification un temps puis la réactiver ; pour cela, contactez support@frem.sh. Pour éviter des comptes orphelins, retirez la source d’authentification avant de supprimer l’application dans votre IdP, et non après.

Dépannage

URI de redirection qui ne correspond pas

L’IdP rejette le retour si l’URI de redirection enregistrée dans l’IdP ne correspond pas exactement à https://frem.sh/user/oauth2/<auth-source-name>/callback. Le <auth-source-name> est le Name que vous avez défini en ajoutant la source d’authentification dans fremforge (par ex. okta-primary, entra-prod) ; le routeur OAuth2 de Forgejo l’utilise pour aiguiller le retour. Copiez l’URL de retour exacte depuis le champ Redirect URI que l’assistant SSO affiche pendant que vous ajoutez la source d’authentification (Administration de l’organisation → SSO → + Ajouter une source SSO) plutôt que de la saisir à la main ; l’URL est sensible à la casse et les barres obliques finales comptent.

invalid_client lors de l’échange de jetons

Le Client ID ou le Client Secret est incorrect. Copiez-les à nouveau depuis la console de l’IdP. Certains IdP n’affichent le secret qu’une seule fois, à la création. Générez un nouveau secret si l’original n’a pas été conservé.

Claims manquants (nom d’utilisateur ou adresse e-mail vides)

Vérifiez la politique de diffusion des attributs / claims de l’IdP. fremforge exige au minimum le claim email dans le jeton d’identité. Si votre IdP conditionne la diffusion des claims à des permissions explicites (par ex. Entra exige les permissions d’API profile et email), assurez-vous qu’elles sont accordées et consenties.

Utilisateurs provisionnés mais incapables de se connecter

Si Require SSO est activé et que le domaine de l’adresse e-mail de l’utilisateur ne correspond à aucun domaine vérifié, fremforge bloque la connexion. Vérifiez le domaine sous Administration de l’organisation → SSO → Domaines vérifiés. Le domaine figurant dans le claim email de l’utilisateur doit correspondre.

Réauthentification liée à la session par organisation

Au-delà de la connexion SSO standard, fremforge peut imposer une authentification IdP fraîche chaque fois qu’un utilisateur entre dans l’interface d’administration d’une nouvelle organisation. C’est le « rattachement de session par organisation » de niveau secteur réglementé annoncé sur la page des tarifs, utile lorsque chaque action d’administration inter-organisations doit s’appuyer sur une authentification attestée par l’IdP et propre à l’organisation concernée.

Deux niveaux de robustesse. Le rattachement est activé par défaut ; le niveau appliqué dépend de la configuration ou non du client de réauthentification décrit ci-dessous :

  • Rattachement souple (par défaut si vous ne configurez pas la réauthentification) : la redirection lors du premier accès à une autre organisation passe par la page universelle /user/login de Forgejo. Si votre session Forgejo est valide, l’aller-retour est invisible et ne demande rien : il prouve donc que le navigateur détient une session valide, et non que l’utilisateur s’est authentifié à nouveau. Utilisez le rattachement strict si vous avez besoin d’une authentification fraîche par organisation. L’accès de secours par identifiants locaux reste intact.
  • Rattachement strict (à configurer ci-dessous) : la redirection passe par le point de terminaison de réauthentification de fremforge, qui lance une authentification OIDC avec prompt=login auprès de votre IdP. L’IdP DOIT redemander les identifiants et la MFA ; nous vérifions que l’auth_time du jeton d’identité renvoyé date de moins de 5 minutes. L’accès de secours par identifiants locaux via /user/login fonctionne toujours pour les propriétaires d’organisation ; le rattachement strict ne modifie que le parcours d’accès à une autre organisation, pas la connexion universelle.

Configurer le rattachement strict

Le rattachement strict exige un SECOND client OIDC dans votre IdP, à côté de celui qu’utilise Forgejo (même émetteur, client_id et client_secret distincts, URI de redirection distincte).

  1. Dans votre IdP, enregistrez une nouvelle application OIDC :

    ChampValeur
    Type d’applicationWeb (confidentielle)
    Types d’autorisationAuthorization Code, avec PKCE
    URI de redirectionhttps://frem.sh/<your-org>/_admin/-/stepup/callback
    Méthode d’authentification au point de terminaison des jetonsclient_secret_basic ou client_secret_post
    Scopes requisopenid, email
    Claim auth_timeObligatoire dans le jeton d’identité
    prompt=loginRespecté (comportement par défaut de la plupart des IdP)
  2. Dans fremforge, allez dans Administration de l’organisation → SSO, dépliez Add OIDC auth source et renseignez les champs facultatifs Per-org session-binding step-up en bas du formulaire :

    • Step-up Client ID : celui de la nouvelle application de votre IdP
    • Step-up Client Secret : celui de la nouvelle application de votre IdP, chiffré au repos en AES-256-GCM (sous-clé dérivée par HKDF) avant enregistrement
    • Step-up Redirect URI : https://frem.sh/<your-org>/_admin/-/stepup/callback
  3. Vérifiez : ouvrez https://frem.sh/<your-org>/_admin/billing dans une nouvelle fenêtre de navigateur. Vous devriez être redirigé vers votre IdP, être invité à vous authentifier à nouveau, puis revenir sur la page de facturation. Le journal d’audit affiche un événement org-session.step-up.ok avec auth_time.

Si les champs de réauthentification sont laissés vides, la source d’authentification se replie sur le rattachement souple, ce qui convient aux organisations qui veulent le SSO à la connexion sans avoir besoin d’une attestation IdP par organisation.

Dépannage du rattachement strict

  • « IdP did not emit auth_time » : l’IdP a renvoyé un jeton d’identité sans le claim auth_time. fremforge l’exige, car c’est ainsi que nous vérifions la fraîcheur de la réauthentification. Vérifiez la politique de claims de l’IdP ; la plupart proposent une option « inclure auth_time ».
  • « auth_time too old » : l’IdP a respecté prompt=login au niveau du protocole, mais n’a pas réellement redemandé l’authentification à l’utilisateur. Resserrez la politique de « durée de session » ou d’« âge maximal » de l’IdP pour ce client.
  • « step-up cookie binding mismatch » : l’utilisateur a changé d’identité en cours de route (par ex. en ouvrant un second onglet et en s’authentifiant comme un autre utilisateur). Recommencez depuis /<your-org>/_admin/billing.
  • « step-up redirect URI rejected » : l’URI n’a pas passé notre contrôle HTTPS public (les adresses privées, de bouclage et de métadonnées sont bloquées). Utilisez la forme canonique frem.sh/_app.

Voir aussi