
# Points de terminaison OAuth 2.0 et OpenID Connect

> **Statut : `planned`.** Cette page décrit la surface du protocole de chaque environnement KeenAuth telle que spécifiée dans le plan (§13). Les points de terminaison sont en cours de développement pendant la phase 2 et ne sont pas encore disponibles dans un environnement hébergé. Les détails peuvent encore changer avant la disponibilité générale.

Chaque environnement est son propre serveur d'autorisation OAuth 2.0 et son propre fournisseur OpenID Connect. Les points de terminaison ne font pas partie de l'API de gestion : ils se trouvent sur l'hôte de l'environnement, `https://<environment-slug>.<region>.keenauth.app`, ou sur votre domaine personnalisé vérifié. Dans le tableau, `<issuer>` désigne l'émetteur de l'environnement, c'est-à-dire la valeur de `issuer` dans le document de découverte.

## Points de terminaison

| Point de terminaison | Méthode et chemin | Authentification du client |
|---|---|---|
| Découverte | `GET <issuer>/.well-known/openid-configuration` et `GET <issuer>/.well-known/oauth-authorization-server` (RFC 8414, contenu identique) | Aucune |
| Clés | `GET <issuer>/.well-known/jwks.json` | Aucune |
| Autorisation | `GET` ou `POST <login host>/oauth2/authorize` | Aucune (navigateur) |
| Requête d'autorisation poussée (RFC 9126) | `POST <issuer>/oauth2/par` | Requise pour les clients confidentiels ; `client_id` pour les clients publics |
| Jeton | `POST <issuer>/oauth2/token` | Requise pour les clients confidentiels ; `client_id` pour les clients publics (DPoP est facultatif) |
| Autorisation d'appareil (RFC 8628) | `POST <issuer>/oauth2/device_authorization` | Identique au point de terminaison de jeton |
| Révocation (RFC 7009) | `POST <issuer>/oauth2/revoke` | Identique au point de terminaison de jeton |
| Introspection (RFC 7662) | `POST <issuer>/oauth2/introspect` | Client confidentiel uniquement |
| UserInfo | `GET` ou `POST <issuer>/oauth2/userinfo` | Jeton d'accès Bearer ou DPoP |
| Fin de session | `GET` ou `POST <login host>/oauth2/logout` | Aucune (`id_token_hint` ou `client_id`) |

`<login host>` désigne n'importe quel domaine de connexion de l'environnement : l'hôte par défaut ou un domaine personnalisé ajouté. Le document de découverte n'est servi que sur l'hôte de l'émetteur. Sur un autre hôte de connexion, `/.well-known/openid-configuration` renvoie `404` avec l'URL de l'émetteur dans le corps de la réponse.

## Types d'autorisation

| Type | Utilisation |
|---|---|
| `authorization_code` | Connexion depuis un navigateur et des applications natives. PKCE avec `S256` est requis. |
| `refresh_token` | Renouvelle les jetons. Chaque utilisation fait tourner le jeton de rafraîchissement, et la réutilisation d'un ancien jeton révoque toute la famille de jetons. |
| `client_credentials` | Accès de machine à machine. |
| `urn:ietf:params:oauth:grant-type:device_code` | Appareils sans clavier, comme une télévision ou un outil en ligne de commande. |
| `urn:ietf:params:oauth:grant-type:token-exchange` | Délégation et usurpation d'identité entre services. |

Les flux implicites (`response_type=token` et tout ce qui contient `id_token`), le type d'autorisation par identifiants du propriétaire des ressources (resource owner password credentials) et les types de réponse hybrides ne sont pas pris en charge, ni maintenant ni plus tard. La RFC 9700 interdit les deux premiers.

## Autorisation d'appareil

Un appareil sans navigateur démarre le flux avec `POST <issuer>/oauth2/device_authorization`. Seules les applications de type `device` ou `native` qui listent explicitement le type d'autorisation par appareil peuvent l'utiliser. La réponse contient un `device_code`, un `user_code` et une adresse de vérification. L'utilisateur ouvre cette adresse sur un autre appareil, se connecte et approuve. Pendant ce temps, l'appareil interroge le point de terminaison de jeton avec `grant_type=urn:ietf:params:oauth:grant-type:device_code`. Le `user_code` comporte 8 caractères et s'affiche sous la forme `XXXX-XXXX`. Un code d'appareil est valide pendant 10 minutes et ne fonctionne qu'une fois. L'appareil interroge au maximum toutes les 5 secondes ; une interrogation plus rapide reçoit la réponse `slow_down`, qui ajoute 5 secondes à l'intervalle. Le `verification_uri` est `https://<login host>/u/device`, et l'utilisateur voit l'application, les étendues demandées et le pays de l'appareil ayant lancé la demande avant d'approuver.

## Règles de sécurité

L'environnement respecte sans exception les meilleures pratiques actuelles de sécurité d'OAuth 2.0 (RFC 9700) :

- L'URI de redirection doit correspondre octet pour octet à un URI enregistré. Les caractères génériques ne sont pas autorisés.
- PKCE n'accepte que `S256` ; `plain` est toujours rejeté. PKCE est requis pour les clients publics et activé par défaut pour chaque application. Une application `web` confidentielle peut le désactiver dans ses paramètres, et seulement si l'environnement exige encore `nonce` dans ce cas.
- Les SDK officiels envoient un `state` de 128 bits et un `nonce`, et vérifient les deux au retour.
- Un code d'autorisation est valide pendant 60 secondes et ne fonctionne qu'une fois. Présenter un code déjà utilisé renvoie `invalid_grant` et révoque les jetons de rafraîchissement ainsi que le jeton d'accès produits par la première utilisation.
- Les requêtes d'autorisation poussées gardent les paramètres de la requête hors de la barre d'adresse du navigateur. Elles sont disponibles sur tous les forfaits, et le paramètre `require_par` les rend obligatoires pour une application ou pour l'environnement entier.
- Les jetons de rafraîchissement tournent à chaque utilisation, et la détection de réutilisation révoque la famille.
- DPoP (RFC 9449) lie un jeton d'accès à une clé détenue par le client. Pour vérifier les jetons liés dans votre API, consultez [Vérifier les jetons dans votre API](/docs/sdk/token-verification).

## Sessions et déconnexion

Après une connexion réussie, l'environnement conserve une session d'authentification unique dans un cookie `HttpOnly` sur l'hôte de connexion. Les applications du même environnement la réutilisent, de sorte qu'une deuxième application ne demande pas de nouveau mot de passe, sauf si sa politique exige une authentification plus forte ou plus récente. Votre code ne voit jamais le cookie : il ne voit que la réponse d'autorisation.

Le point de terminaison de fin de session (OpenID Connect RP-Initiated Logout 1.0) met fin à cette session, révoque les jetons de rafraîchissement qui lui appartiennent et notifie les applications ayant enregistré une adresse de déconnexion back-channel. Pour lister ou révoquer les sessions d'un utilisateur depuis votre backend, utilisez les [points de terminaison de session de l'API de gestion](/docs/api/management/users/list-sessions).

Si l'utilisateur s'est connecté via une connexion d'entreprise, ajoutez `federated=true` à la requête de fin de session pour le déconnecter également chez son fournisseur d'identité. La session est d'abord terminée ici ; le navigateur se rend ensuite à la déconnexion du fournisseur d'identité (déconnexion unique SAML, ou point de terminaison de fin de session du fournisseur OpenID) et revient vers le `post_logout_redirect_uri`. Cela n'a lieu que si la connexion a la déconnexion au fournisseur d'identité activée et si le fournisseur publie une adresse de déconnexion. Sinon, ou si le fournisseur est injoignable, la requête fonctionne comme sans ce paramètre. La déconnexion chez le fournisseur d'identité peut aussi mettre fin aux autres applications de l'utilisateur qui l'utilisent.
