Enabling SSO with QR Code Login

This interactive guide provides a step-by-step process for configuring Single Sign-On (SSO) and QR Code login for a self-hosted Element Synapse instance in Docker. The setup involves multiple components that must work together. This application breaks down the complex process into manageable, task-oriented sections to streamline your configuration.

Setup Components Overview

The entire process involves configuring three main areas: your Synapse server, an external Identity Provider (IdP), and a reverse proxy. The chart below visualizes these core components. Hover over each bar for a brief description of its role.

Prerequisites Checklist

Before you begin, ensure you have the following foundational elements in place. This checklist will help you verify your setup is ready for the configuration steps ahead.

  • โœ“ Running Dockerized Element Synapse Instance
  • โœ“ Registered Domain Name with DNS A/AAAA records
  • โœ“ Valid TLS/SSL Certificates (e.g., from Let's Encrypt)
  • โœ“ Reverse Proxy (Nginx, Apache, Caddy, etc.)
  • โœ“ Basic familiarity with Docker, YAML, and the command line

Core Synapse Setup

This section covers the initial, fundamental settings within your `homeserver.yaml` file. These parameters are the bedrock of your Synapse instance and are critical for SSO integration to function correctly.

Locating `homeserver.yaml`

In a Docker setup, this file resides in the volume you mounted to `/data` inside the container. You'll need to edit this file to apply all subsequent configurations. Remember that YAML is sensitive to indentation; incorrect spacing will cause errors.

`server_name`

Defines your server's public domain (e.g., `yourdomain.com`). It must be lowercase and **cannot be changed** after initial setup without a full reinstallation.

`public_baseurl`

The full public URL clients use to reach your server (e.g., `https://matrix.yourdomain.com`). This must be the URL as seen through your reverse proxy and is critical for OIDC callbacks.

`x_forwarded: true`

Under the `listeners` section, this setting tells Synapse to trust headers from your reverse proxy, which is essential for getting the correct client IP and protocol information.

Configure Identity Provider (OIDC)

Synapse delegates authentication to an external OpenID Connect (OIDC) provider. You must register Synapse as a client application with your chosen provider. This section guides you through the common parameters required.

IdP Client Registration Details

When registering Synapse with your IdP (like Google, Azure AD, Auth0, etc.), you will need to provide a `Redirect URI` and will receive a `Client ID` and `Client Secret`. The table below shows common configurations. Select a provider to see specific notes.

Redirect URI: [synapse public baseurl]/_synapse/client/oidc/callback
Scopes (Common): openid, profile, email

Enable SSO in Synapse

After setting up your IdP, you must configure Synapse to use it. This is done by adding an `oidc_providers` section to your `homeserver.yaml`. The official Docker images already include the necessary libraries.

`homeserver.yaml`: OIDC Configuration

The following snippet is an example for configuring Google as an OIDC provider. You must replace the placeholder values with the `Client ID` and `Client Secret` you obtained from your IdP. Pay close attention to the `user_mapping_provider` section, as it defines how user attributes from the IdP are mapped to Matrix user IDs.

# Example oidc_providers configuration
oidc_providers:
  - idp_id: google
    idp_name: Google
    issuer: "https://accounts.google.com/"
    client_id: "YOUR_GOOGLE_CLIENT_ID"
    client_secret: "YOUR_GOOGLE_CLIENT_SECRET"
    scopes: ["openid", "profile", "email"]
    user_mapping_provider:
      config:
        localpart_template: "{{ user.email.split('@')[0] }}"
        display_name_template: "{{ user.name }}"

User Mapping is Critical

The `localpart_template` determines the user's Matrix ID (the part before the colon). Ensure the claim you use (e.g., `user.email`, `user.preferred_username`) is unique for every user from your IdP. An incorrect mapping is a common point of failure.

Enable QR Code Login

QR code login is a user-friendly feature (MSC4108) that relies on the OIDC setup you've just configured. It requires enabling two distinct features in `homeserver.yaml`: the login flow itself and the underlying rendezvous module.

1. Enable Login Flow

First, add the `login_via_existing_session` block to enable the "login from another device" capability.

login_via_existing_session:
  enabled: true

2. Enable Rendezvous Module

Next, integrate the `matrix-http-rendezvous-synapse` module. This is a critical and often-missed step.

modules:
  - module: matrix_http_rendezvous_synapse.module.RendezvousModule
    config: {}

Synapse Version Matters

Ensure you are running Synapse v1.90.0 or newer. Older versions contain bugs related to QR code login, especially when a reverse proxy is used.

Setup Reverse Proxy

A reverse proxy (like Nginx) is essential for a production Synapse deployment. It handles TLS encryption, routes traffic correctly, and is required for OIDC and QR login to work reliably. This section provides an example Nginx configuration.

Example Nginx Configuration

This configuration listens on port 443, handles TLS, and proxies requests for the Matrix client API to your Synapse container. Pay close attention to the `proxy_set_header` directives and the `proxy_pass` URL.

server {
    listen 443 ssl http2;
    server_name your.matrix.domain.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location ~ ^(/_matrix|/_synapse/client) {
        proxy_pass http://synapse_container_ip:8008;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        
        client_max_body_size 50M;
    }
}

Test & Verify

After applying all configurations and restarting Synapse, it's time to test. Follow these steps to verify that both OIDC SSO and QR code login are functioning correctly. Monitor your Synapse logs (`docker logs synapse`) during testing to catch any errors.

Verifying OIDC SSO Flow

  1. Open an Element client and choose to sign in with your homeserver.
  2. A "Sign in with SSO" button (or your `idp_name`) should appear. Click it.
  3. You should be redirected to your IdP's login page. Authenticate there.
  4. After success, you should be redirected back to Element and logged in.
  5. Common errors include redirect loops (check `public_baseurl`) or metadata errors (check `issuer` URL).

Testing QR Code Login

  1. On a new, logged-out device/browser, navigate to the login screen and find the "Show QR code" option.
  2. On an existing, logged-in mobile client (like Element X), find the "Scan QR code" option.
  3. Scan the code from the new device with your mobile client.
  4. Approve the login on your mobile device.
  5. The new device should automatically log in and verify its E2EE session.

Key Takeaways & Recommendations

This setup is complex, with several potential points of failure. Here are the most critical recommendations to ensure a successful deployment.

  • 1๏ธโƒฃ

    Prioritize Synapse Version

    Update to Synapse v1.90.0 or newer to avoid known bugs with QR code login and reverse proxies.

  • 2๏ธโƒฃ

    Verify `public_baseurl`

    This URL must be perfectly accurate. Any mismatch between your `homeserver.yaml` and the actual public-facing URL will break OIDC redirects.

  • 3๏ธโƒฃ

    Check the Rendezvous Module

    Don't forget to add the `matrix-http-rendezvous-synapse` module to your configuration. QR login will fail without it.

  • 4๏ธโƒฃ

    Monitor Logs

    Your Synapse and reverse proxy logs are your best friends for debugging. They will provide specific error messages to guide your troubleshooting.