No description
  • Go 60.4%
  • TypeScript 21.7%
  • CSS 16.1%
  • templ 1.2%
  • Dockerfile 0.6%
Find a file
2026-08-18 01:14:26 +03:00
cmd demo 2026-08-18 00:39:36 +03:00
docs radme 2026-08-18 00:31:18 +03:00
internal alogo 2026-08-18 00:15:02 +03:00
web fix svg issue 2026-08-18 01:14:26 +03:00
.dockerignore fix svg issue 2026-08-18 01:14:26 +03:00
.gitignore migration to forgejo 2026-08-17 22:31:46 +03:00
CLAUDE.md name 2026-08-17 23:28:50 +03:00
Dockerfile oci 2026-08-17 23:24:54 +03:00
Dockerfile.demo a 2026-08-18 00:43:40 +03:00
go.mod migration to forgejo 2026-08-17 22:31:46 +03:00
go.sum migration to forgejo 2026-08-17 22:31:46 +03:00
matoidc alogo 2026-08-18 00:15:02 +03:00
mise.toml migration to forgejo 2026-08-17 22:31:46 +03:00
README.md readme 2026-08-18 00:52:43 +03:00

matOIDC

Log in with Matrix

matOIDC is an oAuth2 broker to prove Matrix identity without granting access. To an application it looks like an ordinary OpenID Connect provider. Behind that, it owns no users and just authenticates people against their own Matrix homeserver, whichever that is. A service adds one OIDC integration and gets federated Matrix login without being Matrix-aware.

Want to see how it works? Click the login button at the top of this readme.

The security property

The user's Matrix credentials and Matrix access token never touch any backend, not the relying party's, and not matOIDC's.

The login UI is a browser-side application. Credentials go only from your browser to your homeserver. The only thing that reaches the matOIDC backend is a Matrix OpenID token, a single use key proving the user's MXID.

Display name and avatar are self-asserted profile data, fetched in the browser and sanitised server-side before entering an ID token.

How a login flows

  1. The RP redirects to /authorize (standard OIDC code flow).
  2. The user names their homeserver
  3. The browser authenticates directly with the homeserver, with the Matrix oAuth 2.0 API on modern servers, or legacy /login with password/SSO.
  4. The browser mints an OpenID token and posts it, including optional profile data to matOIDC.
  5. matOIDC resolves the homeserver's federation endpoint and exchanges the token.
  6. After giving consent, the user follows the redirect back to the RP with an authorization code.

Running

go build ./cmd/matoidc
./matoidc -listen :8080 -issuer https://id.example.com -db matoidc.db

cd web/app && bun install && bun run build

Container

A pre-built image is published to forgejo.perny.dev/perny/matoidc.

docker run -p 8080:8080 -v matoidc-data:/data \
  -e MATOIDC_ISSUER=https://id.example.com \
  forgejo.perny.dev/perny/matoidc:latest

The image listens on 8080, stores the persistent data at /data.

Or with Docker Compose:

services:
  matoidc:
    image: forgejo.perny.dev/perny/matoidc:latest
    ports:
      - "8080:8080"
    volumes:
      - matoidc-data:/data
    environment:
      MATOIDC_ISSUER: https://id.example.com
      # MATOIDC_REGISTRATION_TOKEN: change-me

volumes:
  matoidc-data:

Flags / environment:

Flag Env Default
-listen :8080 listen address
-issuer MATOIDC_ISSUER http://localhost:8080 public issuer URL, no trailing slash
-db MATOIDC_DB matoidc.db SQLite path (WAL)
-static MATOIDC_STATIC web/static built browser app
-registration-token MATOIDC_REGISTRATION_TOKEN (open) if set, required as a Bearer token on /register

Registering a relying party

Dynamic registration per RFC 7591:

curl -X POST https://id.example.com/register \
  -H 'Content-Type: application/json' \
  -d '{
    "redirect_uris": ["https://app.example.org/callback"],
    "client_name": "My App",
    "homeserver_allowlist": ["example.com"]
  }'

homeserver_allowlist is optional: empty means any homeserver is accepted. Non-empty restricts logins to exactly those server names. Redirect URIs must be https:// (or http:// loopback for native apps).

Then it's plain OIDC: discovery at /.well-known/openid-configuration, response_type=code with PKCE S256, RS256 ID tokens. Claims:

  • sub is the full MXID (@alice:example.com)
  • matrix_user_id, matrix_server_name, preferred_username
  • name, picture (data URI) with the profile scope, when the user has them

Developing

go test ./...
templ generate
cd web/app && bunx tsc --noEmit
cd web/app && bun run build

The matOIDC logo and the "Log in with Matrix" badge are based on the Matrix logo, a trademark of The Matrix.org Foundation. Their use does not imply endorsement or affiliation.