Skip to main content

Authentication for your applications

Available

Deployed and supported. The fields and commands described here are stable within version v1alpha1.

Your applications can entrust the sign-in of their users to StackNGO: you declare an OIDC application in YAML, StackNGO creates the OAuth2 client and makes clientId, clientSecret and issuer available, ready to be passed to your App. Your users sign in on a page in your organization's colors (Sign-in page), without a password (Sign-in providers), and your application receives a standard OIDC token.

billing-api.yml
apiVersion: iam.stackngo.io/v1alpha1
kind: IAMApplication
metadata:
name: billing-api
spec:
directory: tenant # the users of YOUR 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

A few moments later, the billing-api-oidc credentials are ready to be used by your App.

Two directories, two issuers​

The directory field chooses who signs in to the application:

directoryWho signs inIssuer
tenantthe users of your applications (tenant directory)an issuer specific to your tenant: https://auth.dev.stackngo.fr/t/acme
platform (default)your tenant's members on StackNGO (internal tools, machine identities)the platform issuer

For an application meant for your customers, always set directory: tenant. The field can no longer be changed after creation: to change directory, create another application. It is incompatible with the urn:stackngo:introspect scope.

A token issued for your tenant's directory is valid only for it: it is rejected by the StackNGO API and by another tenant's issuer.

Prerequisites​

  • A session on the tenant: sng tenant use acme.
  • deploy:write (policy readwrite or admin).

Steps​

1. Generate and complete the manifest​

sng template gen IAMApplication billing-api > billing-api.yml

Add directory: tenant under spec if the template does not have it. The useful fields:

FieldRoleNotes
directorywhich users sign intenant or platform (default); cannot be changed
displayNamename shown on the sign-in screen256 characters max
homeURLthe application's home pageHTTPS; no local or private address
redirectURLsOAuth2 return URLsHTTPS, except http://127.0.0.1 / http://localhost for a native application or a CLI; 32 max
postLogoutRedirectURLsaddresses allowed after a sign-outsame rules; without them, sign-out does not redirect
grantTypesallowed flowsauthorization_code, refresh_token, client_credentials; 16 max
scopesoffered scopesopenid, profile, email…; 32 max
publicpublic client (native application, CLI)PKCE required, no secret
token.expireInHoursaccess token lifetime1 to 8760; 168 h if omitted (0 forbidden)
token.refreshExpireInHoursrefresh token lifetime168 if refresh_token is in grantTypes; 0 forbidden with refresh_token
credentialsSecret.namename under which the credentials are made available to your Apps<name>-oidc by default
deletionPolicyBlock (default), Orphan, Deletesee Limits

2. Apply​

sng apply billing-api.yml
IAMApplication/billing-api created

The console (Authentication section, Applications page) offers the same form, already prefilled with directory: tenant, and shows which applications sign in your users.

3. Use the credentials​

A few moments after applying, the credentials are ready under the name billing-api-oidc (or that of credentialsSecret.name), with three keys:

KeyContent
clientIdOAuth2 client identifier
clientSecretclient secret
issuerURL of your tenant's OIDC issuer (https://auth.dev.stackngo.fr/t/acme)

Reference them in your App as a 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 }

OIDC discovery is served under <issuer>/.well-known/openid-configuration: any OIDC library is happy with it.

For an application that does not run on the platform, read the credentials with sng iam app credentials billing-api (action auth:ReadCredentials, policy admin).

4. What the token contains​

The identity token (ID token) and the access token are signed JWTs (RS256). For a user of your directory, they carry:

ClaimContent
issyour tenant's issuer
substable account identifier (the same as in sng iam user list)
email, email_verifiedthe account's address (with the email scope)
tenantyour tenant's name
directorytenant
rolesthe account's roles (absent if it has none)
permissionsthe set of permissions of its roles (absent if there are none)

Tokens never reveal the other tenants a person may be a member of.

5. Verify the token in the application​

Your application must verify the signature (public keys announced by discovery), the issuer (iss equal to issuer), the audience (aud equal to your clientId) and the expiry, then read roles and permissions. Go example with 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 { /* refuse: 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 { /* refuse */ }
if !slices.Contains(claims.Permissions, "tickets:reply") { /* 403 */ }

The permissions are the ones you defined in your roles; they are checked by your code.

6. Renew the secret​

To change the clientSecret, renew it from the console (Renouveler le secret, under Authentification > Applications) or with the CLI. The new secret is written to billing-api-oidc; the clientId does not change.

sng iam app rotate billing-api
sng iam app credentials billing-api

The old secret is refused as soon as the renewal is processed, within seconds: then restart the applications that read the secret. This renewal is reserved for tenant administrators.

Verification​

sng iam app list
sng kind get IAMApplication billing-api

The application appears with the "Users of your applications" directory and Ready: True. Then, from your application, start an authorization_code flow to the authorization endpoint announced by the issuer's discovery with the clientId: your organization's sign-in page is displayed.

Limits​

  • If the application still does not appear in sng iam app list after a few minutes, your tenant's directory may not be enabled yet: contact support.
  • deletionPolicy: Block (default) delays deleting an application that is still in use, then deletes it as soon as it no longer is. A deleted application can be recreated under the same name, with new credentials.
  • directory: tenant applications have no access to the StackNGO API: their tokens open no session there.

Going further​

  • An IAMApplication with the client_credentials flow can serve as a machine identity to call the StackNGO API: see Machine identities.
  • The directory's applications are named stably: renaming the manifest creates a new application.

See also​