Aller au contenu principal

CORS et origines autorisées

Une clé publiable peut comporter une liste d’origines autorisées : les sites Web qui peuvent l’utiliser. Cette page explique où cette liste est vérifiée, ce que le navigateur affiche lorsqu’une vérification échoue et ce que cette liste ne protège pas.

Une origine comprend le schéma, l’hôte et le port d’une page, par exemple https://www.example.com ou http://localhost:3000. Elle ne comporte pas de chemin.

La liste est facultative​

Une clé publiable fonctionne avec une liste vide. Une liste vide signifie que toute origine peut utiliser la clé. C’est l’état d’une clé créée sans origines définies ; vous pouvez également vider la liste plus tard.

Ajoutez des origines avant de déployer une clé sur un site de production. Lorsqu’une liste est définie, une copie de votre clé collée dans la page Web d’un tiers ne fonctionne plus sur cette page. Les protections offertes, ainsi que leurs limites, sont expliquées ci-dessous.

Les clés serveur ignorent cette liste. Une clé serveur ne peut jamais être utilisée depuis un navigateur, quel que soit le contenu de sa liste.

Rédiger une entrée​

RègleExemple
Uniquement le schéma, l’hôte et, éventuellement, le port. Aucun chemin, paramètre de requête ni barre oblique finale.https://www.example.com, et non https://www.example.com/
https est obligatoire. http n’est accepté que pour localhost, 127.0.0.1 et [::1]. La page des clés API n’accepte pas [::1] ; définissez-le au moyen de l’API de gestion des clés.http://localhost:3000
La correspondance est exacte. Les caractères génériques ne sont pas admis et un sous-domaine est une origine distincte. Une entrée contenant * est enregistrée telle quelle et ne correspond à aucun site.https://example.com et https://www.example.com constituent deux entrées
Le port fait partie de l’origine. Omettez le port par défaut (443 pour https, 80 pour http).https://example.com, et non https://example.com:443
Jusqu’à 100 entrées par clé. Les doublons sont rejetés.

Les entrées sont enregistrées en minuscules, sans les ports par défaut, afin de correspondre aux valeurs envoyées par le navigateur.

Une page ouverte depuis le disque (file://) n’a pas d’origine que vous puissiez ajouter. Pendant le développement, servez la page depuis http://localhost.

Configurez la liste sur la page kaleidr.com/api-keys, ou avec allowed_origins dans l’API de gestion des clés.

Où la liste est vérifiée​

ÉtapeVérificationEn cas d’échec
1. Échange de sessionL’en-tête Origin de la requête doit figurer dans la liste de la clé, si celle-ci en possède une.403 origin_not_allowed. Aucune session n’est créée. Une requête sans en-tête Origin renvoie 403 origin_required.
2. Chaque appel d’exécutionUn jeton de session fonctionne uniquement depuis l’origine pour laquelle il a été émis.403 session_origin_mismatch.
3. Chaque appel d’exécutionL’origine de la session doit toujours figurer dans la liste de la clé.401. Retirer une origine d’une clé met fin aux sessions déjà émises pour celle-ci.
4. Requêtes de fond de carte avec cléL’éditeur intégré transmet votre clé publiable dans ses requêtes à https://tile.kaleidr.com pour le style, les sprites et les polices. Le site de la page doit figurer dans la liste de la clé pour que celle-ci soit reconnue.La requête est traitée comme si elle n’avait pas de clé et peut être refusée avec 429 tile_access_restricted.
5. RéponseL’API ajoute Access-Control-Allow-Origin uniquement si les identifiants sont valides et si l’origine est autorisée.Le navigateur empêche la page de lire la réponse.

L’étape 5 correspond au fonctionnement normal de CORS et explique pourquoi les échecs se présentent ainsi dans un navigateur.

Requête préliminaire (preflight)​

Avant un POST intersites contenant un corps JSON, le navigateur envoie une requête préliminaire OPTIONS. Kaleidr répond à chacune par 204 en renvoyant l’origine demandeuse, car une telle requête ne contient aucun identifiant et ne peut pas être vérifiée par rapport à une clé. C’est la requête réelle qui est soumise à la liste.

En-tête de la réponse préliminaireValeur
Access-Control-Allow-MethodsGET, POST, OPTIONS
Access-Control-Allow-HeadersAuthorization, Content-Type, Accept, X-Api-Key, X-Request-Id
Access-Control-Max-Age600

Toute requête qui envoie un autre en-tête échoue lors de la vérification préliminaire dans le navigateur. N’ajoutez pas d’en-têtes personnalisés aux appels effectués depuis une page.

Pour une réponse autorisée, l’API envoie aussi Access-Control-Expose-Headers: Retry-After, X-Request-Id, afin que le code de la page puisse lire ces deux en-têtes. Elle n’envoie jamais Access-Control-Allow-Credentials : l’API n’utilise pas de cookies.

Ce qui se produit lorsqu’une origine est refusée​

Lorsque l’origine ou l’identifiant est refusé, la réponse ne comporte pas l’en-tête Access-Control-Allow-Origin. Le navigateur masque alors la réponse à votre code. La page ne voit donc pas le corps de la réponse 401 ou 403 ; elle reçoit une erreur réseau.

Dans la console :

Access to fetch at 'https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions' from origin
'https://www.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
on the requested resource.

suivi d’une erreur du SDK contenant [kaleidr:chat] (ou le nom du produit que vous avez monté). Rien ne s’affiche.

Pour trouver la cause réelle, ouvrez l’onglet Réseau du navigateur, sélectionnez la requête sessions, puis consultez son statut et sa réponse :

Statut et code dans l’onglet RéseauCauseSolution
403 origin_not_allowedL’origine de cette page ne figure pas dans la liste de la clé.Ajoutez exactement l’origine indiquée dans l’en-tête Origin de la requête.
401 Invalid or missing API keyLa clé est mal saisie, révoquée ou expirée.Vérifiez la clé sur la page des clés API.
403 server_key_in_browserUne clé serveur a été envoyée depuis une page.Utilisez une clé publiable dans la page. Effectuez une rotation de la clé serveur.
403 session_origin_mismatchUn jeton de session a été utilisé depuis une autre origine que celle qui l’a demandé.Effectuez l’échange de session depuis la page qui l’utilise.
Échec de la requête préliminaire, aucun POST visibleLa requête a envoyé un en-tête qui ne figure pas dans la liste autorisée.Supprimez l’en-tête personnalisé.

Une fois les identifiants et l’origine acceptés, les erreurs ultérieures sont lisibles par la page et ne produisent pas d’erreur CORS. Une clé valide pour cette origine, mais non autorisée pour ce produit, fait échouer l’échange avec un 403 lisible (product_not_allowed, insufficient_scope ou tier_capability_not_allowed), et le SDK inscrit kaleidr session exchange failed (403) dans les journaux. Une réponse 429 pour une session valide arrive avec son corps et son en-tête Retry-After. Ces codes sont expliqués dans Authentification et portées.

La même requête lancée depuis un terminal ne produit jamais d’erreur CORS, car CORS est une règle du navigateur. curl permet donc de vérifier rapidement un couple clé-origine :

curl -i https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions \
-H "X-Api-Key: kld_pk_live_…" \
-H "Origin: https://www.example.com" \
-H "Content-Type: application/json" \
-d '{"product":"chat"}'

Une origine autorisée renvoie 200 avec access-control-allow-origin: https://www.example.com. Une origine refusée renvoie 403 {"detail":"origin_not_allowed"} sans cet en-tête.

Pourquoi une clé serveur est refusée dans un navigateur​

Une clé serveur est un secret permanent. Quiconque la possède peut appeler l’API au nom de votre organisation jusqu’à sa révocation. Le code source d’une page étant public, une clé serveur intégrée à une page est une clé divulguée.

Kaleidr la refuse à trois niveaux :

  1. Le SDK refuse une clé kld_sk_… au montage, avec une erreur dans la console et sans requête réseau.
  2. L’API répond 403 server_key_in_browser à toute requête avec clé serveur contenant un en-tête Origin.
  3. La réponse ne comporte aucun en-tête CORS ; le code de la page ne pourrait donc pas la lire de toute façon.

Aucun de ces mécanismes n’annule la fuite. CORS bloque la réponse, pas la requête : lorsque l’API refuse celle-ci, la clé a déjà été envoyée et peut être vue par toute personne consultant la page. Si une clé serveur a figuré dans une page, effectuez sa rotation.

La liste ne protège pas un secret​

Les navigateurs définissent honnêtement l’en-tête Origin, mais rien n’impose cette honnêteté aux autres clients. Un script, un outil en ligne de commande ou un serveur peut envoyer l’en-tête Origin qu’il souhaite, comme dans l’exemple curl ci-dessus. Par conséquent :

  • La liste empêche les autres sites Web d’utiliser votre clé dans les navigateurs de leurs visiteurs. C’est sa fonction, et elle la remplit efficacement.
  • La liste n’arrête pas un appelant déterminé qui copie votre clé publiable et envoie des requêtes avec votre origine depuis un environnement autre qu’un navigateur.

Tenez-en compte : considérez que tout ce qu’une clé publiable permet de consulter est accessible à quiconque peut lire votre page :

  • Limitez l’exposition de votre quota au moyen d’un plafond mensuel par clé et de sa limite de débit. Voir Quotas et limites de débit.
  • N’accordez pas la portée vendor à une clé publiable sauf si les données qu’elle permet de lire sont des données que vous accepteriez de publier sur cette page. Voir Authentification et portées.
  • Utilisez une clé par site Web afin de pouvoir en révoquer une sans perturber les autres.

Le modèle de sécurité présente une vue plus complète.

Identifiants dans les URL​

Les appels à l’API de la plateforme transmettent l’identifiant dans un en-tête, jamais dans une URL. Les requêtes de fond de carte effectuées par les intégrations Kaleidr constituent la seule exception : elles incluent un identifiant de navigateur dans l’URL de la requête, où il peut apparaître dans l’historique du navigateur et les journaux réseau. Cela est acceptable pour un identifiant publiable, qui est déjà public, mais jamais pour une clé serveur. Ne placez kld_sk_… dans aucune URL.

Modifier la liste​

  • Ajouter une origine prend effet lors du prochain échange de session depuis cette origine. Les requêtes de fond de carte peuvent nécessiter quelques minutes pour prendre en compte le changement.
  • Supprimer une origine refuse les nouveaux échanges provenant de celle-ci et met fin à ses sessions existantes à leur prochaine requête.
  • Vider la liste rétablit l’autorisation de « toute origine ».

Pages connexes​