Delegated authentication with OIDC

Continuwuity supports delegating user authentication to an external identity provider that implements the OpenID Connect (OIDC) specification, such as Authentik, Kanidm, or Keycloak.

Delegated authentication and legacy logins

When delegated authentication is configured, Continuwuity will disable its support for legacy logins. Only clients that support OAuth will be able to login.

An account on the homeserver can only be associated with one OIDC subject claim - that is, one account on the identity provider - at a time. Linking an account will also prevent the user from deactivating it themselves.

Instructions

A simple OIDC configuration is as easy as creating a new OIDC application in your identity provider's settings and supplying Continuwuity with the client ID and client secret.

Configuring the OIDC provider

This guide will use Kanidm as an example, but the described steps are broadly applicable to other identity providers. Contributions for them are welcome.

First, create a new application for Continuwuity in your identity provider.

# Here, `c10y` is the client ID that Kanidm will use, and `Continuwuity` is the display name.
# Other identity providers may generate a client ID for you.
# Use the domain that clients can reach Continuwuity at, which may not be the same as your server name
# if you have configured well-known delegation.
kanidm system oauth2 create c10y Continuwuity https://matrix.yourdomain.com

Configure the redirect URL that Continuwuity uses.

kanidm system oauth2 add-redirect-url c10y https://matrix.yourdomain.com/_continuwuity/oidc/complete

Allow Continuwuity to request the openid scope. Other identity providers may not require this step.

kanidm system oauth2 update-scope-map c10y idm_all_persons openid

Find the client secret that was generated. Other identity providers may show this information in their web UI.

kanidm system oauth2 show-basic-secret c10y
d1qgx352kkuvs1j70b6w293d65x68jve1f7b27fyk90gjhpr

Configuring Continuwuity

Configure Continuwuity with the client ID, client secret, and discovery URL provided from the steps above. Kanidm has a different discovery URL for each client, but other identity providers may have a single discovery URL at the root of their domain.

[global.oauth.oidc]

# `/.well-known/openid-configuration` will be appended automatically
discovery_url = "https://idm.example.com/oauth2/openid/c10y"

# This may be randomly generated by your identity provider. Kanidm requires
# you to set it manually when you create the application.
client_id = "c10y"

# From the previous step
client_secret = "d1qgx352kkuvs1j70b6w293d65x68jve1f7b27fyk90gjhpr"

Testing that it works

Finally, restart Continuwuity, and log out and back in again. Your client should prompt you to continue in your web browser and open a webpage with the Continuwuity logo that allows you to continue in your identity provider. Once you log in successfully there, you will be prompted to choose a user ID -- to link your existing account, enter its user ID, and then your old password.

Continuwuity offers several additional configuration options to tweak its integration with your identity provider. Review the [global.oauth.oidc] section towards the bottom of the reference configuration for a complete list of options and documentation.

Advanced options

Minting tokens for non-OIDC accounts

With OIDC delegation enabled, accounts without an OIDC mapping (such as bot accounts) can still be created via the admin commands, but will not be able to log in to the homeserver. To accommodate this, homeserver admins can use the !admin users issue-token command to issue tokens for them. This command requires the account to have set a local password, which can be done with !admin users reset-password.

Manually linking users to OIDC claims

To view associations between local users and their linked subject claim, issue the following command:

!admin query raw raw-iter openidsubject_localpart
("1d3fc994-3947-406d-b22c-0fc529baf235", "john")
("ba543628-e6a5-45d8-9bd2-6cc497400136", "jane")

These associations can be changed manually with the !admin oidc commands, which are useful to debug some account linkage issues. For example, to link the user jane to a new Subject Identifier claim of 721c36a8-ce04-4474-8e97-b62655b07340:

!admin oidc unlink ba543628-e6a5-45d8-9bd2-6cc497400136
Subject `ba543628-e6a5-45d8-9bd2-6cc497400136` unlinked.
!admin oidc link jane 721c36a8-ce04-4474-8e97-b62655b07340
Subject `721c36a8-ce04-4474-8e97-b62655b07340` linked to account @jane:example.com.
!admin query raw raw-iter openidsubject_localpart
("1d3fc994-3947-406d-b22c-0fc529baf235", "john")
("721c36a8-ce04-4474-8e97-b62655b07340", "jane")

Decommissioning OIDC delegation

It is possible to revert to using the internal database for authentication. First, comment out the [global.oauth.oidc] section in your config file and restart the homeserver. Then, execute the !admin users reset-password --convert-to-local-account for each user to assign them a local password and convert their linked accounts into local ones.