Documentation · Guides

Clés d’accès pour votre application.

Connexion par clé d’accès pour votre propre application, sans bâtir de base de données d’utilisateurs. Canner conserve la fiche d’utilisateur et la clé publique; votre application vérifie un jeton signé et ne stocke rien.

Les clés d’accès remplacent les mots de passe par l’empreinte, le visage ou le NIP que vos utilisateurs emploient déjà pour déverrouiller leur téléphone. Rien à retenir, rien à réinitialiser et — puisque la clé privée ne quitte jamais l’appareil — rien à dérober dans votre base de données.

Canner Auth vous offre cela sans le coût habituel d’exploitation. Vous obtenez une API; nous gardons les identifiants. Votre serveur n’interroge jamais une table d’utilisateurs, parce qu’elle n’existe pas : il vérifie un jeton signé de courte durée avec une clé publique, comme il le ferait pour n’importe quel JWT.

Comment tout s’articule

Une application Canner Authest l’unité de configuration. Elle appartient à votre compte Canner, est liée à un seul domaine et produit deux clés :

  • une clé publiable (cnr_auth_pk_…) destinée à votre code côté client. Ce n’est pas un secret : elle ne fonctionne que depuis les origines que vous autorisez, sa publication ne coûte donc rien.
  • une clé secrète (cnr_auth_sk_…) pour votre serveur, sur les forfaits payants. Elle gère les utilisateurs finaux et émet des billets d’inscription, et ne doit jamais atteindre un navigateur.

Avant de commencer

Créez une application à Identité → Clé d’accès. Deux conditions d’abord, au sujet de votre compte Canner : son courriel est vérifié et vous y avez ajouté une clé d’accès. La seconde est délibérée — le produit peut écrire à vos utilisateurs, et nous ne confions cette capacité qu’aux comptes ayant prouvé un appareil réel.

Déclarez ensuite les originesoù votre page de connexion est servie — la même idée qu’une liste d’URI de redirection OAuth. Votre application n’a pas à tourner chez Canner : inscrivez https://app.example.com et cela fonctionne où que ce soit hébergé. Rien à vérifier, aucun DNS à modifier.

De ces origines nous déduisons la portée— le domaine auquel vos clés d’accès sont liées. Une seule origine donne la portée la plus étroite : déclarez https://app.example.comet les identifiants fonctionnent sur ce sous-domaine et nulle part ailleurs. Plusieurs origines élargissent la portée à leur parent commun, car une clé d’accès doit être valide sur chaque origine qui l’utilise.

La portée est permanente.Elle est inscrite dans chaque identifiant à sa création : déplacer plus tard une application vers un sous-domaine voisin rend inutilisables toutes les clés inscrites sur l’ancien. Élargissez délibérément dès la configuration si vous prévoyez de bouger; le formulaire de création le propose.

Seule exception : votre-projet.canner.app. Les applications sur notre propre domaine locataire doivent appartenir à un projet de votre organisation. Nous y hébergeons de nombreux clients qui ne se font pas mutuellement confiance — c’est le seul cas où une revendication de domaine mérite d’être vérifiée.

1 — Demander un courriel

L’inscription commence par une adresse. Nous envoyons un lien de confirmation et renvoyons la même réponse dans tous les cas : votre formulaire ne peut donc jamais servir à découvrir quelles adresses ont un compte.

// 1. Ask for an email. We send a confirmation link.
await fetch("https://api.canner.ca/v1/auth/register/start", {
  method: "POST",
  headers: {
    authorization: `Bearer ${process.env.NEXT_PUBLIC_CANNER_AUTH_PUBLISHABLE_KEY}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({ email }),
});
// The response is always { ok: true } — it never reveals whether the
// address already has an account.

2 — Associer une clé d’accès

Le lien envoyé par courriel ramène l’utilisateur sur votrepage avec un jeton à usage unique dans l’URL. Ce n’est pas un détail modifiable : une clé d’accès ne peut être créée que sur votre propre domaine, cette étape doit donc s’y dérouler. Indiquez la page d’arrivée sous Le lien courriel arrive sur — toute URL sur une de vos origines autorisées.

import { startRegistration } from "@simplewebauthn/browser";

// 2. The user clicks the emailed link and lands back on YOUR page with
//    ?canner_auth_token=… in the URL. Bind the passkey here.
const token = new URLSearchParams(location.search).get("canner_auth_token");

const { options, challenge_id } = await api("/v1/auth/register/options", { token });
const attestation = await startRegistration({ optionsJSON: options });

const { token: jwt } = await api("/v1/auth/register/verify", {
  token, challenge_id, response: attestation,
});

3 — Se connecter

La connexion ne demande aucun identifiant. Le navigateur propose la clé d’accès qu’il détient pour votre domaine, et l’assertion nous indique à qui elle appartient.

import { startAuthentication } from "@simplewebauthn/browser";

// No email, no password, no identifier — the browser offers whichever
// passkey it holds for your domain.
const { options, challenge_id } = await api("/v1/auth/login/options", {});
const assertion = await startAuthentication({ optionsJSON: options });

const { token, expires_in, user_id } = await api("/v1/auth/login/verify", {
  challenge_id, response: assertion,
});

4 — Vérifier le jeton côté serveur

C’est ici que « sans base de données » devient concret. Le jeton est un JWT ES256 standard; vérifiez-le avec n’importe quelle bibliothèque JWT à partir du JWKS public. Aucun appel vers nous, aucune recherche d’utilisateur, aucune table de sessions.

import { createRemoteJWKSet, jwtVerify } from "jose";

// Injected into your project automatically when the app is attached.
const JWKS = createRemoteJWKSet(new URL(process.env.CANNER_AUTH_JWKS_URL!));

export async function currentUser(req: Request) {
  const token = req.headers.get("authorization")?.replace("Bearer ", "");
  if (!token) return null;

  const { payload } = await jwtVerify(token, JWKS, {
    issuer: process.env.CANNER_AUTH_ISSUER,
    audience: process.env.CANNER_AUTH_APP_ID,
  });
  return { id: payload.sub, email: payload.email };
}

Votre application a besoin de quatre identifiants pour cela. Attachez l’application Canner Auth à un projet et ils arrivent automatiquement dans son environnement au prochain déploiement — rien à recopier d’un tableau de bord à l’autre :

CANNER_AUTH_APP_ID=…
CANNER_AUTH_PUBLISHABLE_KEY=cnr_auth_pk_…
CANNER_AUTH_ISSUER=https://auth.canner.app/apps/…
CANNER_AUTH_JWKS_URL=https://auth.canner.app/apps/…/.well-known/jwks.json

L’attachement est facultatif et réversible : il ne concerne que la livraison de ces valeurs. Si votre application tourne ailleurs, ou que vous préférez gérer sa configuration vous-même, laissez-la détachée et définissez les quatre valeurs à la main — la connexion se comporte exactement pareil.

Dans les deux cas, la clé secrète n’est jamais injectée, car les variables d’environnement de compilation se retrouvent dans le paquet client de la plupart des cadriciels.

Applications sans interface et utilisateurs opaques

Si vos utilisateurs ne sont pas identifiés par courriel, sautez entièrement l’étape du courriel. Votre serveur appelle /v1/auth/tickets avec la clé secrète et son propre external_id, puis remet le billet obtenu à votre interface pour l’inscription. C’est votre application qui décide qui peut s’inscrire — la bonne place pour cette décision — car une clé publiable seule ne peut jamais associer une clé d’accès à un identifiant.

Une application configurée ainsi n’envoie aucun courriel, ce qui est le meilleur résultat possible pour la délivrabilité de tous.

Courriels

Tous les forfaits peuvent choisir la langue— français ou anglais — sous Identité → Clé d’accès. Passez localeà l’appel de connexion pour la définir par utilisateur; sinon le réglage de l’application s’applique. La localisation n’est pas une fonction payante : le texte reste le nôtre, simplement dans la langue du lecteur.

Les forfaits payants peuvent ajouter un logo et une adresse de soutien, et envoyer depuis leur propre domaine vérifié— ajoutez le domaine, publiez les enregistrements DNS affichés, et l’expéditeur devient le vôtre.

Le texte personnalisé exige ce domaine vérifié. Sur auth.canner.app, l’objet et le corps restent les nôtres : cette adresse est partagée par toutes les applications de la plateforme et sa réputation n’appartient pas à un seul client. Dès que votre domaine signe le courriel, la réputation engagée est la vôtre et vous pouvez rédiger l’objet, le corps, le bouton et la note de chaque message, dans chaque langue, en laissant vide ce que vous voulez garder de nous.

La récupération remplace plutôt qu’elle n’ajoute : si toutes les clés d’accès sont perdues, les anciennes sont de toute façon inaccessibles, et les laisser en place signifierait qu’un appareil volé fonctionne encore après la récupération.

Réglages

Les forfaits payants peuvent modifier cinq valeurs par défaut. Toutes sont visibles sur tous les forfaits, et chacune fonctionne telle quelle.

RéglageDéfautPlage
Durée de vie du jeton15 min5 min – 24 h
Méthode de connexionN’importe laquelleN’importe laquelle · cet appareil · téléphone ou clé
Exiger un NIP ou une biométrieNonNon · toujours
Délai de connexion60 s30 – 300 s
Max de clés d’accès par utilisateur51 – 10

Deux points à retenir. Un jeton ne peut pas être révoqué avant terme : sa durée de vie est donc le temps pendant lequel un jeton volé fonctionnerait. Et « téléphone ou clé de sécurité » est l’option qui affiche le code QR intra-appareils à vos utilisateurs.

Forfaits

L’API de connexion est offerte sur tous les forfaits, y compris Démarrage— un projet gratuit peut faire de la vraie authentification par clé d’accès, avec 1 000 utilisateurs actifs mensuels. Live porte ce nombre à 125 000et ajoute l’API de gestion, les réglages ci-dessus, une allocation de courriels plus élevée et un domaine d’envoi personnalisé. Studio est sans plafond. Tableau complet : forfaits et limites.

Le plafond d’utilisateurs actifs mensuels ne s’applique qu’aux nouvellesinscriptions. L’atteindre arrête les inscriptions; toutes les personnes qui utilisent déjà votre application continuent de se connecter.