Aller au contenu principal

Authentification de vos applications

Disponible

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.

billing-api.yml
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 :

directoryQui se connecteÉmetteur
tenantles 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 (policy readwrite ou admin).

É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 :

ChampRôleRemarques
directoryquels utilisateurs se connectenttenant ou platform (défaut) ; non modifiable
displayNamenom affiché sur l'écran de connexion256 caractères max
homeURLpage d'accueil de l'applicationHTTPS ; pas d'adresse locale ni privée
redirectURLsURL de retour OAuth2HTTPS, sauf http://127.0.0.1 / http://localhost pour une application native ou une CLI ; 32 max
postLogoutRedirectURLsadresses admises après une déconnexionmêmes règles ; sans elles, la déconnexion ne redirige pas
grantTypesflux autorisésauthorization_code, refresh_token, client_credentials ; 16 max
scopesscopes proposésopenid, profile, email… ; 32 max
publicclient public (application native, CLI)PKCE obligatoire, aucun secret
token.expireInHoursdurée du jeton d'accès1 à 8760 ; 168 h si omis (0 interdit)
token.refreshExpireInHoursdurée du jeton de rafraîchissement168 si refresh_token est dans grantTypes ; 0 interdit avec refresh_token
credentialsSecret.namenom sous lequel les identifiants sont mis à disposition de vos App<nom>-oidc par défaut
deletionPolicyBlock (défaut), Orphan, Deletevoir 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
clientIdidentifiant client OAuth2
clientSecretsecret client
issuerURL de l'émetteur OIDC de votre tenant (https://auth.dev.stackngo.fr/t/acme)

Référencez-les dans votre App comme un secret :

billing-api-app.yml
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 :

ClaimContenu
issl'émetteur de votre tenant
subidentifiant stable du compte (le même que dans sng iam user list)
email, email_verifiedadresse du compte (avec le scope email)
tenantle nom de votre tenant
directorytenant
rolesles rôles du compte (absent s'il n'en a pas)
permissionsl'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 list aprè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: tenant n'ont pas accès à l'API StackNGO : leurs jetons n'y ouvrent aucune session.

Pour aller plus loin​

  • Une IAMApplication avec le flux client_credentials peut 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.

Voir aussi​