Authentification de vos applications
Fonctionnalité déployée et prise en charge. Les champs et commandes décrits ici sont stables au sein de la version v1alpha1.
Vos applications peuvent confier la connexion de leurs utilisateurs à StackNGO : vous déclarez une application OIDC en YAML, StackNGO crée le client OAuth2 et met à disposition clientId, clientSecret et issuer, prêts à être passés à votre App. Vos utilisateurs se connectent sur une page aux couleurs de votre organisation (Page de connexion), sans mot de passe (Fournisseurs de connexion), et votre application reçoit un jeton OIDC standard.
apiVersion: iam.stackngo.io/v1alpha1
kind: IAMApplication
metadata:
name: billing-api
spec:
directory: tenant # les utilisateurs de VOS applications
displayName: Billing API
redirectURLs:
- https://billing-api.acme.dev.stackngo.app/auth/callback
grantTypes: [authorization_code, refresh_token]
scopes: [openid, profile, email]
sng apply billing-api.yml
Quelques instants plus tard, les identifiants billing-api-oidc sont prêts à être utilisés par votre App.
Deux annuaires, deux émetteurs
Le champ directory choisit qui se connecte à l'application :
directory | Qui se connecte | Émetteur |
|---|---|---|
tenant | les utilisateurs de vos applications (annuaire du tenant) | un émetteur propre à votre tenant : https://auth.dev.stackngo.fr/t/acme |
platform (défaut) | les membres de votre tenant sur StackNGO (outils internes, identités machine) | l'émetteur de la plateforme |
Pour une application destinée à vos clients, mettez toujours directory: tenant. Le champ ne change plus après la création : pour changer d'annuaire, créez une autre application. Il est incompatible avec le scope urn:stackngo:introspect.
Un jeton émis pour l'annuaire de votre tenant n'est valable que pour lui : il est refusé par l'API StackNGO et par l'émetteur d'un autre tenant.
Prérequis
- Une session sur le tenant :
sng tenant use acme. deploy:write(policyreadwriteouadmin).
Étapes
1. Générer et compléter le manifeste
sng template gen IAMApplication billing-api > billing-api.yml
Ajoutez directory: tenant sous spec si le gabarit ne l'a pas. Les champs utiles :
| Champ | Rôle | Remarques |
|---|---|---|
directory | quels utilisateurs se connectent | tenant ou platform (défaut) ; non modifiable |
displayName | nom affiché sur l'écran de connexion | 256 caractères max |
homeURL | page d'accueil de l'application | HTTPS ; pas d'adresse locale ni privée |
redirectURLs | URL de retour OAuth2 | HTTPS, sauf http://127.0.0.1 / http://localhost pour une application native ou une CLI ; 32 max |
postLogoutRedirectURLs | adresses admises après une déconnexion | mêmes règles ; sans elles, la déconnexion ne redirige pas |
grantTypes | flux autorisés | authorization_code, refresh_token, client_credentials ; 16 max |
scopes | scopes proposés | openid, profile, email… ; 32 max |
public | client public (application native, CLI) | PKCE obligatoire, aucun secret |
token.expireInHours | durée du jeton d'accès | 1 à 8760 ; 168 h si omis (0 interdit) |
token.refreshExpireInHours | durée du jeton de rafraîchissement | 168 si refresh_token est dans grantTypes ; 0 interdit avec refresh_token |
credentialsSecret.name | nom sous lequel les identifiants sont mis à disposition de vos App | <nom>-oidc par défaut |
deletionPolicy | Block (défaut), Orphan, Delete | voir Limites |
2. Appliquer
sng apply billing-api.yml
IAMApplication/billing-api created
La console (section Authentification, page Applications) propose le même formulaire, déjà prérempli avec directory: tenant, et indique les applications qui connectent vos utilisateurs.
3. Utiliser les identifiants
Quelques instants après l'application, les identifiants sont prêts sous le nom billing-api-oidc (ou celui de credentialsSecret.name), avec trois clés :
| Clé | Contenu |
|---|---|
clientId | identifiant client OAuth2 |
clientSecret | secret client |
issuer | URL de l'émetteur OIDC de votre tenant (https://auth.dev.stackngo.fr/t/acme) |
Référencez-les dans votre App comme un secret :
apiVersion: deploy.stackngo.io/v1alpha1
kind: App
metadata:
name: billing-api
spec:
services:
api:
image: ovh-gra-0.registry.dev.stackngo.fr/acme/billing-api:1.0.0
ports: ["8080"]
ingress: { port: 8080 }
env:
OIDC_ISSUER: { secret: billing-api-oidc, key: issuer }
OIDC_CLIENT_ID: { secret: billing-api-oidc, key: clientId }
OIDC_CLIENT_SECRET: { secret: billing-api-oidc, key: clientSecret }
La découverte OIDC est servie sous <issuer>/.well-known/openid-configuration : n'importe quelle bibliothèque OIDC s'en contente.
Pour une application qui ne tourne pas sur la plateforme, lisez les identifiants avec sng iam app credentials billing-api (action auth:ReadCredentials, policy admin).
4. Ce que contient le jeton
Le jeton d'identité (ID token) et le jeton d'accès sont des JWT signés (RS256). Pour un utilisateur de votre annuaire, ils portent :
| Claim | Contenu |
|---|---|
iss | l'émetteur de votre tenant |
sub | identifiant stable du compte (le même que dans sng iam user list) |
email, email_verified | adresse du compte (avec le scope email) |
tenant | le nom de votre tenant |
directory | tenant |
roles | les rôles du compte (absent s'il n'en a pas) |
permissions | l'ensemble des permissions de ses rôles (absent s'il n'y en a pas) |
Les jetons n'indiquent jamais les autres tenants dont une personne pourrait être membre.
5. Vérifier le jeton côté application
Votre application doit vérifier la signature (clés publiques annoncées par la découverte), l'émetteur (iss égal à issuer), l'audience (aud égal à votre clientId) et l'expiration, puis lire roles et permissions. Exemple en Go avec go-oidc :
provider, err := oidc.NewProvider(ctx, os.Getenv("OIDC_ISSUER"))
if err != nil { log.Fatal(err) }
verifier := provider.Verifier(&oidc.Config{ClientID: os.Getenv("OIDC_CLIENT_ID")})
idToken, err := verifier.Verify(ctx, rawIDToken) // signature, iss, aud, exp
if err != nil { /* refuser : 401 */ }
var claims struct {
Subject string `json:"sub"`
Email string `json:"email"`
Roles []string `json:"roles"`
Permissions []string `json:"permissions"`
}
if err := idToken.Claims(&claims); err != nil { /* refuser */ }
if !slices.Contains(claims.Permissions, "tickets:reply") { /* 403 */ }
Les permissions sont celles que vous avez définies dans vos rôles ; elles sont vérifiées par votre code.
6. Renouveler le secret
Pour changer le clientSecret, renouvelez-le depuis la console (Renouveler le secret, dans Authentification > Applications) ou avec la CLI. Le nouveau secret est écrit dans billing-api-oidc ; le clientId ne change pas.
sng iam app rotate billing-api
sng iam app credentials billing-api
L'ancien secret est refusé dès que le renouvellement est traité, en quelques secondes : redémarrez ensuite les applications qui lisent le secret. Ce renouvellement est réservé aux administrateurs du tenant.
Vérification
sng iam app list
sng kind get IAMApplication billing-api
L'application apparaît avec l'annuaire « Utilisateurs de vos applications » et Ready: True. Puis, depuis votre application, lancez un flux authorization_code vers le point d'autorisation annoncé par la découverte de l'émetteur avec le clientId : la page de connexion de votre organisation s'affiche.
Limites
- Si l'application n'apparaît toujours pas dans
sng iam app listaprès quelques minutes, l'annuaire de votre tenant n'est peut-être pas encore activé : contactez le support. deletionPolicy: Block(défaut) retarde la suppression d'une application encore utilisée, puis la supprime dès qu'elle ne l'est plus. Une application supprimée peut être recréée sous le même nom, avec de nouveaux identifiants.- Les applications
directory: tenantn'ont pas accès à l'API StackNGO : leurs jetons n'y ouvrent aucune session.
Pour aller plus loin
- Une
IAMApplicationavec le fluxclient_credentialspeut servir d'identité machine pour appeler l'API StackNGO : voir Identités machine. - Les applications de l'annuaire sont nommées de façon stable : renommer le manifeste crée une nouvelle application.