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:

flow
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_token

Access 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.

id_token payload
{
  "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.
Because NIA is standard OIDC, “Sign in with NIA” works with any conformant library — exactly like “Sign in with Google”.

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:

PKCE
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_challenge

Most OIDC libraries generate and manage PKCE for you. Public clients (SPAs, mobile) rely on PKCE instead of a client secret.

Never reuse a 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.

ScopeGrantsClaims
openidRequired for OIDC — issues an ID tokensub
emailThe user's email address — a contact attribute, not an identifieremail, email_verified
profileBasic profilename, given_name, family_name, picture, updated_at
offline_accessEnables refresh tokens (long-lived access)—
Identify users by 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.