sng sso
Deployed and supported. The fields and commands described here are stable within version v1alpha1.
The sng sso group identifies you to StackNGO: it obtains an identity token from the platform's SSO (https://auth.dev.stackngo.app) and saves it in your configuration file. This token gives access to no tenant: sng tenant use then exchanges it for a tenant session.
sng sso login # browser
sng sso whoami
sng tenant use acme
The full flow is described in The identity, session, tenant model. The global flags (--config, --json, -v, --version) are described in the CLI index.
| Command | Route | Token presented |
|---|---|---|
login | SSO …/login/oauth/authorize and …/api/login/oauth/access_token; with --oidc: POST /v1/iam/session | — |
logout | POST /v1/iam/logout | identity |
whoami | GET /v1/iam/me | identity |
None of these routes checks a policy.
sng sso login
sng sso login [--client-credentials [--client-id ID] [--client-secret SECRET]] [--oidc]
Three mutually exclusive modes:
| Mode | For whom | What is saved |
|---|---|---|
| (default) browser, OAuth2 Authorization Code + PKCE | you, on your workstation | identity token (access_token, refresh_token) |
--client-credentials | a script or a CI, with the credentials of your machine application (IAMApplication) | identity token (access_token) |
--oidc Beta | a persistent CI runner | a tenant session (tenant_token); the saved identity is erased |
| Flag | Type | Default | Description |
|---|---|---|---|
--client-credentials | bool | false | client_credentials machine flow instead of the browser |
--client-id | string | (environment variable, then the CLI's client) | client ID of the machine application, with --client-credentials only; otherwise STNG_OAUTH_CLIENT_ID, then the identifier built into the CLI |
--client-secret | string | (environment variable) | client secret; otherwise STNG_OAUTH_CLIENT_SECRET |
--oidc | bool | false | exchanges the CI job's OIDC token for a tenant session and saves it |
Browser (PKCE)
The CLI opens an ephemeral local port on 127.0.0.1, prints the sign-in URL, and opens your browser on it. After sign-in, the SSO redirects to http://127.0.0.1:<port>/callback and the CLI exchanges the code for the tokens (scopes openid profile email).
sng sso login
Ouvrez cette URL dans votre navigateur :
https://auth.dev.stackngo.app/login/oauth/authorize?client_id=…&code_challenge=…&code_challenge_method=S256&redirect_uri=http%3A%2F%2F127.0.0.1%3A53817%2Fcallback&response_type=code&scope=openid+profile+email&state=…
session saved (api https://api.dev.stackngo.fr)
Without a graphical browser (remote server), open the printed URL on a machine that can reach the CLI's local port; otherwise, ouverture navigateur: … is shown and the command waits. The browser shows Connexion réussie. Vous pouvez fermer cette fenêtre.
The SSO address and the client identifier of the browser sign-in are built into the binary: neither the configuration file nor an environment variable changes them.
--client-credentials
Sign in with the credentials of a machine application declared by an IAMApplication with the client_credentials flow:
sng sso login --client-credentials --client-id "$CLIENT_ID" --client-secret "$CLIENT_SECRET"
# or, with nothing on the command line:
STNG_OAUTH_CLIENT_ID="$CLIENT_ID" STNG_OAUTH_CLIENT_SECRET="$CLIENT_SECRET" sng sso login --client-credentials
sng tenant use acme
session saved (api https://api.dev.stackngo.fr)
The client ID comes from --client-id, otherwise from STNG_OAUTH_CLIENT_ID, otherwise from the identifier built into the CLI. Both settings only apply to --client-credentials: the browser sign-in always keeps the CLI's identifier. For the machine to then open a tenant session, attach a policy to it with assume-role (see Machines and technical accounts).
Being rolled out. The interface described here is the one of the next release: it may still change, and may not be enabled on your tenant yet.
CI pipeline federation is being rolled out gradually.
--oidc: persistent CI runner
In a CI job, no sign-in is needed: each tenant command detects the job's OIDC token, opens a session in memory, and reopens it on expiry, without writing anything to disk. sng sso login --oidc is only useful when several commands or scripts must share a saved session (persistent runner).
The command reads the job's token, in this order:
| Source | Variable |
|---|---|
token provided in a variable (GitLab id_tokens) | STNG_OIDC_TOKEN |
| token in a file | STNG_OIDC_TOKEN_FILE |
GitHub Actions (permissions: id-token: write) | ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN, audience STNG_OIDC_AUDIENCE (default: https://api.dev.stackngo.fr) |
It then calls POST /v1/iam/session on the tenant STNG_TENANT (otherwise the current tenant), with STNG_OIDC_TRUST if several of the tenant's trusts may match.
STNG_TENANT=acme sng sso login --oidc
OIDC session saved: tenant acme (token from STNG_OIDC_TOKEN, expires in 900s)
--json output: {"tenant": "acme", "origin_tenant": "acme", "expires_in": 900, "source": "STNG_OIDC_TOKEN"}.
The saved session does not renew itself: on expiry (at most the trust's maxSessionDuration), run sng sso login --oidc again. The saved identity token is erased, so that an OIDC session is never renewed with another subject's identity. A saved session only opens the tenant's routes: sng tenant list, create, use, and sng template require an identity.
Typical errors
| Message | Cause |
|---|---|
client_credentials requires --client-secret or STNG_OAUTH_CLIENT_SECRET | --client-credentials without a secret |
--client-id only applies to --client-credentials | --client-id given without --client-credentials |
client_credentials 401: … | secret refused by the SSO |
oauth error: access_denied (…) | sign-in refused or cancelled in the browser |
oauth state mismatch | browser response that does not match this sign-in: run again |
binary has no embedded auth: … | binary compiled without SSO settings: install an official binary |
--oidc and --client-credentials are mutually exclusive | two modes at once |
no CI OIDC token: set STNG_OIDC_TOKEN (GitLab id_tokens), STNG_OIDC_TOKEN_FILE, or run in GitHub Actions with permissions: id-token: write | no job token detected |
OIDC: tenant required: set STNG_TENANT to the tenant the CI job authenticates to | neither STNG_TENANT nor a current tenant |
OIDC exchange refused (401 invalid identity token): no trust of tenant "acme" accepts this CI token (iss=…, aud=…, sub=…); … | no trust matches, or several do: compare with sng tenant oidc get, or set STNG_OIDC_TRUST |
jeton OIDC du CI expiré (CI OIDC token expired): … | the token provided by variable or file has expired |
api_url must be HTTPS (except localhost), got: … | STNG_API_URL over http:// to a remote host |
sng sso logout
sng sso logout
Ends every tenant session opened with your account, then erases the identity token, the refresh token, the session, and the current tenant from the configuration. The command calls POST /v1/iam/logout with your identity token; if that call fails (identity already expired, network), the local configuration is erased anyway.
sng sso logout
signed out
Every tenant session issued for your account up to the sign-out is refused (401) within a few seconds, including those copied to another machine. Your identity token, however, is only forgotten locally: a copy of that token stays valid until it expires and can still open a session. See API authentication.
sng sso whoami
sng sso whoami [--json]
Shows the signed-in identity, as the SSO describes it.
sng sso whoami
org=stackngo user=alice email=alice@acme.example platform_admin=false
roles: stackngo/dev
The roles: line only appears if you hold roles.
--json output:
{
"organization": "stackngo",
"username": "alice",
"display_name": "Alice",
"email": "alice@acme.example",
"roles": ["stackngo/dev"],
"is_platform_admin": false,
"tenant": ""
}
With an OIDC session (CI) Beta
When the CLI works with a session without an identity (job OIDC token detected, session saved by sng sso login --oidc, or STNG_TENANT_TOKEN without STNG_ACCESS_TOKEN), whoami decodes the session instead of calling GET /v1/iam/me:
kind=oidc sub=acme/gitlab-deploy tenant=acme
name: project_path:acme/infra:ref_type:branch:ref:main
expires: 2026-10-07T10:42:00Z
--json output: {"kind": "oidc", "sub": "acme/gitlab-deploy", "name": "…", "tenant": "acme", "origin_tenant": "acme", "expires_at": "…"}.
Typical errors: not authenticated: run sng sso login or set STNG_ACCESS_TOKEN; not authenticated: run sng sso login (identity expired, 401).
Environment variables
| Variable | Effect |
|---|---|
STNG_ACCESS_TOKEN | identity token to use instead of the file's |
STNG_TENANT_TOKEN | tenant session to use; takes precedence over OIDC detection |
STNG_TENANT | current tenant |
STNG_OAUTH_CLIENT_ID | client ID for --client-credentials |
STNG_OAUTH_CLIENT_SECRET | secret for --client-credentials |
STNG_OIDC_TOKEN, STNG_OIDC_TOKEN_FILE, STNG_OIDC_AUDIENCE, STNG_OIDC_TRUST | CI job OIDC token and its use (Beta) |
Full list in Configuration.
See also
- Guides: The identity, session, tenant model, Machines and technical accounts, Deploy without secrets (OIDC)
- Related commands:
sng tenant(use,assume),sng config - API: Authentication