OpenID Connect
What Is OpenID Connect?
Section titled “What Is OpenID Connect?”OpenID Connect (OIDC) is the identity layer that most modern web applications use. When you click “Sign in with Google” or “Sign in with Microsoft” on a website, that’s OIDC at work — the website asks an identity provider who you are, and receives a signed token with your identity.
The protocol has two roles:
- The OpenID Provider (OP) is the system that authenticates the user and issues an identity token. Google, Microsoft, and Okta are common examples.
- The Relying Party (RP) is the application that needs to know who the user is — it trusts the provider’s token.
IDToken Seal acts as the OpenID Provider. When an application asks “who is this user?”, IDToken Seal authenticates them with the standard passwordless flow (code + face verification) and returns a signed identity token — exactly the way the application expects from any OIDC provider.
When Would I Use This?
Section titled “When Would I Use This?”OIDC is the right choice for most modern integrations:
- Cloud services — Google Workspace, Microsoft 365, Slack, GitHub, and thousands of SaaS platforms accept OIDC providers out of the box. Configuring them to trust IDToken Seal replaces password login without any code changes.
- Modern web applications — any application built with standard OIDC client libraries (in any language) can integrate IDToken Seal with minimal configuration. The application just needs the discovery URL.
- Mobile and single-page apps — OIDC’s authorization code flow works natively with browser redirects and mobile deep links.
If you need to integrate with legacy enterprise systems that only speak SAML, see the SAML 2.0 IdP page. If you want full control over the authentication UX (custom login screens, embedded WebSocket updates), the direct JWT integration gives you lower-level access. If you need portable credentials for digital wallets, see Verifiable Credentials.
How It Works
Section titled “How It Works”From the user’s perspective, the experience is identical to any IDToken Seal login — code confirmation and face verification. The OIDC protocol handles the communication between the application and IDToken Seal behind the scenes.
- The user clicks “Sign in” on the application
- The application redirects to IDToken Seal’s authorization endpoint with the requested scopes (e.g., “give me their name and whether they’re over 18”)
- IDToken Seal shows the login page — the user enters their token ID
- The standard X.1280 authentication runs: code displayed, mobile push, confirmation, face verification
- IDToken Seal redirects back to the application with an authorization code
- The application exchanges the code for an identity token — a signed JWT containing the user’s verified claims
What the Application Receives
Section titled “What the Application Receives”After the exchange, the application gets an ID token — a signed JWT containing the identity claims the user consented to share. The token is signed with ECDSA P-256, and the application verifies it using IDToken Seal’s public key (published at /.well-known/jwks.json).
The claims in the token depend on the scopes requested. For example, an application that requested openid identity:name identity:age_over_18 receives:
{ "iss": "https://auth.idtokenseal.id3.eu", "sub": "vds-token-uuid", "aud": "bar-le-central", "exp": 1705316400, "iat": 1705312800, "nonce": "random-replay-protection", "given_name": "Jean", "family_name": "Dupont", "name": "Jean Dupont", "age_over_18": true, "trust_level": 3, "acr": "urn:idtokenseal:acr:face-oob-high"}The application never sees data it didn’t ask for, and the user can deny individual scopes on their mobile app — in which case those claims are simply absent from the token.
Selective Disclosure
Section titled “Selective Disclosure”OIDC scopes map directly to the IDToken Seal selective disclosure system. The application requests scopes in the authorization URL, and the user approves (or denies) each one on their mobile app. Only approved claims appear in the identity token.
IDToken Seal maps to OIDC standard claim names where possible (given_name, family_name, birthdate, picture). Claims without a standard equivalent — like nationality, age_over_18, or trust_level — use IDToken Seal-specific names.
Comparison with SAML and Direct JWT
Section titled “Comparison with SAML and Direct JWT”| Feature | OIDC | SAML | Direct JWT |
|---|---|---|---|
| Token format | JWT (compact, JSON) | XML assertion (verbose) | JWT (compact, JSON) |
| Discovery | Auto-configure via /.well-known/ URL | Import IdP metadata XML | Manual JWKS URL configuration |
| Best for | Modern web/mobile apps, cloud SaaS | Legacy enterprise SSO | Custom UX, embedded login flows |
| Client libraries | Available in every language | Available but heavier | None needed (standard HTTP) |
| Selective disclosure | Via OIDC scopes | Via attribute mapping | Via IDToken Seal scopes |
All three use the same underlying X.1280 authentication flow. The choice depends on what the consuming application supports.
Technical Reference
Section titled “Technical Reference”The sections below cover endpoints, discovery metadata, authorization parameters, token claims, client registration, and authentication context. This is the implementation detail for developers integrating an OIDC Relying Party with IDToken Seal.
OIDC Endpoints
Section titled “OIDC Endpoints”| Endpoint | Method | Description |
|---|---|---|
/.well-known/openid-configuration | GET | OIDC discovery document |
/oidc/authorize | GET | Authorization endpoint (starts auth flow) |
/oidc/token | POST | Token endpoint (exchanges code for tokens) |
/oidc/userinfo | GET | UserInfo endpoint (returns identity claims) |
/.well-known/jwks.json | GET | JSON Web Key Set (existing endpoint) |
/oidc/end-session | GET/POST | RP-initiated logout |
Discovery Document
Section titled “Discovery Document”The OIDC discovery document at /.well-known/openid-configuration advertises the provider’s capabilities:
{ "issuer": "https://auth.idtokenseal.id3.eu", "authorization_endpoint": "https://auth.idtokenseal.id3.eu/oidc/authorize", "token_endpoint": "https://auth.idtokenseal.id3.eu/oidc/token", "userinfo_endpoint": "https://auth.idtokenseal.id3.eu/oidc/userinfo", "jwks_uri": "https://auth.idtokenseal.id3.eu/.well-known/jwks.json", "end_session_endpoint": "https://auth.idtokenseal.id3.eu/oidc/end-session", "scopes_supported": [ "openid", "profile", "email", "identity:name", "identity:date_of_birth", "identity:nationality", "identity:age_over_18", "identity:age_over_21", "identity:trust_level" ], "response_types_supported": ["code"], "grant_types_supported": ["authorization_code"], "subject_types_supported": ["public", "pairwise"], "id_token_signing_alg_values_supported": ["ES256"], "token_endpoint_auth_methods_supported": [ "client_secret_basic", "client_secret_post" ], "claims_supported": [ "sub", "name", "given_name", "family_name", "birthdate", "nationality", "age_over_18", "age_over_21", "trust_level" ]}Authorization Request
Section titled “Authorization Request”GET /oidc/authorize? response_type=code &client_id=bar-le-central &redirect_uri=https://bar-le-central.fr/callback &scope=openid identity:name identity:age_over_18 &state=random-csrf-token &nonce=random-replay-protectionIDToken Seal uses the Authorization Code Flow exclusively (the most secure OIDC flow). Implicit and hybrid flows are not supported.
Token Response
Section titled “Token Response”{ "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 3600, "id_token": "eyJhbGciOiJFUzI1NiIs...", "scope": "openid identity:name identity:age_over_18"}ID Token Claims
Section titled “ID Token Claims”The id_token is a JWT (ES256-signed) containing identity claims mapped to OIDC standard claim names where possible:
| IDToken Seal Scope | OIDC Claim | Type | Description |
|---|---|---|---|
openid | sub | string | Subject identifier (tokenId) |
identity:name | given_name, family_name, name | string | Full name from VDS |
identity:date_of_birth | birthdate | string | ISO 8601 date |
identity:nationality | nationality | string | 3-letter ISO code (custom claim) |
identity:age_over_18 | age_over_18 | boolean | Derived from birthdate (custom claim) |
identity:age_over_21 | age_over_21 | boolean | Derived from birthdate (custom claim) |
identity:trust_level | trust_level | number | 1 (self), 2 (operator), 3 (eIDAS) |
identity:photo | picture | string | Base64-encoded portrait (restricted) |
Standard vs. Custom Claims
Section titled “Standard vs. Custom Claims”| Category | Standard Claims Used | Custom Claims |
|---|---|---|
| Name | given_name, family_name, name | — |
| Birth | birthdate | — |
| Photo | picture | — |
| Nationality | — | nationality |
| Age verification | — | age_over_18, age_over_21, age_range |
| Trust | — | trust_level |
| Identity | — | is_eu_citizen, name_initial |
OIDC Standard Scope Mapping
Section titled “OIDC Standard Scope Mapping”| OIDC Standard Scope | Maps To | Claims Returned |
|---|---|---|
openid | — | sub |
profile | identity:name | given_name, family_name, name |
email | — | Not available (VDS contains no email) |
For identity claims beyond standard OIDC scopes, use IDToken Seal’s native scopes (identity:age_over_18, identity:nationality, etc.) alongside openid.
Subject Identifier Types
Section titled “Subject Identifier Types”| Type | Behavior | Use Case |
|---|---|---|
public | sub = tokenId (same across all clients) | Default; enables cross-service identity linking |
pairwise | sub = HMAC(tokenId, client_id) | Privacy-preserving; different sub per client, preventing cross-service tracking |
The subject type is configured per client registration.
Client Registration
Section titled “Client Registration”OIDC clients (Relying Parties) are registered with the IDToken Seal operator. Each client record defines:
| Field | Description |
|---|---|
client_id | Unique identifier for the client application |
client_secret | Secret for token endpoint authentication |
redirect_uris | Allowed callback URLs (strict matching) |
allowed_scopes | Maximum scopes this client can request |
subject_type | public or pairwise |
id_token_signed_response_alg | ES256 (default, ECDSA P-256) |
token_endpoint_auth_method | client_secret_basic or client_secret_post |
Authentication Context
Section titled “Authentication Context”The acr (Authentication Context Class Reference) claim in the id_token reflects the trust level:
| Trust Level | ACR Value |
|---|---|
| 1 (self-issued) | urn:idtokenseal:acr:face-oob-low |
| 2 (operator-verified) | urn:idtokenseal:acr:face-oob-substantial |
| 3 (NFC + eIDAS) | urn:idtokenseal:acr:face-oob-high |
Clients can request a minimum ACR via the acr_values parameter in the authorization request.
UserInfo Endpoint
Section titled “UserInfo Endpoint”The /oidc/userinfo endpoint returns identity claims for the authenticated user:
GET /oidc/userinfoAuthorization: Bearer {access_token}{ "sub": "vds-token-uuid", "given_name": "Jean", "family_name": "Dupont", "name": "Jean Dupont", "birthdate": "1985-06-15", "nationality": "FRA", "age_over_18": true, "trust_level": 3}The response contains only claims matching the scopes granted during authentication.