There are two kinds of user. Org users (you and your team) sign in to API Studio to build. App users are the end-users of your deployed app. This page is about app users — the people who call your live endpoints.
Accounts are created on first sign-in
App users don't have a separate registration step. The first time someone signs in — by email/password or OAuth — their account and workspace membership are provisioned inline.
Token exchange
Your app obtains an identity token from the provider, then exchanges it for a nostackai app JWT at the token endpoint. The app JWT is what every data API call carries.
GET /app/{orgCode}/token
oauthtoken: <provider id token | password-login token>
client_id: <your app client id>
-> 200, header x-nostackai-token: <app JWT> The token Lambda validates your client_id against the org record, checks the token issuer against the allowlist, resolves the user's workspace, and signs the app JWT (valid ~48h).
OAuth providers
- Google — the browser gets a Google ID token via the Sign-In SDK and posts it to the token endpoint. The workspace registers its Google client ID under Tenant Settings → SSO (a paid-plan feature); the token endpoint accepts a Google token only when it was issued to a client ID one of the org's workspaces registered. For Google Workspace company emails, an optional sign-in domain lets your app discover the workspace's client ID from a public pre-login route first. For personal Gmail accounts, a workspace can register your app's client ID under Personal Google accounts (Gmail); people who sign in with Gmail through it join that workspace, pending or approved by its setting.
- Okta (or any OIDC provider), per tenant — each tenant registers its own provider under Tenant Settings → SSO. Your app fetches that tenant's issuer/authorize-endpoint/client-id from a public pre-login route, redirects to the IdP (implicit flow), and the returned ID token is verified against that tenant's own JWKS before the token endpoint mints an app JWT.
Tenant SSO config lives with the tenant, not the org
Unlike org/console SSO, a tenant's Okta config is stored in that tenant's own app-domain data — never in the shared platform table. See the SSO section for full setup and testing steps.
What the app JWT carries
- `org` — your org code (the claim is
org, notorg_code). - `tenant_id` / `tenant_code` — the active workspace, when resolved.
- `role` — an app-defined label (e.g.
admin). It is not enforced by the gateway — see ACL, roles & groups. - `email`, `fn`, `ln`, `picture`, `email_verified`, `clientid`, `iss` — identity and source.
The role claim grants nothing
The app authorizer ignores the JWT role. Permissions come only from ACL policies. The role is surfaced for your own in-app logic.