Connect with Spunto

Connectez les utilisateurs à votre app avec leur compte Spunto — OAuth 2 en authorization code avec PKCE, et qui ils sont dans quelles organisations.

Spunto est un fournisseur OAuth 2 pour ses apps. « Connect with Spunto » indique à votre app qui est un membre, à quelles organisations il appartient, et avec quel rôle — de quoi montrer à chaque membre ce qui appartient à son organisation, et ne laisser que les owners et les admins le modifier.

C’est ce qu’utilise la page où une organisation gère ses propres machines : cette page vit sur le domaine de l’app, pas dans le dashboard, et a besoin de savoir qui la regarde.

FluxAuthorization code, PKCE S256 obligatoire
client_idL’id de votre app, tiré de son manifeste
client_secretLe secret de signature de votre app — le seul secret que vous partagez déjà avec Spunto
URI de redirectionCelles que votre manifeste déclare dans oauth.redirectUris, comparées à l’identique. HTTPS uniquement (http est accepté pour localhost). Une fois l’app publiée, seulement celles qui ont été revues
Qui peut se connecterTant que votre app n’est pas publiée, seulement les membres de l’organisation qui l’a enregistrée
Scopesidentity
Access tokenOpaque (spo_…), valable 1 heure. Pas de refresh token

1

Envoyez l’utilisateur chez Spunto

Générez un code_verifier et un state, gardez-les tous les deux (un cookie signé de courte durée fait l’affaire), et redirigez :

https://spunto.net/api/oauth/authorize
  ?response_type=code
  &client_id=acme-git
  &redirect_uri=https%3A%2F%2Fgit.acme.dev%2Fspunto%2Foauth%2Fcallback
  &scope=identity
  &state=…
  &code_challenge=BASE64URL(SHA256(code_verifier))
  &code_challenge_method=S256

Un utilisateur qui n’est pas connecté à Spunto se connecte d’abord. La première fois, il voit un écran de consentement ; ensuite, le consentement est mémorisé pour votre app et ces scopes, et il revient directement.

2

Récupérez le code

Spunto redirige vers votre redirect_uri avec ?code=…&state=…. Vérifiez state. Le code est valable 60 secondes et ne sert qu’une fois.

3

Échangez-le, de serveur à serveur

curl -X POST https://spunto.net/api/oauth/token \
  -d grant_type=authorization_code \
  -d code=… \
  -d redirect_uri=https://git.acme.dev/spunto/oauth/callback \
  -d code_verifier=… \
  -d client_id=acme-git \
  -d client_secret=…

En form-encoded ou en JSON ; les identifiants du client peuvent aussi passer dans un en-tête HTTP Basic.

{ "access_token": "spo_…", "token_type": "Bearer", "expires_in": 3600, "scope": "identity" }
4

Demandez de qui il s’agit

curl https://spunto.net/api/oauth/userinfo -H "Authorization: Bearer spo_…"
{
  "sub": "usr_…",
  "name": "Ada Lovelace",
  "email": "ada@acme.dev",
  "picture": "https://…",
  "orgs": [{ "id": "org_…", "name": "Acme", "slug": "acme", "role": "admin" }]
}

Ouvrez ensuite votre propre session — un cookie sur votre domaine — avec ce qu’a dit userinfo. Quand elle expire, relancez le flux : le consentement étant mémorisé, cela ne coûte aucun clic à l’utilisateur.

  • Une erreur sur une URI de redirection inconnue n’est pas redirigée. Si la redirect_uri ne fait pas partie de celles que déclare votre manifeste, Spunto affiche l’erreur lui-même plutôt que d’envoyer le navigateur vers une adresse dont il ne peut pas se porter garant.
  • Un rôle lu à la connexion est le rôle au moment de la connexion. Si un admin est rétrogradé, votre app l’apprend à sa connexion suivante. Gardez des sessions courtes si cela compte pour vous.
  • org.id est le même id que celui que Spunto envoie dans chaque appel de capability — c’est ainsi que vous rapprochez un membre connecté des installations de son organisation.
  • Servez vos pages sur votre propre origine. OAuth n’a de sens qu’entre origines distinctes ; ne montez jamais les pages de votre app sous le domaine de Spunto.
  • Une clé d’API ne peut pas donner son consentement. Seul un membre connecté au dashboard peut consentir ; une clé spk_ est refusée.

Note

identity n’agit sur rien — il dit seulement qui est l’utilisateur. Les scopes qui permettront à une app d’agir sur Spunto au nom de l’utilisateur (lire ses sandboxes, par exemple) utiliseront les mêmes tokens quand ils arriveront. D’ici là, une app qui doit appeler l’API de Spunto le fait avec une clé d’API que l’organisation lui confie.