> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SSO de Devin en air gap avec votre IdP

> Exigez une connexion à Devin Desktop et à la CLI en air gap via votre propre fournisseur d’identité OIDC : fichier d’authentification, paramètres client, restriction par groupe, événements d’audit, codes IDP.

> [!NOTE]
>
> Cette documentation concerne les déploiements fédéraux de Devin. [Retour à la documentation Devin](/fr/get-started/devin-intro)

Par défaut, l’accès au build en air gap est contrôlé uniquement par le [fichier de licence](/fr/federal/air-gapped/license). Vous pouvez en outre exiger que chaque utilisateur se connecte via **votre propre fournisseur d’identité OIDC**. Le SSO (authentification unique) vient s’ajouter à la licence sous forme de couche supplémentaire : la licence reste obligatoire, et le flux de connexion s’effectue auprès de l’émetteur que vous configurez.

## Créer le fichier d'authentification

| | |
| - | - |
| Chemin par défaut | `/etc/devin/auth.json` |
| Chemin par défaut (Windows) | `C:\ProgramData\Devin\auth.json` |
| Surcharge | `DEVIN_AUTH_FILE=<path>` |

Le fichier définit un seul et unique mode. S'il n'existe pas, le produit se comporte comme s'il contenait `"mode": "license"`.

```json /etc/devin/auth.json theme={null}
{
  "schema_version": 0,
  "mode": "sso",
  "issuer": "https://sso.example.com",
  "client_id": "devin-cli",
  "scopes": ["openid", "profile", "email"],
  "groups_claim": "groups",
  "required_group": "devin-users",
  "additional_endpoint_hosts": []
}
```

| Champ | Obligatoire | Signification |
| - | - | - |
| `schema_version` | oui | Doit valoir `0`. |
| `mode` | oui | `"sso"` pour exiger une connexion, ou `"license"` pour un accès par licence uniquement (valeur par défaut en l’absence de fichier). |
| `issuer` | oui (sso) | L’URL de l’émetteur OIDC. Doit utiliser `https://` (le simple `http://` n’est accepté que pour les hôtes de bouclage), sans chaîne de requête, fragment ni credentials intégrés. La découverte s’effectue à l’adresse `<issuer>/.well-known/openid-configuration`. |
| `client_id` | oui (sso) | Le client que vous enregistrez auprès de l’IdP. |
| `scopes` | non | Valeur par défaut : `openid profile email`. Si ce champ est défini, il doit inclure `openid`. `offline_access` est demandé automatiquement lorsque l’IdP le prend en charge, afin d’obtenir un jeton de rafraîchissement. |
| `groups_claim` | non | Claim de l’ID token contenant l’appartenance aux groupes. Valeur par défaut : `groups`. |
| `required_group` | non | S’il est défini, la connexion est refusée si cette valeur ne figure pas dans le claim des groupes. |
| `additional_endpoint_hosts` | non | Hôtes supplémentaires sur lesquels le document de découverte de l’IdP peut annoncer des endpoints. Laissez ce champ vide sauf en cas de besoin ; voir [Les endpoints découverts doivent rester sur l’émetteur](#discovered-endpoints-must-stay-on-the-issuer). |

Les champs inconnus sont rejetés. En mode `license`, seuls `schema_version` et `mode` sont autorisés.

> [!TIP]
>
> Si votre IdP utilise un certificat émis par une autorité de certification privée, définissez `DEVIN_CA_BUNDLE` sur un paquet PEM pour que la CLI lui fasse confiance ; voir [Réseau et certificats](/fr/federal/air-gapped/network-and-certificates).

## Enregistrer le client auprès de votre IdP

La CLI exécute le **flux authorization code OIDC avec PKCE (S256)** en tant que **client public**ﾠ; aucun secret client n’est utilisé. Le client que vous enregistrez doit remplir les conditions suivantesﾠ:

1. Un client **public** (sans secret client) dont l’ID correspond à la valeur de `client_id`, par exemple `devin-cli`, avec le grant authorization code activé et la méthode PKCE `S256`.
2. `http://127.0.0.1/callback` enregistrée comme URI de redirection valide. La CLI écoute sur un port de bouclage aléatoire (`http://127.0.0.1:<port>/callback`) pour le flux via navigateur et utilise l’adresse fixe `http://127.0.0.1/callback` pour le flux manuel. Conformément à la RFC 8252, l’IdP doit ignorer le port de bouclageﾠ; si ce n’est pas le cas du vôtre, enregistrez un caractère générique correspondant.
3. Pour utiliser `required_group`, l’ID token doit contenir le claim d’appartenance aux groupes indiqué dans `groups_claim` (`groups` par défaut).
4. L’IdP renvoie un ID token lors du rafraîchissement (c’est le cas de la plupart des IdP lorsque le périmètre `openid` est accordé), et la durée de vie de l’ID token pour ce client est courte. Consultez [Propagation de la révocation](#how-revocation-propagates) pour en savoir plus.

## Connexion

Connectez-vous depuis un terminal du poste de travail :

```sh theme={null}
devin auth login
```

```text theme={null}
Opening your browser to sign in with your identity provider...
If the browser does not open, visit:

  https://sso.example.com/authorize?client_id=devin-cli&...

(Use `devin auth login --force-manual-token-flow` on headless machines.)
Logged in as jsmith via https://sso.example.com.
Token expires at 2026-03-02 15:04:05 UTC.
```

Sur un hôte sans interface graphique ou via SSH, utilisez le flux manuel. La CLI affiche une URL à ouvrir dans un navigateur, sur n'importe quelle machine ; une fois la connexion effectuée, le navigateur est redirigé vers une URL `127.0.0.1` qui ne se chargera pas. Copiez cette URL en entier (paramètres de requête compris) et collez-la dans le terminal.

```sh theme={null}
devin auth login --force-manual-token-flow
```

```text theme={null}
Open this URL in a browser (on any machine) and sign in:

  https://sso.example.com/authorize?client_id=devin-cli&...

After signing in, the browser is redirected to a 127.0.0.1 URL that will not load — copy that full URL (including its query parameters) and paste it here.
Paste the full redirect URL:
```

Devin Desktop utilise les mêmes identifiants de connexion via l'agent intégré ; si l'utilisateur n'est pas connecté, il est invité à se connecter dans les paramètres de Devin avant de commencer à travailler.

## Vérifier le statut et se déconnecter

```sh theme={null}
devin auth status
```

```text theme={null}
Auth mode: SSO (issuer: https://sso.example.com)
Status: logged in
User: jsmith
Subject: 6f1c2a0e-...
Groups: devin-users
Token expires at 2026-03-02 15:04:05 UTC.
```

Si la connexion mise en cache est absente ou ne peut plus être actualisée, la commande affiche `Status: not logged in (<reason>)` suivi de `Run \`devin auth login\` to sign in.\`

```sh theme={null}
devin auth logout
```

```text theme={null}
Logged out: local SSO tokens deleted.
```

La déconnexion s'effectue uniquement en local : elle supprime le cache de tokens sans contacter l'IdP.

## Ce que la CLI valide

L'ID token est validé localement : signature vérifiée à l'aide du JWKS de l'IdP, `iss`, `aud`, expiration (avec une tolérance de décalage d'horloge de 120 secondes), `nonce` de connexion et contrôle d'appartenance au groupe. Les ID tokens et les jetons de rafraîchissement sont mis en cache dans le magasin local de credentials, avec des autorisations réservées au propriétaire (`0600`), et sont actualisés de manière transparente auprès de l'IdP.

Lorsque le SSO (authentification unique) est configuré, qu'aucune connexion valide n'existe et que l'actualisation transparente échoue, la CLI s'arrête dès le démarrage et affiche une erreur invitant l'utilisateur à exécuter `devin auth login`.

La CLI ne suit jamais les redirections HTTP de l'IdP : une réponse `3xx` de l'endpoint de découverte, du JWKS ou de l'endpoint de token fait échouer la connexion, avec une erreur indiquant l'endpoint concerné. `issuer` doit donc pointer vers les URL effectivement servies par l'IdP.

### Les endpoints découverts doivent rester sur l'émetteur

Les valeurs `authorization_endpoint`, `token_endpoint` et `jwks_uri` obtenues lors de la découverte doivent avoir **le même schéma, le même hôte et le même port** que `issuer` (les ports par défaut sont considérés comme équivalents). Tout endpoint situé sur un autre hôte est refusé, et la connexion échoue avec une erreur du type :

```text theme={null}
IdP discovery document advertises jwks_uri 'https://keycloak.corp.internal:8443/realms/devin/protocol/openid-connect/certs'
on host 'keycloak.corp.internal:8443', which is not the configured issuer's host 'sso.corp.example:443';
refusing to trust it. If this IdP really serves that endpoint from a different host,
add "keycloak.corp.internal" to `sso.additional_endpoint_hosts` in the auth file
```

Certaines topologies d'IdP exposent légitimement des endpoints sur plusieurs hôtes. Le cas le plus courant sur site est Keycloak avec `hostname-backchannel-dynamic=true`, où `token_endpoint` et `jwks_uri` sont réécrits avec le hostname interne par lequel la CLI s'est connectée. Si, et seulement si, vous avez vérifié dans la configuration de l'IdP elle-même que l'hôte supplémentaire est voulu, ajoutez-le :

```json theme={null}
"additional_endpoint_hosts": ["keycloak.corp.internal"]
```

Les entrées sont de la forme `host` (n’importe quel port) ou `host:port`, sans distinction de casse. Il n’existe ni caractère générique ni moyen de désactiver la vérification. La liste d’autorisation n’assouplit jamais les exigences TLS : un endpoint `http://` reste refusé avec un émetteur `https://`. N’ajoutez pas un hôte simplement parce qu’une erreur de connexion le mentionne : cette erreur signifie justement que la vérification fonctionne.

## Propagation de la révocation

Le contrôle d’appartenance au groupe s'appuie sur l'ID token mis en cache : retirer un utilisateur de `required_group` (ou désactiver l'utilisateur) au niveau de l'IdP prend donc effet lors de sa prochaine actualisation du token, soit au plus tard à l'expiration de l'ID token actuel, plus la tolérance de décalage de 120 secondes. Si une révocation rapide est importante, définissez une durée de vie courte pour l'ID token de ce client.

Si une réponse de rafraîchissement ne contient pas de nouvel ID token, l'ID token mis en cache reste utilisé, mais seulement jusqu'à 24 heures après le `exp` de ce token ; au-delà, l'utilisateur doit se reconnecter, même si l'IdP accepte toujours le jeton de rafraîchissement.

### Revalidation dans les sessions en cours

Tant que Devin Desktop (ou tout autre client de l'agent intégré) est en cours d'exécution, l'agent revérifie la connexion toutes les **60 secondes** et force une actualisation du token auprès de l'IdP au moins toutes les **15 minutes**. En cas d'échec d'une vérification, l'agent consigne un événement d'audit `sso_revalidation_failed` avec le code `IDP`, cesse d'accepter de nouvelles tâches, puis s'arrête ; l'utilisateur doit alors se reconnecter et le relancer.

## Éléments audités

L’activité SSO est consignée dans le [journal d’audit](/fr/federal/air-gapped/on-disk-formats#audit-log) local sous forme d’événements `auth`. Tout événement associé à un token validé inclut l’identité SSO dans `actor` (`sso_issuer`, `sso_subject`, `sso_user`, `sso_groups`).

| `action` | Quand |
| - | - |
| `sso_login` | Connexion réussie (`devin auth login` ou Desktop). |
| `sso_login_denied` | Connexion refusée après la réponse de l’IdP : le groupe obligatoire est absent (`error_code: "IDP004"`), ou l’ID token renvoyé n’a pas passé la validation ou était absent (`IDP005`). `actor` contient l’identité attestée par l’IdP ; rien n’est mis en cache. |
| `sso_refresh` | Jetons actualisés auprès de l’IdP. |
| `sso_logout` | `devin auth logout` ou déconnexion depuis Desktop. |
| `sso_revalidation_failed` | Un agent en cours d’exécution a perdu sa connexion et s’arrête ; `error_code` contient le code `IDP`. |

## Codes d’erreur IDP

| Code | Signification | Que faire |
| - | - | - |
| `IDP001` | Le fichier d’authentification est illisible ou invalide. | Corrigez `/etc/devin/auth.json` (ou le chemin défini par `DEVIN_AUTH_FILE`) ; le message indique le champ en cause. |
| `IDP002` | Aucune connexion en cache pour l’émetteur configuré. | Exécutez `devin auth login`. |
| `IDP003` | La connexion est invalide ou a expiré, et n’a pas pu être actualisée de manière transparente (y compris en cas de réponse `invalid_grant` de l’IdP). | Exécutez à nouveau `devin auth login`. |
| `IDP004` | L’utilisateur est connecté, mais n’est pas membre de `required_group`. | Ajoutez l’utilisateur au groupe dans l’IdP, ou corrigez `required_group` / `groups_claim`. |
| `IDP005` | L’IdP est injoignable ou a renvoyé une erreur. | Vérifiez l’accessibilité réseau, la confiance TLS (`DEVIN_CA_BUNDLE`) et les logs de l’IdP. |
| `IDP006` | Le cache local des tokens SSO est illisible, mal formé ou n’est pas réservé à l’utilisateur actuel. | Exécutez `devin auth login` ; une nouvelle connexion réécrit le cache. |

Le catalogue complet est disponible sur la page [Codes d’erreur](/fr/federal/air-gapped/error-codes).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.