OIDC relying-party integration
OIDC relying-party integration
The MVS OIDC Identity Provider is live at https://c-auth.mvscloud.com. Any
standards-compliant OIDC client library works (e.g. openid-client,
next-auth, Better Auth’s genericOAuth/social provider).
1. Register your client
Clients exist only as oauth_client database rows. There are two supported
ways to create that row: the gated, authenticated
self-service registration API (an admin session
or a scoped Initial Access Token — the self-serve path for internal MVS apps /
CI), or the operator CLI below (the manual fallback for external/un-tokened RPs,
or when self-registration is disabled). To use the CLI, from the mvs-auth repo,
with AUTH_DATABASE_URL pointing at the auth database:
The script prints the client_id and the one-time-visible client secret
(only a SHA-256 hash is stored). First-party clients can be registered with
skipConsent so users never see the consent page.
An oauth_client database row is what authenticates a client — written
either via the gated, authenticated
self-service registration API or via the
oidc:register CLI. The OIDC_CLIENT_* environment triplets are vestigial.
The only thing disabled is the better-auth plugin’s RFC 7591 /oauth2/register
endpoint, so the discovery document carries no registration_endpoint — there
is no dynamic (RFC 7591) client registration.
2. Configure your client
3. Validate tokens
Access tokens are opaque (mvs_at_* prefix) — validate them server-side
with RFC 7662 introspection at /api/auth/oauth2/introspect using your client
credentials. ID tokens are JWTs signed with EdDSA (Ed25519); verify against
the JWKS endpoint.
Namespaced custom claims are present in the ID token and userinfo response:
A JWT-access-token lane (RFC 8707 resource parameter + aud-bound JWTs)
is available once your API origin is on the OIDC_VALID_AUDIENCES allowlist
and you pass the RFC 8707 resource param on /authorize (see the downstream
guide §5). Without it, access tokens are opaque and require introspection.
4. Logout
RP-initiated logout is available at /api/auth/oauth2/end-session. Refresh
tokens rotate on use; reusing a rotated refresh token invalidates the whole
token family.