Built-in OpenID Connect identity provider. The handler is fully spec-compliant for Authorization Code + PKCE, exposes discovery + JWKS at the conventional /.well-known paths, and signs id_token / access_token with RS256.
Two URL shapes, one handler. Every endpoint below is reachable in either form — the conventional /oauth2/v1/<name> path (used by most commercial OIDC providers and what discovery advertises), or the legacy /oidc.ashx?action=<name> form. RP libraries that follow discovery automatically use the /oauth2/v1/* shape and need no special configuration.
Form POST that authenticates the visitor using the same HA1 (MD5(user:realm:password)) as the SIP credentials store. Computes HA1 client-side so plaintext passwords never reach the IdP. When the return URL points back to ?action=authorize, the code is minted directly — no cookie is set.
Request
Body fields: user, ha1 (32 hex), return (optional URL).
Response
Either a 302 redirect with ?code=… appended to return, or JSON { ok: true, code: "…" }.
Errors
400 / 401 { error: "invalid_credentials" }. 429 if IP exceeded 10 attempts in the last 60 s.
HA1 comparison is constant-time. The login is stateless: no session cookie is set on the IdP origin.
RFC 6749 token endpoint. Exchanges either an authorization code (with PKCE verifier) or a refresh token for a fresh id_token, access_token and rotated refresh_token.
Request
Form / JSON body: grant_type (authorization_code, refresh_token, or urn:ietf:params:oauth:grant-type:jwt-bearer), code, redirect_uri, code_verifier, client_id, client_secret (confidential clients only), refresh_token, assertion (JWT-bearer grant only).
The JWT-bearer grant (RFC 7523) lets a wallet integrator exchange an SSO assertion (typ=sso) from vp-response directly for an access_token, skipping the full Authorization Code + PKCE choreography. See the EU Wallet integration walkthrough →
OpenID Connect RP-Initiated Logout 1.0. Clears the IdP-side SSO assertion and bounces the browser back to post_logout_redirect_uri if it’s registered for the client.
Equivalent legacy form: /oidc.ashx?action=userinfo. Discovery advertises the /oauth2/v1/userinfo path so off-the-shelf RP libraries pick it up automatically.
RFC 7662 token introspection. Submit any token issued by this IdP — access_token, id_token, or refresh_token — and find out whether it’s still active, who it belongs to, and when it expires.
Request
Form / JSON body: token (required), token_type_hint (optional — access_token, id_token or refresh_token), client_id (required only when introspecting a token that was issued to a confidential client), client_secret (then required).
For an inactive / unknown / expired token — per RFC 7662 §2.2 the only field returned is active:
{"active":false}
Verified 2026-06-05 — POST token=bogus → 200 {"active":false}.
Errors
400 if token is missing. 401 if the named confidential client’s secret fails to verify. Never a 4xx for “token unknown” — that returns 200 {active: false} by spec.
Useful for resource servers that want to defer token-validation logic to the IdP instead of verifying JWT signatures themselves. Note: for high-traffic resource servers, local JWT verification using the JWKS is usually faster.
Build stamp, tenant identity, and live EU Wallet verifier counters. Handy as a liveness probe and a quick way to spot the OID4VP abandonment rate without parsing logs.
build — handler build version. Format YYYY-MM-DD-slug; bumped on every meaningful change.
tenant — tenant the request resolved to (multi‑tenancy by domain).
now — current server time, seconds since epoch.
vp_started / vp_completed — counters of OID4VP sessions opened and completed since service start.
vp_abandoned — counter of sessions that timed out without a wallet response.
vp_pending_or_inflight — gauge of sessions currently waiting on a wallet.
Verified 2026-06-09.
Example
curl https://phone.codeb.io/oidc.ashx?action=ping
Full EU Wallet verifier endpoint set (vp-start, vp-request, vp-response, verifier-metadata) is documented separately at eu-wallet-api.html.
Need an admin endpoint? Admin-only and OIDC Bearer-gated routes
are documented inside the admin UI itself (visible only to signed-in admins
on this host). The public API set on this page is the surface you can
integrate against without provisioning a CodeB user.