Skip to content

feat: implement OIDC server for next-gen auth (MSC2965/2964/2966/2967)#342

Draft
lytedev wants to merge 2 commits intomatrix-construct:mainfrom
lytedev:oidc-server
Draft

feat: implement OIDC server for next-gen auth (MSC2965/2964/2966/2967)#342
lytedev wants to merge 2 commits intomatrix-construct:mainfrom
lytedev:oidc-server

Conversation

@lytedev
Copy link

@lytedev lytedev commented Feb 26, 2026

Implements a built-in OIDC authorization server that allows Matrix clients like Element X to authenticate via the next-gen auth flow (MSC2964). User authentication is delegated to upstream identity providers (e.g. Kanidm) through the existing SSO/OAuth client flow.

Endpoints

  • auth_issuer + auth_metadata discovery (stable v1 + unstable MSC2965)
  • OpenID Connect discovery (/.well-known/openid-configuration)
  • Dynamic Client Registration (MSC2966)
  • Authorization + token + revocation + JWKS + userinfo
  • SSO bridge: authorize → SSO redirect → complete → code → token

Features

  • ES256 (P-256) JWT signing with persistent key material
  • PKCE (S256) support with RFC 7636 verifier validation (43-128 chars, restricted charset)
  • Authorization code grant with refresh tokens
  • All OIDC state persisted in RocksDB (signing keys, client registrations, auth codes, pending auth requests)
  • Device ID extraction from MSC2967 scopes

Spec compliance fixes

  • OAuth error responses use RFC 6749 §5.2 format ({"error": "...", "error_description": "..."}) on token, registration, and revocation endpoints instead of Matrix {"errcode": "M_..."} format
  • PKCE code_verifier validation per RFC 7636 §4.1 (length and charset checks)
  • Scope token matching uses exact whitespace-delimited comparison per RFC 6749 §3.3 instead of substring matching
  • Typed ProviderMetadata struct for the discovery document with documented fields per RFC 8414 / OpenID Connect Discovery 1.0
  • DCR request/response includes policy_uri, tos_uri, software_id, software_version per RFC 7591

Refs: #246, #266

@lytedev lytedev marked this pull request as draft February 26, 2026 17:39
@jevolk jevolk added the feature New feature or functionality that didn't exist. label Feb 27, 2026
@Ludea
Copy link

Ludea commented Feb 27, 2026

@lytedev lytedev mentioned this pull request Mar 12, 2026
@lytedev
Copy link
Author

lytedev commented Mar 12, 2026

There is https://github.com/element-hq/matrix-authentication-service/tree/main/crates/cli which start MAS

Looks like that code is under an incompatible software license. I'm a big AGPL fan, but we can't use it here as far as I'm aware =(

@lytedev lytedev force-pushed the oidc-server branch 2 times, most recently from 7b49e20 to 1807530 Compare March 12, 2026 16:11
Implements a built-in OIDC authorization server that allows Matrix clients
like Element X to authenticate via OIDC, delegating user authentication
to upstream identity providers (e.g. Kanidm) through the existing SSO flow.

## Endpoints
- GET /_matrix/client/unstable/org.matrix.msc2965/auth_issuer
- GET /.well-known/openid-configuration
- POST /_tuwunel/oidc/registration (Dynamic Client Registration)
- GET /_tuwunel/oidc/authorize → SSO redirect → _complete bridge
- POST /_tuwunel/oidc/token (auth code exchange + refresh)
- POST /_tuwunel/oidc/revoke
- GET /_tuwunel/oidc/jwks
- GET /_tuwunel/oidc/userinfo
- GET /_tuwunel/oidc/account (placeholder)

## Spec compliance fixes
- OAuth error responses use RFC 6749 §5.2 format ({"error": "...", "error_description": "..."})
- PKCE code_verifier validation per RFC 7636 §4.1
- Scope token matching uses exact whitespace-delimited comparison per RFC 6749 §3.3
- Typed ProviderMetadata struct for the discovery document
- DCR includes policy_uri, tos_uri, software_id, software_version per RFC 7591

Refs: matrix-construct#246, matrix-construct#266
… sync

- Add policy_uri, tos_uri, software_id, software_version to DCR per RFC 7591
- Add code_verifier length (43-128) and charset validation per RFC 7636 §4.1
- Warn at startup if OIDC server enabled without identity providers
- Include Cargo.lock update for ring dependency
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or functionality that didn't exist.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants