1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

docs: expand the setup documentation and configuration file reference

This commit is contained in:
Quentin Gliech
2023-07-26 18:29:52 +02:00
parent 9c7bb69914
commit 1d2ebe3dac
7 changed files with 444 additions and 68 deletions

View File

@ -12,7 +12,6 @@
- [Database setup](./setup/database.md)
- [Homeserver configuration](./setup/homeserver.md)
- [Configuring a reverse proxy](./setup/reverse-proxy.md)
- [Email configuration](./setup/email.md)
- [Running the service](./setup/running.md)
# Usage

View File

@ -1,4 +1,53 @@
# Setup introduction
# Planning the installation
This part of the documentation goes through installing the service, the important parts of the configuration file, and how to run the service.
Before going through the installation, it is important to understand the different components of an OIDC-native Matrix homeserver, and how they interact with each other.
It is meant to complement the homeserver, replacing the internal authentication mechanism with the authentication service.
Making a homeserver deployment OIDC-native radically shifts the authentication model: the homeserver is no longer responsible for managing user accounts and sessions.
The authentication service becomes the source of truth for user accounts and access tokens, and the homeserver only verifies the validity of the tokens it receives through the service.
At time of writing, the authentication service is meant to be run on a standalone domain name (e.g. `auth.example.com`), and the homeserver on another (e.g. `matrix.example.com`).
This domain will be user-facing as part of the authentication flow.
When a client initiates an authentication flow, it will discover the authentication service through the deployment `.well-known/matrix/client` endpoint.
This file will refer to an `issuer`, which is the canonical name of the authentication service instance.
Out of that issuer, it will discover the rest of the endpoints by calling the `[issuer]/.well-known/openid-configuration` endpoint.
By default, the `issuer` will match the root domain where the service is deployed (e.g. `https://auth.example.com/`), but it can be configured to be different.
An example setup could look like this:
- The deployment domain is `example.com`, so Matrix IDs look like `@user:example.com`
- The issuer chosen is `https://example.com/`
- The homeserver is deployed on `matrix.example.com`
- The authentication service is deployed on `auth.example.com`
- Calling `https://example.com/.well-known/matrix/client` returns the following JSON:
```json
{
"m.homeserver": {
"base_url": "https://matrix.example.com"
},
"org.matrix.msc2965.authentication": {
"issuer": "https://example.com/",
"account": "https://auth.example.com/account"
}
}
```
- Calling `https://example.com/.well-known/openid-configuration` returns a JSON document similar to the following:
```json
{
"issuer": "https://example.com/",
"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/oauth2/token",
"jwks_uri": "https://auth.example.com/oauth2/keys.json",
"registration_endpoint": "https://auth.example.com/oauth2/registration",
"//": "..."
}
```
With the installation planned, it is time to go through the installation and configuration process.
The first section focuses on [installing the service](./installation.md).

View File

@ -69,6 +69,6 @@ mas-cli server --migrate
Once the database is up, the remaining steps are to:
- [Set up the connection to the homeserver (recommended)](./homeserver.md)
- [Setup email sending (optional)](./email.md)
- [Setup email sending (optional)](../usage/configuration.md#email)
- [Configure a reverse proxy (optional)](./reverse-proxy.md)
- [Run the service](./running.md)

View File

@ -1,3 +0,0 @@
# Email configuration
TODO: explain how to configure the email backend in the `email` section of the configuration file.

View File

@ -1,3 +1,115 @@
# Configuring a reverse proxy
TODO: explain how to run a reverse proxy in front of the service, and which C-S API endpoints need to be proxied to the service.
Although the service can be exposed directly to the internet, including handling the TLS termination, many deployments will want to run a reverse proxy in front of the service.
In those configuration, the service should be configured to listen on `localhost` or Unix domain socket.
## Example configuration
```yaml
http:
public_base: https://auth.example.com/
listeners:
- name: web
resources:
- name: discovery
- name: human
- name: oauth
- name: compat
- name: graphql
# Uncomment to serve the assets by the service
#- name: assets
# path: ./share/assets/
binds:
# Bind on a local port
- host: localhost
port: 8080
# OR bind on a Unix domain socket
#- path: /var/run/mas.sock
# Optional: use the PROXY protocol
#proxy_protocol: true
```
## Example nginx configuration
Note that the assets can be served directly by nginx, and the `assets` resource can be removed from the service configuration.
```nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name auth.example.com;
ssl_certificate path/to/fullchain.pem;
ssl_certificate_key path/to/privkey.pem;
location / {
proxy_pass http://localhost:8080;
# OR via the Unix domain socket
#proxy_pass http://unix:/var/run/mas.sock;
proxy_http_version 1.1;
# Optional: use the PROXY protocol
#proxy_protocol on;
}
# Optional: serve the assets directly
location /assets/ {
root /path/to/share/assets/;
# Serve pre-compressed assets
gzip_static on;
# With the ngx_brotli module installed
# https://github.com/google/ngx_brotli
#brotli_static on;
# Cache assets for a year
expires 365d;
}
}
```
For the compatibility layer, the following endpoints need to be proxied to the service:
- `/_matrix/client/*/login`
- `/_matrix/client/*/logout`
- `/_matrix/client/*/refresh`
For example, a nginx configuration could look like:
```nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name matrix.example.com;
# Forward to the auth service
location ~ ^/_matrix/client/(.*)/(login|logout|refresh) {
proxy_pass http://localhost:8080;
# OR via the Unix domain socket
#proxy_pass http://unix:/var/run/mas.sock;
proxy_http_version 1.1;
# Optional: use the PROXY protocol
#proxy_protocol on;
}
# Forward to Synapse
# as per https://matrix-org.github.io/synapse/latest/reverse_proxy.html#nginx
location ~ ^(/_matrix|/_synapse/client) {
proxy_pass http://localhost: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;
proxy_http_version 1.1;
}
}
```

View File

@ -21,4 +21,31 @@ Other than the binary, the service needs a few files to run:
Be sure to check the [installation instructions](./installation.md) for more information on how to get these files, and make sure the configuration file is updated accordingly.
TODO: systemd service, docker, etc.
## Configure the HTTP server
The service can be configured to have multiple HTTP listeners, serving different resources.
See the [`http.listeners`](../usage/configuration.md#http) configuration section for more information.
The service needs to be aware of the public URL it is served on, regardless of the HTTP listeners configuration.
This is done using the [`http.public_base`](../usage/configuration.md#http) configuration option.
By default, the OIDC issuer advertised by the `/.well-known/openid-configuration` endpoint will be the same as the `public_base` URL, but can be configured to be different.
## Tweak the remaining configuration
A few configuration sections might still require some tweaking, including:
- [`telemetry`](../usage/configuration.md#telemetry): to setup metrics, tracing and Sentry crash reporting
- [`email`](../usage/configuration.md#email): to setup email sending
- [`password`](../usage/configuration.md#password): to enable/disable password authentication
- [`upstream_oauth`](../usage/configuration.md#upstream-oauth): to configure upstream OAuth providers
## Run the service
Once the configuration is done, the service can be started with the [`mas-cli server`](../usage/cli/server.md) command:
```sh
mas-cli server
```
It is advised to run the service as a non-root user, using a tool like [`systemd`](https://www.freedesktop.org/wiki/Software/systemd/) to manage the service lifecycle.

View File

@ -6,34 +6,81 @@ Controls the web server.
```yaml
http:
listeners:
- name: web
resources:
- name: discovery
- name: human
- name: oauth
- name: compat
- name: graphql
playground: true
- name: assets
# Path from which to serve static files
path: ./frontend/dist/
binds:
# On what address and port the server should listen to
- address: '[::]:8080'
proxy_protocol: false
- name: internal
resources:
- name: health
binds:
- host: localhost
port: 8081
proxy_protocol: false
# Public URL base used when building absolute public URLs
public_base: http://[::]:8080/
issuer: http://[::]:8080/
public_base: https://auth.example.com/
# OIDC issuer advertised by the service. Defaults to `public_base`
issuer: https://example.com/
# List of HTTP listeners, see below
listeners:
# ...
```
### `http.listeners`
Each listener can serve multiple resources, and listen on multiple TCP ports or UNIX sockets.
```yaml
http:
listeners:
# The name of the listener, used in logs and metrics
- name: web
# List of resources to serve
resources:
# Serves the .well-known/openid-configuration document
- name: discovery
# Serves the human-facing pages, such as the login page
- name: human
# Serves the OAuth 2.0/OIDC endpoints
- name: oauth
# Serves the Matrix C-S API compatibility endpoints
- name: compat
# Serve the GraphQL API used by the frontend,
# and optionally the GraphQL playground
- name: graphql
playground: true
# Serve the given folder on the /assets/ path
- name: assets
path: ./share/assets/
# List of addresses and ports to listen to
binds:
# First option: listen to the given address
- address: '[::]:8080'
# Second option: listen on the given host and port combination
- host: localhost
port: 8081
# Third option: listen on the given UNIX socket
- socket: /tmp/mas.sock
# Fourth option: grab an already open file descriptor given by the parent process
# This is useful when using systemd socket activation
- fd: 1
# Kind of socket that was passed, defaults to tcp
kind: tcp # or unix
# Whether to enable the PROXY protocol on the listener
proxy_protocol: false
# If set, makes the listener use TLS with the provided certificate and key
tls:
#certificate: <inline PEM>
certificate_file: /path/to/cert.pem
#key: <inline PEM>
key_file: /path/to/key.pem
#password: <password to decrypt the key>
#password_file: /path/to/password.txt
```
The following additional resources are available, although it is recommended to serve them on a separate listener, not exposed to the public internet:
- `name: prometheus`: serves the a Prometheus-compatible metrics endpoint on `/metrics`, if the Prometheus exporter is enabled in `telemetry.metrics.exporter`.
- `name: health`: serves the health check endpoint on `/health`.
## `database`
Configure how to connect to the PostgreSQL database.
@ -61,6 +108,23 @@ database:
max_lifetime: 1800
```
## `matrix`
Settings related to the connection to the Matrix homeserver
```yaml
matrix:
# The homeserver name, as per the `server_name` in the Synapse configuration file
homeserver: example.com
# Shared secret used to authenticate the service to the homeserver
# This must be of high entropy, because leaking this secret would allow anyone to perform admin actions on the homeserver
secret: "SomeRandomSecret"
# URL to which the homeserver is accessible from the service
endpoint: "http://localhost:8008"
```
## `templates`
Allows loading custom templates
@ -83,7 +147,7 @@ List of OAuth 2.0/OIDC clients and their keys/secrets. Each `client_id` must be
clients:
# Confidential client
- client_id: 000000000000000000000FIRST
client_auth_method: clent_secret_post
client_auth_method: client_secret_post
client_secret: secret
# List of authorized redirect URIs
redirect_uris:
@ -93,6 +157,8 @@ clients:
client_auth_method: none
```
**Note:** this list is not used at runtime, and any modification of this list must be synced to the database using the [`config sync`](../usage/cli/config.md#config-sync---prune---dry-run) command.
## `secrets`
Signing and encryption secrets
@ -100,6 +166,7 @@ Signing and encryption secrets
```yaml
secrets:
# Encryption secret (used for encrypting cookies and database fields)
# This must be a 32-byte long hex-encoded key
encryption: c7e42fb8baba8f228b2e169fdf4c8216dffd5d33ad18bafd8b928c09ca46c718
# Signing keys
@ -107,43 +174,82 @@ secrets:
# It needs at least an RSA key to work properly
- kid: "ahM2bien"
key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7iinu0NXjWP5/
/4OqyqOMI5uLJIHSrYIZLUlWMldtXmNy0c/pan+gxvZogiYx0cNydO/FogNbC4oD
yj7RIF+QcWJ8wcdG94/P+Xs3HFQzIZfwF+78RWQQJ7nQFekXJ1wQSXV4giw9b4XR
YkoVhHlyxyYGBFffO//DtYVto4uHvXVL0M27bV6l1K8VKspF72gb8Vt44V8OX5hT
sEsYW8SjOD1neEoVKiY6XP63cAG9FTB4a4sKkcUqwjrKEYKio/JLujmCl96eLN18
cuqr6XuSDKvuVJtb+ZNLJi61vIOlD8cz3wu37hr3PCUZ+Ko9Ley+QfopJ3WYFxrI
IjQKb0W5AgMBAAECggEBAK87ZfsTfwczPHn1Ed4gAbkL/GaC8hscrJdBzWiRGUfE
DkBW82IydJaR0ePM2EtsqKblxLRxsZj8qzTnYNKe4SxiBZh0p/MTlnjJr+vKuJIe
LY3VjySA4gKGXASmtGlCCa/eM7kqSJQPBIakxHxej+xDULAGluSrd0wy7D2JtvJY
5By+2apILUujBZZU/iUyB2AqK6IrzALo2gTV9Jhun9Wz0k3DXZBGd41v42BhZ+Rx
bHHgpuUTyDQOpKqJ5g1kN4qGlN/CeoontxcE5NOSgtipWeQEuelT8t4eZKHTXBS+
Byd+uFe8oobWRY2crLptX8TZEENH7wX7y2YgNYUbeZECgYEA95YRhDuukcrDiNuF
fOXs+99XFORsKTbtZYwrouc7PI2CYb0I9ezoQMu3dzWIwOTUQHea5qCo/dYzbeED
fNzwPb2zaWaWFbkEWVTOwRewL+NfP+Ek2Nml+dVJm3d35qdIHYV+9gAcI87iCHxA
gqc13ZS4ba+5/vV6OYwNSAeW0TcCgYEAwem1F9zhVVOIReh3JaJLpZn0xuvZs5kN
TzvFXar33LKdulk5liC3L7ZrqspGESU0JC3pANR8PwuNteEEdHnkC5UTEqMf/fxG
j5CObJl+e2CiV2CNbe+3IQ1PKSxopD+Sq65ze7aP2moVZg94mbw4dsN+uY5QEql1
Bmq0b7Wm2I8CgYBOqlDgefIKgqlEF7O/LnLwyFKr4bP4GGqvZC0NMnkg0TmHAoAR
W3ej9tZROyI7X7mMzjPaaVuoY2Gt3Nu11aFDjL2vlJfFSSb3lzmmInepj43ZBxkl
CWpyCfG8QuZG1AnWz266jOhj/DzXQ1tf5+72e2Vp/HaVaruuAzDJHRgvWwKBgAHy
aMEOlKyYpBufk+Kq2HuXKh/9KjhlZv7OqNKh7s8mc/L1BmD9fxlZiYczdLSjXPyo
AVjiyUSQxyF2WucYejOrkX90Z9PS/ppeZy+r8tsmQzsBWyopZ/tK+Op+6aYMhVp3
6+zoDlWxDvnxWdKhUyfOGq2eQiuNzAD+fUVJ25z9AoGARUJ4C87X7vH4QnsIE0g+
ni0xSs8DgSq0v8+cJ7xwyN+NnC6eeU9N2U/m/5anLEM2GFjo4kghLDkC/2urc8dD
UtiisQjWz3O88QHqOvclEAmveuxfCYr/A/CWGdkH3YoK+AXIj3fkwb2Qd//rJ9zL
dT3XPCRatoVKLNKzUGNVcFM=
-----END PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuf28zPUp574jDRdX6uN0d7niZCIUpACFo+Po/13FuIGsrpze
yMX6CYWVPalgXW9FCrhxL+4toJRy5npjkgsLFsknL5/zXbWKFgt69cMwsWJ9Ra57
bonSlI7SoCuHhtw7j+sAlHAlqTOCAVz6P039Y/AGvO6xbC7f+9XftWlbbDcjKFcb
pQilkN9qtkdEH7TLayMAFOsgNvBlwF9+oj9w5PIk3veRTdBXI4GlHjhhzqGZKiRp
oP9HnycHHveyT+C33vuhQso5a3wcUNuvDVOixSqR4kvSt4UVWNK/KmEQmlWU1/m9
ClIwrs8Q79q0xkGaSa0iuG60nvm7tZez9TFkxwIDAQABAoIBAHA5YkppQ7fJSm0D
wNDCHeyABNJWng23IuwZAOXVNxB1bjSOAv8yNgS4zaw/Hx5BnW8yi1lYZb+W0x2u
i5X7g91j0nkyEi5g88kJdFAGTsM5ok0BUwkHsEBjTUPIACanjGjya48lfBP0OGWK
LJU2Acbjda1aeUPFpPDXw/w6bieEthQwroq3DHCMnk6i9bsxgIOXeN04ij9XBmsH
KPCP2hAUnZSlx5febYfHK7/W95aJp22qa//eHS8cKQZCJ0+dQuZwLhlGosTFqLUm
qhPlt/b1EvPPY0cq5rtUc2W31L0YayVEHVOQx1fQIkH2VIUNbAS+bfVy+o6WCRk6
s1XDhsECgYEA30tykVTN5LncY4eQIww2mW8v1j1EG6ngVShN3GuBTuXXaEOB8Duc
yT7yJt1ZhmaJwMk4agmZ1/f/ZXBtfLREGVzVvuwqRZ+LHbqIyhi0wQJA0aezPote
uTQnFn+IveHGtpQNDYGL/UgkexuCxbc2HOZG51JpunCK0TdtVfO/9OUCgYEA1TuS
2WAXzNudRG3xd/4OgtkLD9AvfSvyjw2LkwqCMb3A5UEqw7vubk/xgnRvqrAgJRWo
jndgRrRnikHCavDHBO0GAO/kzrFRfw+e+r4jcLl0Yadke8ndCc7VTnx4wQCrMi5H
7HEeRwaZONoj5PAPyA5X+N/gT0NNDA7KoQT45DsCgYBt+QWa6A5jaNpPNpPZfwlg
9e60cAYcLcUri6cVOOk9h1tYoW7cdy+XueWfGIMf+1460Z90MfhP8ncZaY6yzUGA
0EUBO+Tx10q3wIfgKNzU9hwgZZyU4CUtx668mOEqy4iHoVDwZu4gNyiobPsyDzKa
dxtSkDc8OHNV6RtzKpJOtQKBgFoRGcwbnLH5KYqX7eDDPRnj15pMU2LJx2DJVeU8
ERY1kl7Dke6vWNzbg6WYzPoJ/unrJhFXNyFmXj213QsSvN3FyD1pFvp/R28mB/7d
hVa93vzImdb3wxe7d7n5NYBAag9+IP8sIJ/bl6i9619uTxwvgtUqqzKPuOGY9dnh
oce1AoGBAKZyZc/NVgqV2KgAnnYlcwNn7sRSkM8dcq0/gBMNuSZkfZSuEd4wwUzR
iFlYp23O2nHWggTkzimuBPtD7Kq4jBey3ZkyGye+sAdmnKkOjNILNbpIZlT6gK3z
fBaFmJGRJinKA+BJeH79WFpYN6SBZ/c3s5BusAbEU7kE5eInyazP
-----END RSA PRIVATE KEY-----
- kid: "iv1aShae"
key: |
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgaa7KvLdq72Nb7i7pGm/6
SCW0RAKFcVwz7P9/8Wo2TTShRANCAATlTf0uyezm7riXjZdn1XND00uf4d1tc1jc
V4CiFiDQsDX+3znAGxqhTuoOkVn/G5lwgE1cgTX57r9cyYkso9UY
-----END PRIVATE KEY-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIE8yeUh111Npqu2e5wXxjC/GA5lbGe0j0KVXqZP12vqioAcGBSuBBAAK
oUQDQgAESKfUtKaLqCfhK+p3z870W59yOYvd+kjGWe+tK16SmWzZJbRCgdHakHE5
MC6tJRnvedsYoKTrYoDv/XZIBI9zlA==
-----END EC PRIVATE KEY-----
```
### `secrets.keys`
The service can use a number of key types for signing.
The following key types are supported:
- RSA
- ECDSA with the P-256 (`prime256v1`) curve
- ECDSA with the P-384 (`secp384r1`) curve
- ECDSA with the K-256 (`secp256k1`) curve
Each entry must have a unique (and arbitrary) `kid`, plus the key itself.
The key can either be specified inline (with the `key` property), or loaded from a file (with the `key_file` property).
The following key formats are supported:
- PKCS#1 PEM or DER-encoded RSA private key
- PKCS#8 PEM or DER-encoded RSA or ECDSA private key, encrypted or not
- SEC1 PEM or DER-encoded ECDSA private key
For PKCS#8 encoded keys, the `password` or `password_file` properties can be used to decrypt the key.
## `passwords`
Settings related to the local password database
```yaml
passwords:
# Whether to enable the password database.
# If disabled, users will only be able to log in using upstream OIDC providers
enabled: true
# List of password hashing schemes being used
# /!\ Only change this if you know what you're doing
# TODO: document this section better
schemes:
- version: 1
algorithm: argon2id
```
## `policy`
Policy settings
@ -163,7 +269,7 @@ policy:
allow_insecure_uris: true
# Registration using passwords
passwords:
passwords:
# minimum length of a password. default: ?
min_length: 8
# require at least one lowercase character in a password. default: false
@ -173,3 +279,89 @@ policy:
# require at least one number in a password. default: false
require_number: true
```
## `telemetry`
Settings related to metrics and traces
```yaml
telemetry:
tracing:
# List of propagators to use for extracting and injecting trace contexts
propagators:
# Propagate according to the W3C Trace Context specification
- tracecontext
# Propagate according to the W3C Baggage specification
- baggage
# Propagate trace context with Jaeger compatible headers
- jaeger
# Propagate trace context with Zipkin compatible headers (single `b3` header variant)
- b3
# Propagate trace context with Zipkin compatible headers (multiple `x-b3-*` headers variant)
- b3multi
# The default: don't export traces
exporter: none
# Export traces to an OTLP-compatible endpoint
#exporter: otlp
#endpoint: https://localhost:4317
# Export traces to a Jaeger endpoint
#exporter: jaeger
#protocol: http/thrift.binary | udp/thrift.compact
#endpoint: http://localhost:14268/api/traces # for http/thrift.binary
#username: username # for http/thrift.binary
#password: password # for http/thrift.binary
#agent_host: localhost # for udp/thrift.compact
#agent_port: 6831 # for udp/thrift.compact
# Export traces to a Zipkin endpoint
#exporter: zipkin
#collector_endpoint: http://localhost:9411/api/v2/spans
metrics:
# The default: don't export metrics
exporter: none
# Export metrics to an OTLP-compatible endpoint
#exporter: otlp
#endpoint: https://localhost:4317
# Export metrics by exposing a Prometheus endpoint
# This requires mounting the `prometheus` resource to an HTTP listener
#exporter: prometheus
sentry:
# DSN to use for sending errors and crashes to Sentry
dsn: https://public@host:port/1
```
### `email`
Settings related to sending emails
```yaml
email:
from: '"The almighty auth service" <auth@example.com>'
reply_to: '"No reply" <no-reply@example.com>'
# Default transport: don't send any emails
transport: blackhole
# Send emails using SMTP
#transport: smtp
#mode: plain | tls | starttls
#hostname: localhost
#port: 587
#username: username
#password: password
# Send emails by calling a local sendmail binary
#transport: sendmail
#command: /usr/sbin/sendmail
# Send emails through the AWS SESv2 API
# This uses the AWS SDK, so the usual AWS environment variables are supported
#transport: aws_ses
```