Portal Community

OIDC Discovery Document

Any OIDC-compliant library can auto-configure itself from Passport's discovery endpoint. This is the recommended way to integrate — the document provides all endpoints, supported scopes, signing algorithms, and claims.

GET /passport/.well-known/openid-configuration
Content-Type: application/json

{
  "issuer": "https://passport.bizfirst.ai",
  "authorization_endpoint": "https://passport.bizfirst.ai/passport/authorize",
  "token_endpoint": "https://passport.bizfirst.ai/passport/token",
  "userinfo_endpoint": "https://passport.bizfirst.ai/passport/userinfo",
  "jwks_uri": "https://passport.bizfirst.ai/passport/.well-known/jwks.json",
  "end_session_endpoint": "https://passport.bizfirst.ai/passport/logout",
  "response_types_supported": ["code", "token", "id_token"],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token",
    "client_credentials"
  ],
  "subject_types_supported": ["public"],
  "id_token_signing_alg_values_supported": ["RS256"],
  "scopes_supported": ["openid", "profile", "email", "roles", "tenant"],
  "claims_supported": [
    "sub", "iss", "aud", "exp", "iat",
    "email", "name", "given_name", "family_name",
    "roles", "tenant_id", "permissions"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post",
    "private_key_jwt"
  ],
  "code_challenge_methods_supported": ["S256"]
}

Client Registration

Each application that connects to Passport as an OIDC client must be registered. Registration is performed by a Passport administrator via the Admin API or the Passport Admin UI.

POST /passport/admin/clients
Authorization: Bearer {admin-token}
Content-Type: application/json

{
  "clientId": "myapp-prod",
  "clientName": "My Application (Production)",
  "clientSecret": "generated-by-passport",
  "redirectUris": [
    "https://myapp.example.com/auth/callback",
    "https://myapp.example.com/auth/silent-callback"
  ],
  "postLogoutRedirectUris": [
    "https://myapp.example.com/logged-out"
  ],
  "allowedScopes": ["openid", "profile", "email", "roles"],
  "grantTypes": ["authorization_code", "refresh_token"],
  "requirePkce": true,
  "accessTokenLifetime": 900,
  "refreshTokenLifetime": 604800,
  "tenantId": "tenant-abc"
}

Supported Scopes and Claims

ScopeClaims IncludedNotes
openidsub, iss, aud, exp, iatRequired — establishes the OIDC context
profilename, given_name, family_name, pictureBasic profile info
emailemail, email_verifiedUser's email address and verification status
rolesroles (array)Passport roles assigned to the user in this tenant
tenanttenant_id, tenant_nameTenant context — required for multi-tenant apps

Authorization Code Flow with PKCE

This is the recommended flow for web applications and SPAs. PKCE (Proof Key for Code Exchange) prevents authorization code interception attacks.

1

Generate PKCE Parameters

// Client generates code_verifier + code_challenge
const code_verifier = crypto.randomBytes(64).toString('base64url');
const code_challenge = crypto.createHash('sha256')
  .update(code_verifier).digest('base64url');
2

Authorization Request

GET /passport/authorize
  ?response_type=code
  &client_id=myapp-prod
  &redirect_uri=https://myapp.example.com/auth/callback
  &scope=openid%20profile%20email%20roles%20tenant
  &state=random-csrf-state
  &code_challenge=S256-hashed-verifier
  &code_challenge_method=S256
3

User Authenticates

Passport presents the login UI. User enters credentials (or uses an existing SSO session). MFA is triggered if required by the client's policy.

4

Callback with Authorization Code

GET https://myapp.example.com/auth/callback
  ?code=authorization-code-short-lived
  &state=random-csrf-state
5

Token Exchange

POST /passport/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=authorization-code-short-lived
&redirect_uri=https://myapp.example.com/auth/callback
&client_id=myapp-prod
&code_verifier=original-code-verifier
6

Token Response

{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "id_token": "eyJhbGciOiJSUzI1NiJ9...",
  "refresh_token": "opaque-refresh-token",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email roles tenant"
}

id_token Structure

The id_token is a signed JWT containing the authenticated user's identity. Verify the signature using Passport's JWKS before trusting the claims.

// Header
{
  "alg": "RS256",
  "kid": "signing-key-id-2026",
  "typ": "JWT"
}

// Payload
{
  "iss": "https://passport.bizfirst.ai",
  "sub": "user-guid-here",
  "aud": "myapp-prod",
  "exp": 1748120400,
  "iat": 1748119500,
  "nonce": "random-nonce-from-auth-request",
  "email": "jane.smith@example.com",
  "email_verified": true,
  "name": "Jane Smith",
  "given_name": "Jane",
  "family_name": "Smith",
  "roles": ["manager", "finance-user"],
  "tenant_id": "tenant-abc",
  "tenant_name": "Acme Corp"
}

Client Credentials Flow

For service-to-service calls (no user involved), use the client credentials grant. This is how managed identities and background services authenticate.

POST /passport/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(clientId:clientSecret)

grant_type=client_credentials
&scope=openid%20roles

// Response
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600
}
Token Lifetimes

Access tokens are short-lived (15 minutes by default). Refresh tokens are valid for 7 days and are rotated on each use — storing the new refresh token after each refresh is mandatory. Configure these values per client registration to match your security requirements.