Protocol
How NIA implements OAuth 2.0 and OpenID Connect — the standards behind “Sign in with NIA”, and exactly how the flow, PKCE, scopes and claims work.
OAuth 2.0
NIA Auth is a standards-compliant OAuth 2.0 Authorization Server (RFC 6749). OAuth 2.0 lets your application obtain limited access to a user's identity without ever handling their password — the user signs in on NIA, and your app receives tokens.
Four roles are involved:
- Resource owner — the user signing in.
- Client — your application.
- Authorization server — NIA Auth, which authenticates the user and issues tokens.
- Resource server — an API that accepts NIA access tokens (e.g. the UserInfo endpoint, or your own backend).
NIA supports these grant types:
authorization_code— the primary flow for web, SPA and mobile apps (always with PKCE).refresh_token— obtain a new access token without re-prompting the user.client_credentials— machine-to-machine access with no user context.
The authorization-code flow at a glance:
1. App redirects the user to https://dev-api.niaauth.com/oauth/authorize
2. User authenticates and consents on NIA
3. NIA redirects back with a one-time ?code=...
4. App exchanges the code at https://dev-api.niaauth.com/oauth/token
5. NIA returns access_token (+ id_token, refresh_token)
6. App calls your API / UserInfo with the Bearer access_tokenAccess tokens are RS256-signed JWTs sent as Authorization: Bearer <token> (RFC 6750). Resource servers verify them offline against the JWKS.
OpenID Connect
OpenID Connect (OIDC Core 1.0) is a thin identity layer on top of OAuth 2.0. Where OAuth answers “can this app access X?”, OIDC answers “who is the user?”. Request the openid scope and NIA issues an ID token alongside the access token.
The ID token is a signed JWT (RS256) that proves the user's identity. Your client verifies it and reads the claims — no extra API call required.
{
"iss": "https://dev-api.niaauth.com",
"sub": "550e8400-e29b-41d4-a716-446655440000",
"aud": "your-client-id",
"exp": 1751500900,
"iat": 1751500000,
"nonce": "the-nonce-you-sent",
"email": "alice@example.com",
"email_verified": true,
"name": "Alice Smith"
}OIDC also adds:
- UserInfo endpoint —
https://dev-api.niaauth.com/oauth/userinfo, returns claims for a valid access token. - Discovery —
/.well-known/openid-configuration, so libraries auto-configure every endpoint. - nonce — echoed back in the ID token to prevent replay; validate it matches what you sent.
PKCE
PKCE (Proof Key for Code Exchange, RFC 7636) protects the authorization code from interception. NIA requires PKCE with the S256 method on every flow — the plain method is rejected.
Your app generates a random code_verifier, derives a code_challenge from it, sends the challenge on the authorization request, then proves possession by sending the verifier on the token request:
code_verifier = random 43-128 char string (keep it secret, in the session)
code_challenge = BASE64URL( SHA-256( code_verifier ) )
# /oauth/authorize → code_challenge + code_challenge_method=S256
# /oauth/token → code_verifier
# NIA recomputes SHA-256(code_verifier) and checks it equals code_challengeMost OIDC libraries generate and manage PKCE for you. Public clients (SPAs, mobile) rely on PKCE instead of a client secret.
code_verifier across requests, and never send code_challenge_method=plain — NIA will reject it.Scopes & claims
Scopes control what your app may access; each scope maps to a set of claims returned in the ID token and from UserInfo. Request scopes space-separated on the authorization request, e.g. scope=openid email profile.
| Scope | Grants | Claims |
|---|---|---|
openid | Required for OIDC — issues an ID token | sub |
email | The user's email address — a contact attribute, not an identifier | email, email_verified |
profile | Basic profile | name, given_name, family_name, picture, updated_at |
offline_access | Enables refresh tokens (long-lived access) | — |
sub. sub is the NIA user id: globally unique, stable and immutable for the life of the account. It is the only claim safe to store as a foreign key or to compare to decide who someone is. email is a sign-in and contact attribute — people change it, and an administrator or a directory sync can change it for them — so keying your records on it will orphan users the day it changes.The user sees a consent screen the first time your app requests a scope. Requesting new scopes later prompts again for just the new ones. NIA's discovery document lists everything supported under scopes_supported and claims_supported.