Skip to content

Applications And OAuth

Applications use SigID through OAuth 2.1 and OpenID Connect. SigID hosts the authentication experience, records consent, and returns tenant-scoped tokens to your application.

Use Authorization Code with PKCE for browser, native, and desktop applications.

  1. Your application creates a high-entropy state, code_verifier, and code_challenge.
  2. The browser redirects to /oauth/authorize.
  3. SigID authenticates the user and applies tenant policy.
  4. SigID prompts for consent when scopes or profile claims are new.
  5. SigID redirects to your registered callback with an authorization code.
  6. Your backend exchanges the code at /oauth/token.
  7. Your backend validates tokens and establishes an application session.
GET /oauth/authorize
  ?response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
  &scope=openid%20profile%20email
  &code_challenge=BASE64URL_SHA256_VERIFIER
  &code_challenge_method=S256
  &state=OPAQUE_CSRF_VALUE

Do not skip backend validation

Frontend login state is not authorization. Your API must validate the access token on every protected request or through a trusted session that was created after token validation.

OAuth and OIDC endpoints

Endpoint Use
/.well-known/openid-configuration Discover issuer, authorization endpoint, token endpoint, JWKS, UserInfo, revocation, and introspection metadata
/.well-known/jwks.json Fetch public keys for token signature validation
/oauth/authorize Start hosted login and consent
/oauth/par Store a pushed authorization request and receive a request_uri
/oauth/token Exchange authorization codes, refresh tokens, client credentials, token exchange, device code, or CIBA polling requests
/oauth/revoke Revoke supported token types
/oauth/introspect Check token status from a trusted backend
/oauth/device/code Start device authorization for CLI and input-constrained clients
/oauth/device/verify User-facing device verification page
/bc-authorize Start OIDC CIBA backchannel authentication
/oauth/end-session OIDC RP-initiated logout
/oauth/register Dynamic client registration when enabled
/userinfo Return consented OIDC profile claims

Dynamic Client Registration can be used by @sigid/init to create development applications from a terminal or coding agent. On shared issuer hosts, explicit tenant selection with tenant_id or tenant_slug is accepted only when DCR is protected by an initial access token.

Grant types

Grant type Use it for Avoid when
authorization_code with PKCE Human login for web, mobile, desktop, and server-rendered apps Machine-only service access
client_credentials Service clients and automation acting as themselves User login or delegated user actions
refresh_token Renewing sessions without another browser redirect High-risk actions that need step-up
urn:ietf:params:oauth:grant-type:token-exchange Reduced delegated access for agents, services, or vault grants Broad impersonation
urn:ietf:params:oauth:grant-type:device_code CLI, TV, device, or terminal flows Normal browser applications
urn:openid:params:grant-type:ciba Backchannel authentication where the client cannot redirect the user Normal browser applications

Token validation

When your API receives an access token, validate:

Check Why it matters
Issuer Prevents accepting tokens from another authority
Audience Ensures the token was minted for your API
Signature Confirms the token was issued by SigID
Expiration and not-before Rejects stale or future tokens
Tenant context Prevents cross-tenant access
Scopes Enforces API permission
Subject type Distinguishes human, agent, and service behavior
DPoP binding, when used Confirms the caller possesses the bound key

Minimal backend authorization pattern:

1. Parse bearer token.
2. Resolve issuer metadata and JWKS.
3. Verify signature and claims.
4. Load tenant and subject from validated claims.
5. Check required scope for the requested API operation.
6. Check subject type (human, agent, service, or delegated).
7. Apply organization, role, policy, or delegation rules.
8. Record high-impact actions in audit logs.
9. Serve the request or return an authorization error.

Tenant-scoped subjects

Tenant applications receive tenant-local subjects and tenant-scoped authority. Do not assume a user's sub is the same across tenants. Use the tenant-local subject as the durable user key inside your application.

Use global identifiers only when a documented product workflow explicitly shares them. Pairwise subject identifiers are designed to reduce cross-tenant correlation.

Request only the scopes your application needs for the current workflow. If you later request broader access, SigID prompts the user again.

Prompt parameter Result
prompt=login Require the user to sign in again
prompt=consent Require a fresh consent decision
prompt=none Attempt silent login and fail if interaction is needed
max_age Require authentication within a recent time window

Consent should be understandable without reading your source code. Scope names can be technical; consent descriptions should explain the outcome.

Advanced authorization requests

Use Pushed Authorization Requests for high-value integrations or clients that need FAPI-style request integrity. POST the same authorization parameters to /oauth/par, then redirect the browser to /oauth/authorize with the returned request_uri.

The authorization endpoint accepts Rich Authorization Requests through the authorization_details parameter and OIDC individual claim requests through the claims parameter. Authorization codes retain those request details through token issuance so APIs can enforce fine-grained consent.

Use acr_values when a route needs a minimum authentication assurance level. If the current session is below the requested ACR, SigID returns a step-up requirement instead of issuing an authorization code.

For CIBA, POST /bc-authorize to create a backchannel request, then poll /oauth/token with grant_type=urn:openid:params:grant-type:ciba and the returned auth_req_id until the request is approved, denied, expired, or still pending.

Refresh tokens and revocation

Use refresh tokens when your application needs long-lived sessions. Protect them like credentials:

  • store refresh tokens server-side or in platform-secure storage
  • rotate tokens according to the token response behavior
  • revoke refresh tokens on logout, account compromise, or device loss
  • treat reuse detection as a security event
  • keep access tokens short-lived

Use /oauth/revoke when a user disconnects an application, an administrator suspends access, or an incident requires token invalidation.

Device authorization

Device Authorization is designed for clients that cannot receive browser redirects, such as CLIs or devices with limited input.

  1. The client requests a device code at /oauth/device/code.
  2. SigID returns a user code, verification URI, device code, and polling interval.
  3. The user opens the verification URI and approves or denies the request.
  4. The device polls /oauth/token with the device-code grant until completion, denial, expiry, or slow_down.

Respect the returned polling interval. Treat authorization_pending as normal, slow_down as a signal to back off, and expired_token as a reason to restart the flow.

Hosted sign-in methods

Tenant administrators can enable email and password, passkeys, magic links, OTP, social OAuth, enterprise SSO, SIWE wallet authentication, and anonymous accounts. For all supported methods and descriptions, see Product Reference.

Use step-up MFA or fresh login for sensitive actions such as billing changes, organization ownership transfer, credential export, wallet signing, or administrator access.

Common integration mistakes

Mistake Correct approach
Using email as the primary user key Use the tenant-local subject
Accepting tokens without checking audience Configure and validate the API audience
Trusting frontend-only login state Validate access tokens in the backend
Reusing one OAuth client everywhere Create clients per application or runtime boundary
Requesting broad scopes at first login Request scopes when the user reaches the feature that needs them
Ignoring state Validate state to prevent CSRF and callback confusion
Treating agents as users Check subject type and delegation claims