Compare commits

...

18 Commits

Author SHA1 Message Date
3f488167bc chore: publish 7.1.0+v1.149.1 release 2026-05-11 13:19:17 +02:00
c71dc162cb readd cleanup trap to mas migration script 2026-04-09 11:51:39 +02:00
625b0381f8 readd cleanup trap to mas migration script 2026-04-09 11:48:25 +02:00
7492e8bd4e add mas healthcheck 2026-04-09 10:54:51 +02:00
60bd8b1b49 provide readme for mas setup and migration 2026-04-08 14:06:10 +02:00
6f47fca73b add script to perform mas migration compatibility check 2026-04-08 13:18:28 +02:00
dd92cd4bd7 add config for upstream oidc provider for mas 2026-04-08 13:02:22 +02:00
cf30cebf8e add function to init mas database 2026-04-07 16:20:34 +02:00
5481b7e31c add initial mas setup 2026-04-07 14:59:19 +02:00
8a7978b388 add docs for breaking share secret authenticator 2026-03-31 15:17:29 +02:00
d0d5cfb1bc chore: publish 7.0.2+v1.149.1 release 2026-03-31 14:55:43 +02:00
3d13505330 bumb python version for shared secret authenticator 2026-03-31 14:53:32 +02:00
68fd515297 chore: publish 7.0.1+v1.149.1 release 2026-03-30 13:04:48 +02:00
01e3feb1cf fix: healthchecks and restart_policy for web container 2026-03-30 13:02:27 +02:00
c51120c41a chore: publish 7.0.0+v1.149.1 release 2026-03-25 01:20:30 +01:00
b81fecdd23 chore: replace depricated traefik.docker.* with traefik.swarm.* 2026-03-17 17:26:54 +01:00
18b658c452 chore: publish 6.8.3+v1.139.2 release 2026-03-05 14:49:59 +01:00
553fee0e9d feat: compress db dumps 2026-03-05 14:49:11 +01:00
15 changed files with 776 additions and 373 deletions

View File

@ -19,6 +19,82 @@ SECRET_FORM_SECRET_VERSION=v1
SECRET_MACAROON_VERSION=v1 SECRET_MACAROON_VERSION=v1
SECRET_REGISTRATION_VERSION=v1 SECRET_REGISTRATION_VERSION=v1
## Authentication
# All login / SSO / MAS-related toggles in one place.
### Local password & registration (Synapse native)
# With MAS_ENABLED=1 you must set PASSWORD_LOGIN_ENABLED=false — Synapse forbids legacy password DB alongside matrix_authentication_service.
PASSWORD_LOGIN_ENABLED=true
ENABLE_REGISTRATION=false
# Token based registration. Enable ADMIN_INTERFACE (below) to use the admin interface to generate tokens.
#REGISTRATION_REQUIRES_TOKEN=true
### OIDC via Keycloak-shaped API (e.g. Authentik)
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak.yml"
#KEYCLOAK_ENABLED=1
#KEYCLOAK_ID=keycloak
#KEYCLOAK_NAME=
#KEYCLOAK_URL=
#KEYCLOAK_CLIENT_ID=
#KEYCLOAK_CLIENT_DOMAIN=
#KEYCLOAK_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1
### Second OIDC provider (compose.keycloak2.yml)
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak2.yml"
#KEYCLOAK2_ENABLED=1
#KEYCLOAK2_ID=keycloak2
#KEYCLOAK2_NAME=
#KEYCLOAK2_URL=
#KEYCLOAK2_CLIENT_ID=
#KEYCLOAK2_CLIENT_DOMAIN=
#KEYCLOAK2_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK2_CLIENT_SECRET_VERSION=v1
### Third OIDC provider (compose.keycloak3.yml)
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak3.yml"
#KEYCLOAK3_ENABLED=1
#KEYCLOAK3_ID=keycloak3
#KEYCLOAK3_NAME=
#KEYCLOAK3_URL=
#KEYCLOAK3_CLIENT_ID=
#KEYCLOAK3_CLIENT_DOMAIN=
#KEYCLOAK3_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION=v1
### Matrix Authentication Service (MAS) — Element X / OIDC-native auth
#COMPOSE_FILE="$COMPOSE_FILE:compose.mas.yml"
#MAS_ENABLED=1
#PASSWORD_LOGIN_ENABLED=false
#SECRET_MAS_ENCRYPTION_VERSION=v1 # length=64 # charset=hex
#SECRET_MAS_SYNAPSE_SHARED_VERSION=v1 # length=64 # charset=hex
# PEM private key: abra cannot generate this format — insert only (e.g. openssl genrsa 2048 | abra app secret insert …)
#SECRET_MAS_SIGNING_RSA_VERSION=v1 # generate=false
#### MAS upstream OIDC provider (e.g. Authentik)
# Create a new OAuth2 app in your IdP with redirect URI: https://<DOMAIN>/upstream/callback/<MAS_UPSTREAM_PROVIDER_ID>
#COMPOSE_FILE="$COMPOSE_FILE:compose.mas-upstream.yml"
#MAS_UPSTREAM_PROVIDER_ID= # ULID, e.g. 01JSHPZHAXC50QBKH67MH33TNF — generate at https://www.ulidtools.com
#MAS_UPSTREAM_ISSUER= # e.g. https://auth.example.com/application/o/matrix-mas/
#MAS_UPSTREAM_CLIENT_ID=
#MAS_UPSTREAM_HUMAN_NAME=Authentik
# For migration from previous direct Keycloud-style config: set to oidc-<your old KEYCLOAK_ID> so syn2mas maps users correctly.
#MAS_UPSTREAM_SYNAPSE_IDP_ID=
#SECRET_MAS_UPSTREAM_CLIENT_SECRET_VERSION=v1
### Shared secret auth (bridges / automation)
#COMPOSE_FILE="$COMPOSE_FILE:compose.shared_secret_auth.yml"
#SHARED_SECRET_AUTH_ENABLED=1
#SECRET_SHARED_SECRET_AUTH_VERSION=v1 # length=128
## Federation ## Federation
#DISABLE_FEDERATION=1 #DISABLE_FEDERATION=1
@ -28,14 +104,6 @@ SERVE_SERVER_WELLKNOWN=false
ALLOW_PUBLIC_ROOMS_FEDERATION=false ALLOW_PUBLIC_ROOMS_FEDERATION=false
## Registration
ENABLE_REGISTRATION=false
PASSWORD_LOGIN_ENABLED=true
# Token based registration. Enable ADMIN_INTERFACE (below) to use the admin interface to generate tokens.
#REGISTRATION_REQUIRES_TOKEN=true
## Room auto-join ## Room auto-join
#AUTO_JOIN_ROOM_ENABLED=1 #AUTO_JOIN_ROOM_ENABLED=1
@ -98,30 +166,8 @@ RETENTION_MAX_LIFETIME=4w
#LOGIN_LIMIT_ACCOUNT_PER_SECOND=1 #LOGIN_LIMIT_ACCOUNT_PER_SECOND=1
#LOGIN_LIMIT_ACCOUNT_BURST=10 #LOGIN_LIMIT_ACCOUNT_BURST=10
## Keycloak SSO
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak.yml"
#KEYCLOAK_ENABLED=1
#KEYCLOAK_ID=keycloak
#KEYCLOAK_NAME=
#KEYCLOAK_URL=
#KEYCLOAK_CLIENT_ID=
#KEYCLOAK_CLIENT_DOMAIN=
#KEYCLOAK_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1
## TURN ## TURN
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak3.yml"
#KEYCLOAK3_ENABLED=1
#KEYCLOAK3_ID=keycloak3
#KEYCLOAK3_NAME=
#KEYCLOAK3_URL=
#KEYCLOAK3_CLIENT_ID=
#KEYCLOAK3_CLIENT_DOMAIN=
#KEYCLOAK3_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION=v1
#COMPOSE_FILE="$COMPOSE_FILE:compose.turn.yml" #COMPOSE_FILE="$COMPOSE_FILE:compose.turn.yml"
#TURN_ENABLED=1 #TURN_ENABLED=1
#TURN_URIS="[\"turns:coturn.foo.zone?transport=udp\", \"turns:coturn.foo.zone?transport=tcp\"]" #TURN_URIS="[\"turns:coturn.foo.zone?transport=udp\", \"turns:coturn.foo.zone?transport=tcp\"]"
@ -189,12 +235,6 @@ RETENTION_MAX_LIFETIME=4w
#SECRET_SIGNAL_HS_TOKEN_VERSION=v1 #SECRET_SIGNAL_HS_TOKEN_VERSION=v1
#SECRET_SIGNAL_PICKLE_KEY_VERSION=v1 #SECRET_SIGNAL_PICKLE_KEY_VERSION=v1
## Shared auth
#COMPOSE_FILE="$COMPOSE_FILE:compose.shared_secret_auth.yml"
#SHARED_SECRET_AUTH_ENABLED=1
#SECRET_SHARED_SECRET_AUTH_VERSION=v1 # length=128
## Web Client (Redirect) ## Web Client (Redirect)
#WEB_CLIENT_LOCATION=https://element-web.example.com #WEB_CLIENT_LOCATION=https://element-web.example.com

View File

@ -45,6 +45,50 @@ See [`#27`](https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/27) for m
You'll need to deploy something like [this](https://git.autonomic.zone/ruangrupa/well-known-uris). This could be implemented in this recipe but we haven't merged it in yet. Change sets are welcome. You'll need to deploy something like [this](https://git.autonomic.zone/ruangrupa/well-known-uris). This could be implemented in this recipe but we haven't merged it in yet. Change sets are welcome.
### Matrix Authentication Service (MAS)
[MAS](https://element-hq.github.io/matrix-authentication-service/) is Elements OAuth/OIDC-native auth service for Matrix: it handles login, tokens, and upstream IdPs while Synapse delegates authentication via `matrix_authentication_service`.
**Enable the stack:**
- In `.env`, uncomment `compose.mas.yml` (and `compose.mas-upstream.yml` plus upstream envs if you use an external IdP), and uncomment the `SECRET_MAS_*` version lines.
- `abra app secret generate YOURAPPDOMAIN`
- **Manually insert** the PEM RSA key for `SECRET_MAS_SIGNING_RSA_VERSION` (`generate=false` in `.env.sample`) — abra cannot generate that format; see the comment there (e.g. `openssl genrsa 2048` piped to `abra app secret insert`).
- `abra app cmd YOURAPPDOMAIN db ensure_mas_database` (once, creates the `mas` database in Postgres)
- `abra app deploy YOURAPPDOMAIN`
**If you plan to migrate an existing homeserver with `syn2mas`:** deploy and configure MAS as above, but **leave `MAS_ENABLED=1` commented** until migration and cutover are done, so Synapse keeps using your current login path until you intentionally switch. You cannot use Synapse legacy OIDC/Keycloak SSO alongside MAS; plan IdP apps and envs accordingly.
<details>
<summary><strong>Migrating an existing server (<code>syn2mas</code>)</strong></summary>
Requires PostgreSQL on Synapse and a dedicated MAS database. Backup Postgres (and configs) before you start. Official background: [MAS migration guide](https://element-hq.github.io/matrix-authentication-service/setup/migration.html).
1. **Prepare (Synapse still running):** With MAS in `COMPOSE_FILE` but **`MAS_ENABLED` still off**, deploy, then run checks from your machine:
```bash
abra app cmd YOURAPPDOMAIN prepare_mas_migration
```
This fetches rendered `homeserver.yaml` into the MAS container, runs `syn2mas check`, then `migrate --dry-run` (the dry run rolls back MAS data at the end). The file stays in the MAS container until next restart, so you can repeat this step to provide the file for the actual migration.
2. **Optional snapshot:** save a copy of the rendered config while `app` is up, e.g. `abra app run -t YOURAPPDOMAIN app cat /data/homeserver.yaml > homeserver.snapshot.yaml`.
3. **Downtime — stop Synapse:** run on the **host** with Docker/Swarm access (not inside a container), e.g.:
```bash
docker service scale <STACK_NAME>_app=0
```
Use the real service name from `docker service ls` (suffix `_app`).
4. **Migration:** with MAS still running and Synapse at zero replicas,
```bash
abra app run YOURAPPDOMAIN mas -- mas-cli syn2mas migrate \
--config /etc/mas/config.yaml \
--synapse-config /tmp/homeserver.yaml
```
5. **Cutover:** in `.env`, set `MAS_ENABLED=1`, `PASSWORD_LOGIN_ENABLED=false`, remove legacy Keycloak/SSO envs, then `abra app deploy YOURAPPDOMAIN` (Synapse comes back with MAS delegation). `syn2mas` does not write to the Synapse database; if you abort before serving traffic through MAS, you can often drop and recreate the MAS DB and revert env.
</details>
## Bridges ## Bridges
For all Bridges: For all Bridges:
- Setting it up is a bit of a chicken/egg & chasing cats moment. - Setting it up is a bit of a chicken/egg & chasing cats moment.
@ -52,6 +96,9 @@ For all Bridges:
- include the registration in synapse, e.g. `APP_SERVICE_CONFIGS="[\"/telegram-data/registration.yaml\"]"` - include the registration in synapse, e.g. `APP_SERVICE_CONFIGS="[\"/telegram-data/registration.yaml\"]"`
- and set yourself as admin, e.g.: `TELEGRAM_BRIDGE_PERMISSIONS="{ \"*\": \"relaybot\", \"@akadmin:example.com\": \"admin\"}"` - and set yourself as admin, e.g.: `TELEGRAM_BRIDGE_PERMISSIONS="{ \"*\": \"relaybot\", \"@akadmin:example.com\": \"admin\"}"`
> [!IMPORTANT]
> The shared secret authenticator may break when matrix-synapse uses a newer python version with an error stating something like "module not found". You have to fix the path in the compose.shared_secret_auth.yml like [here](https://git.coopcloud.tech/coop-cloud/matrix-synapse/commit/3d1350533079ce1ad3bea92039fe003684589b95)
### Telegram bridging ### Telegram bridging
You need to get your bot setup on the telegram side first by creating a [telegram app](https://my.telegram.org/apps) and a [telegram bot](https://docs.mau.fi/bridges/python/telegram/relay-bot.html#setup) and have these values: You need to get your bot setup on the telegram side first by creating a [telegram app](https://my.telegram.org/apps) and a [telegram bot](https://docs.mau.fi/bridges/python/telegram/relay-bot.html#setup) and have these values:

55
abra.sh
View File

@ -1,16 +1,63 @@
export DISCORD_BRIDGE_YAML_VERSION=v2 export DISCORD_BRIDGE_YAML_VERSION=v2
export ENTRYPOINT_CONF_VERSION=v3 export ENTRYPOINT_CONF_VERSION=v3
export HOMESERVER_YAML_VERSION=v35 export HOMESERVER_YAML_VERSION=v36
export LOG_CONFIG_VERSION=v2 export LOG_CONFIG_VERSION=v2
export SHARED_SECRET_AUTH_VERSION=v2 export SHARED_SECRET_AUTH_VERSION=v2
export SIGNAL_BRIDGE_YAML_VERSION=v6 export SIGNAL_BRIDGE_YAML_VERSION=v6
export TELEGRAM_BRIDGE_YAML_VERSION=v6 export TELEGRAM_BRIDGE_YAML_VERSION=v6
export NGINX_CONFIG_VERSION=v12 export NGINX_CONFIG_VERSION=v13
export WK_SERVER_VERSION=v1 export WK_SERVER_VERSION=v1
export WK_CLIENT_VERSION=v1 export WK_CLIENT_VERSION=v2
export PG_BACKUP_VERSION=v1 export MAS_CONFIG_VERSION=v1
export PG_BACKUP_VERSION=v2
export ADMIN_CONFIG_VERSION=v1 export ADMIN_CONFIG_VERSION=v1
ensure_mas_database () {
if ! psql -U synapse -d postgres -v ON_ERROR_STOP=1 -Atqc "SELECT 1 FROM pg_database WHERE datname = 'mas'" | grep -qx 1
then
psql -U synapse -d postgres -v ON_ERROR_STOP=1 -c "CREATE DATABASE mas OWNER synapse"
fi
}
# Local helper: fetch homeserver.yaml from app, push to mas, then syn2mas check + dry-run.
prepare_mas_migration () {
local hs_local syn_cfg
syn_cfg=/tmp/homeserver.yaml
cleanup_prepare_mas_migration() {
rm -f "homeserver.yaml"
}
trap cleanup_prepare_mas_migration EXIT
echo "Fetching /data/homeserver.yaml from app to homeserver.yaml (abra app run … cat)..."
if ! abra app run -t "$DOMAIN" app cat /data/homeserver.yaml > "homeserver.yaml"
then
return 1
fi
if [ ! -s "homeserver.yaml" ]; then
echo "Error: fetched homeserver.yaml is empty." >&2
return 1
fi
echo "Copying into mas:/tmp"
abra app cp "$DOMAIN" "homeserver.yaml" "mas:/tmp" || return 1
echo "Running mas-cli syn2mas check..."
abra app run -t "$DOMAIN" mas -- mas-cli syn2mas check \
--config /etc/mas/config.yaml \
--synapse-config "$syn_cfg" || return 1
echo "Running mas-cli syn2mas migrate --dry-run..."
abra app run -t "$DOMAIN" mas -- mas-cli syn2mas migrate \
--config /etc/mas/config.yaml \
--synapse-config "$syn_cfg" \
--dry-run || return 1
trap - EXIT
cleanup_prepare_mas_migration
}
set_admin () { set_admin () {
admin=akadmin admin=akadmin
if [ -n "$1" ] if [ -n "$1" ]

View File

@ -3,13 +3,13 @@ version: "3.8"
services: services:
admin: admin:
image: awesometechnologies/synapse-admin:0.11.1 image: awesometechnologies/synapse-admin:0.11.4
networks: networks:
- proxy - proxy
deploy: deploy:
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.docker.network=proxy" - "traefik.swarm.network=proxy"
- "traefik.http.services.${STACK_NAME}_admin.loadbalancer.server.port=80" - "traefik.http.services.${STACK_NAME}_admin.loadbalancer.server.port=80"
- "traefik.http.routers.${STACK_NAME}_admin.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})&&PathPrefix(`/admin`)" - "traefik.http.routers.${STACK_NAME}_admin.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})&&PathPrefix(`/admin`)"
- "traefik.http.routers.${STACK_NAME}_admin.entrypoints=web-secure" - "traefik.http.routers.${STACK_NAME}_admin.entrypoints=web-secure"

21
compose.mas-upstream.yml Normal file
View File

@ -0,0 +1,21 @@
---
version: "3.8"
# Upstream OIDC provider for MAS (e.g. Authentik, Keycloak).
# Requires compose.mas.yml. Adds the client secret and env vars needed by mas.config.yaml.tmpl.
services:
mas:
environment:
- MAS_UPSTREAM_PROVIDER_ID
- MAS_UPSTREAM_ISSUER
- MAS_UPSTREAM_CLIENT_ID
- MAS_UPSTREAM_HUMAN_NAME
- MAS_UPSTREAM_SYNAPSE_IDP_ID
secrets:
- mas_upstream_client_secret
secrets:
mas_upstream_client_secret:
external: true
name: ${STACK_NAME}_mas_upstream_client_secret_${SECRET_MAS_UPSTREAM_CLIENT_SECRET_VERSION}

64
compose.mas.yml Normal file
View File

@ -0,0 +1,64 @@
---
version: "3.8"
# Matrix Authentication Service (MAS) — optional overlay for Element X / OIDC-native auth.
services:
mas:
image: ghcr.io/element-hq/matrix-authentication-service:1.14.0
command: ["server", "--config=/etc/mas/config.yaml"]
environment:
- DOMAIN
- SERVER_NAME
- STACK_NAME
networks:
- internal
configs:
- source: mas_config
target: /etc/mas/config.yaml
secrets:
- db_password
- mas_encryption
- mas_synapse_shared
- mas_signing_rsa
# Official image is distroless (no curl/wget); upstream suggests `mas-cli config check` for probes.
# See https://github.com/element-hq/matrix-authentication-service/issues/3741 — validates config, not HTTP.
# GET /health is still served (resource `health` in mas.config.yaml.tmpl) for probes from other images.
healthcheck:
test:
[
"CMD",
"/usr/local/bin/mas-cli",
"--config",
"/etc/mas/config.yaml",
"config",
"check",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
restart_policy:
condition: on-failure
app:
secrets:
- mas_synapse_shared
configs:
mas_config:
name: ${STACK_NAME}_mas_config_${MAS_CONFIG_VERSION}
file: mas.config.yaml.tmpl
template_driver: golang
secrets:
mas_encryption:
external: true
name: ${STACK_NAME}_mas_encryption_${SECRET_MAS_ENCRYPTION_VERSION}
mas_synapse_shared:
external: true
name: ${STACK_NAME}_mas_synapse_shared_${SECRET_MAS_SYNAPSE_SHARED_VERSION}
mas_signing_rsa:
external: true
name: ${STACK_NAME}_mas_signing_rsa_${SECRET_MAS_SIGNING_RSA_VERSION}

View File

@ -9,7 +9,7 @@ services:
- shared_secret_auth - shared_secret_auth
configs: configs:
- source: shared_secret_auth - source: shared_secret_auth
target: /usr/local/lib/python3.12/site-packages/shared_secret_authenticator.py target: /usr/local/lib/python3.13/site-packages/shared_secret_authenticator.py
configs: configs:
shared_secret_auth: shared_secret_auth:

View File

@ -3,13 +3,14 @@ version: "3.8"
services: services:
web: web:
image: nginx:1.29.2 image: nginx:1.29.6
networks: networks:
- proxy - proxy
- internal - internal
environment: environment:
- DOMAIN - DOMAIN
- STACK_NAME - STACK_NAME
- MAS_ENABLED
- NGINX_ACCESS_LOG_LOCATION - NGINX_ACCESS_LOG_LOCATION
- NGINX_ERROR_LOG_LOCATION - NGINX_ERROR_LOG_LOCATION
- MAX_UPLOAD_SIZE - MAX_UPLOAD_SIZE
@ -22,7 +23,7 @@ services:
target: /var/www/.well-known/matrix/client target: /var/www/.well-known/matrix/client
deploy: deploy:
restart_policy: restart_policy:
condition: on-failure condition: any
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80" - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
@ -33,11 +34,11 @@ services:
test: curl -f http://${STACK_NAME}_app:8008/health || exit 1 test: curl -f http://${STACK_NAME}_app:8008/health || exit 1
interval: 30s interval: 30s
timeout: 15s timeout: 15s
retries: 30 retries: 90
start_period: 1m start_period: 2m
app: app:
image: "matrixdotorg/synapse:v1.139.2" image: "matrixdotorg/synapse:v1.149.1"
volumes: volumes:
- "data:/data" - "data:/data"
secrets: secrets:
@ -46,6 +47,7 @@ services:
- macaroon - macaroon
- form_secret - form_secret
environment: environment:
- MAS_ENABLED
- ALLOWED_LIFETIME_MAX - ALLOWED_LIFETIME_MAX
- ALLOW_PUBLIC_ROOMS_FEDERATION - ALLOW_PUBLIC_ROOMS_FEDERATION
- AUTO_JOIN_ROOM - AUTO_JOIN_ROOM
@ -106,7 +108,7 @@ services:
restart_policy: restart_policy:
condition: on-failure condition: on-failure
labels: labels:
- "coop-cloud.${STACK_NAME}.version=6.8.2+v1.139.2" - "coop-cloud.${STACK_NAME}.version=7.1.0+v1.149.1"
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT}" - "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT}"
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8008/health"] test: ["CMD", "curl", "-f", "http://localhost:8008/health"]
@ -116,21 +118,20 @@ services:
start_period: 1m start_period: 1m
db: db:
image: postgres:13-alpine image: pgautoupgrade/pgautoupgrade:17-alpine
secrets: secrets:
- db_password - db_password
environment: environment:
- LC_COLLATE=C - LC_COLLATE=C
- LC_CTYPE=C - LC_CTYPE=C
- POSTGRES_DB=synapse - POSTGRES_DB=synapse
- POSTGRES_INITDB_ARGS="-E \"UTF8\"" - POSTGRES_INITDB_ARGS=-E UTF8
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
- POSTGRES_USER=synapse - POSTGRES_USER=synapse
- DOMAIN - DOMAIN
networks: networks:
- internal - internal
healthcheck: healthcheck:
test: ["CMD", "pg_isready", "-U", "synapse"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 20 retries: 20

View File

@ -1,317 +1,390 @@
# All configuration options are documented on the following link: # All configuration options are documented on the following link:
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
{{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }} {{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1 # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1
modules: modules:
- module: shared_secret_authenticator.SharedSecretAuthProvider - module: shared_secret_authenticator.SharedSecretAuthProvider
config: config:
shared_secret: {{ secret "shared_secret_auth" }} shared_secret: {{ secret "shared_secret_auth" }}
m_login_password_support_enabled: true m_login_password_support_enabled: true
{{ end }} {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name
server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }} server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl
public_baseurl: https://{{ env "DOMAIN" }}/ public_baseurl: https://{{ env "DOMAIN" }}/
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#require_auth_for_profile_requests # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#require_auth_for_profile_requests
require_auth_for_profile_requests: {{ env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS" }} {{ if (env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS") }}
require_auth_for_profile_requests: {{ env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS" }}
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_profile_requests_to_users_who_share_rooms {{ end }}
limit_profile_requests_to_users_who_share_rooms: {{ env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS" }}
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_profile_requests_to_users_who_share_rooms
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#serve_server_wellknown {{ if (env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS") }}
serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }} limit_profile_requests_to_users_who_share_rooms: {{ env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth
allow_public_rooms_without_auth: false # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#serve_server_wellknown
{{ if (env "SERVE_SERVER_WELLKNOWN") }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }}
allow_public_rooms_over_federation: {{ or (env "ALLOW_PUBLIC_ROOMS_FEDERATION") "true" }} {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth
listeners: allow_public_rooms_without_auth: false
- port: 8008
tls: false # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation
type: http {{ if (env "ALLOW_PUBLIC_ROOMS_FEDERATION") }}
x_forwarded: true allow_public_rooms_over_federation: {{ env "ALLOW_PUBLIC_ROOMS_FEDERATION" }}
{{ end }}
{{ if eq (env "DISABLE_FEDERATION") "1" }}
resources: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners
{{ if eq (env "KEYCLOAK_ENABLED") "1" }} listeners:
- names: [client, openid] - port: 8008
compress: true tls: false
{{ else }} type: http
- names: [client] x_forwarded: true
compress: true
{{ end }} {{ if eq (env "DISABLE_FEDERATION") "1" }}
{{ else }} resources:
resources: {{ if eq (env "KEYCLOAK_ENABLED") "1" }}
{{ if eq (env "KEYCLOAK_ENABLED") "1" }} - names: [client, openid]
- names: [client, openid, federation] compress: true
compress: true {{ else }}
{{ else }} - names: [client]
- names: [client, federation] compress: true
compress: true {{ end }}
{{ end }} {{ else }}
{{ end }} resources:
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#delete_stale_devices_after - names: [client, openid, federation]
{{ if (env "DELETE_STALE_DEVICES_AFTER") }} compress: true
delete_stale_devices_after: {{ env "DELETE_STALE_DEVICES_AFTER" }} {{ else }}
{{ end }} - names: [client, federation]
compress: true
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact {{ end }}
admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}' {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#delete_stale_devices_after
limit_remote_rooms: {{ if (env "DELETE_STALE_DEVICES_AFTER") }}
enabled: true delete_stale_devices_after: {{ env "DELETE_STALE_DEVICES_AFTER" }}
complexity: 200.0 {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact
max_avatar_size: 10M {{ if (env "ADMIN_EMAIL") }}
admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}'
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period {{ end }}
forgotten_room_retention_period: 3d
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#request_token_inhibit_3pid_errors limit_remote_rooms:
request_token_inhibit_3pid_errors: true enabled: true
complexity: 200.0
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#redaction_retention_period
redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size
max_avatar_size: 10M
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age
user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period
forgotten_room_retention_period: 3d
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention
retention: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#request_token_inhibit_3pid_errors
enabled: true request_token_inhibit_3pid_errors: true
default_policy:
min_lifetime: 1d # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#redaction_retention_period
max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }} {{ if (env "REDACTION_RETENTION_PERIOD") }}
allowed_lifetime_min: 1d redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }}
allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }} {{ end }}
purge_jobs:
- longest_max_lifetime: 3d # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age
interval: 12h {{ if (env "USER_IPS_MAX_AGE") }}
- shortest_max_lifetime: 3d user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }}
interval: 1d {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention
{{ if eq (env "DISABLE_FEDERATION") "1" }} retention:
federation_domain_whitelist: [] enabled: true
{{ else if eq (env "ENABLE_ALLOWLIST") "1" }} default_policy:
federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }} min_lifetime: 1d
{{ end }} {{ if (env "RETENTION_MAX_LIFETIME") }}
max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1 {{ end }}
database: allowed_lifetime_min: 1d
name: psycopg2 {{ if (env "ALLOWED_LIFETIME_MAX") }}
txn_limit: 10000 allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }}
args: {{ end }}
user: synapse purge_jobs:
password: "{{ secret "db_password" }}" - longest_max_lifetime: 3d
database: synapse interval: 12h
host: "{{ env "STACK_NAME" }}_db" - shortest_max_lifetime: 3d
port: 5432 interval: 1d
cp_min: 5
cp_max: 10 # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist
keepalives_idle: 10 {{ if eq (env "DISABLE_FEDERATION") "1" }}
keepalives_interval: 10 federation_domain_whitelist: []
keepalives_count: 3 {{ else if eq (env "ENABLE_ALLOWLIST") "1" }}
federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config {{ end }}
log_config: "/data/log.config"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path database:
media_store_path: "/data/media_store" name: psycopg2
txn_limit: 10000
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size args:
max_upload_size: 50M user: synapse
password: "{{ secret "db_password" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn database: synapse
{{ if eq (env "TURN_ENABLED") "1" }} host: "{{ env "STACK_NAME" }}_db"
turn_uris: {{ env "TURN_URIS" }} port: 5432
turn_shared_secret: "{{ secret "turn_shared_secret" }}" cp_min: 5
turn_user_lifetime: 1h cp_max: 10
turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }} keepalives_idle: 10
{{ end }} keepalives_interval: 10
keepalives_count: 3
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration
enable_registration: {{ env "ENABLE_REGISTRATION" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config
log_config: "/data/log.config"
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_requires_token
registration_requires_token: {{ env "REGISTRATION_REQUIRES_TOKEN" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path
media_store_path: "/data/media_store"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup
enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size
max_upload_size: 50M
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access
allow_guest_access: false # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn
{{ if eq (env "TURN_ENABLED") "1" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret {{ if (env "TURN_URIS") }}
registration_shared_secret: {{ secret "registration" }} turn_uris: {{ env "TURN_URIS" }}
{{ end }}
{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }} turn_shared_secret: "{{ secret "turn_shared_secret" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms turn_user_lifetime: 1h
{{ if (env "TURN_ALLOW_GUESTS") }}
# AUTO_JOIN_ROOM only for backwards compatibility turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }}
{{ if (env "AUTO_JOIN_ROOM") }} {{ end }}
auto_join_rooms: {{ end }}
- "{{ env "AUTO_JOIN_ROOM" }}"
{{ else }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration
auto_join_rooms: {{ env "AUTO_JOIN_ROOM_LIST" }} {{ if (env "ENABLE_REGISTRATION") }}
{{ end }} enable_registration: {{ env "ENABLE_REGISTRATION" }}
{{ end }}
{{ end }}
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_requires_token
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#session_lifetime {{ if (env "REGISTRATION_REQUIRES_TOKEN") }}
{{ if (env "SESSION_LIFETIME") }} registration_requires_token: {{ env "REGISTRATION_REQUIRES_TOKEN" }}
session_lifetime: {{ env "SESSION_LIFETIME" }} {{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats {{ if (env "ENABLE_3PID_LOOKUP") }}
report_stats: false enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }}
{{ end }}
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#track_puppeted_user_ips
track_puppeted_user_ips: {{ env "TRACK_PUPPETED_USER_IPS" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access
allow_guest_access: false
{{ if eq (env "APP_SERVICES_ENABLED") "1" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret
app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }} registration_shared_secret: {{ secret "registration" }}
{{ end }}
{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#macaroon_secret_key # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms
macaroon_secret_key: "{{ secret "macaroon" }}"
# AUTO_JOIN_ROOM only for backwards compatibility
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#form_secret {{ if (env "AUTO_JOIN_ROOM") }}
form_secret: "{{ secret "form_secret" }}" auto_join_rooms:
- "{{ env "AUTO_JOIN_ROOM" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#signing_key_path {{ else }}
signing_key_path: "/data/{{ env "DOMAIN" }}.signing.key" auto_join_rooms: {{ env "AUTO_JOIN_ROOM_LIST" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#old_signing_keys
{{ if (and (env "OLD_SIGNING_KEY_ID") (env "OLD_SIGNING_KEY") (env "OLD_SIGNING_KEY_EXPIRES")) }} {{ end }}
old_signing_keys:
"ed25519:{{ env "OLD_SIGNING_KEY_ID" }}": { key: "{{ env "OLD_SIGNING_KEY" }}", expired_ts: {{ env "OLD_SIGNING_KEY_EXPIRES" }} } # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#session_lifetime
{{ end }} {{ if (env "SESSION_LIFETIME") }}
session_lifetime: {{ env "SESSION_LIFETIME" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers {{ end }}
{{ if eq (env "ENABLE_ALLOWLIST") "1" }}
trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats
{{ else }} report_stats: false
trusted_key_servers:
- server_name: "matrix.org" # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#track_puppeted_user_ips
{{ end }} {{ if (env "TRACK_PUPPETED_USER_IPS") }}
track_puppeted_user_ips: {{ env "TRACK_PUPPETED_USER_IPS" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers {{ end }}
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
oidc_providers: {{ if eq (env "APP_SERVICES_ENABLED") "1" }}
- idp_id: {{ env "KEYCLOAK_ID" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files
idp_name: {{ env "KEYCLOAK_NAME" }} app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }}
issuer: "{{ env "KEYCLOAK_URL" }}" {{ end }}
client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}"
client_secret: "{{ secret "keycloak_client_secret" }}" # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#macaroon_secret_key
scopes: ["openid", "profile"] macaroon_secret_key: "{{ secret "macaroon" }}"
allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }}
user_mapping_provider: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#form_secret
config: form_secret: "{{ secret "form_secret" }}"
localpart_template: "{{ "{{ user.preferred_username }}" }}"
display_name_template: "{{ "{{ user.name }}" }}" # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#signing_key_path
signing_key_path: "/data/{{ env "DOMAIN" }}.signing.key"
{{ if eq (env "KEYCLOAK2_ENABLED") "1" }}
- idp_id: {{ env "KEYCLOAK2_ID" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#old_signing_keys
idp_name: {{ env "KEYCLOAK2_NAME" }} {{ if (and (env "OLD_SIGNING_KEY_ID") (env "OLD_SIGNING_KEY") (env "OLD_SIGNING_KEY_EXPIRES")) }}
issuer: "{{ env "KEYCLOAK2_URL" }}" old_signing_keys:
client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}" "ed25519:{{ env "OLD_SIGNING_KEY_ID" }}": { key: "{{ env "OLD_SIGNING_KEY" }}", expired_ts: {{ env "OLD_SIGNING_KEY_EXPIRES" }} }
client_secret: "{{ secret "keycloak2_client_secret" }}" {{ end }}
scopes: ["openid", "profile"]
allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers
user_mapping_provider: {{ if eq (env "ENABLE_ALLOWLIST") "1" }}
config: trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST
localpart_template: "{{ "{{ user.preferred_username }}" }}" {{ else }}
display_name_template: "{{ "{{ user.name }}" }}" trusted_key_servers:
{{ end }} - server_name: "matrix.org"
{{ end }}
{{ if eq (env "KEYCLOAK3_ENABLED") "1" }}
- idp_id: {{ env "KEYCLOAK3_ID" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers
idp_name: {{ env "KEYCLOAK3_NAME" }} {{ if eq (env "KEYCLOAK_ENABLED") "1" }}
issuer: "{{ env "KEYCLOAK3_URL" }}" oidc_providers:
client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}" - idp_id: {{ env "KEYCLOAK_ID" }}
client_secret: "{{ secret "keycloak3_client_secret" }}" idp_name: {{ env "KEYCLOAK_NAME" }}
scopes: ["openid", "profile"] issuer: "{{ env "KEYCLOAK_URL" }}"
allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }} client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}"
user_mapping_provider: client_secret: "{{ secret "keycloak_client_secret" }}"
config: scopes: ["openid", "profile"]
localpart_template: "{{ "{{ user.preferred_username }}" }}" {{ if (env "KEYCLOAK_ALLOW_EXISTING_USERS") }}
display_name_template: "{{ "{{ user.name }}" }}" allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }}
{{ end }} {{ end }}
{{ end }} user_mapping_provider:
config:
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#sso localpart_template: "{{ "{{ user.preferred_username }}" }}"
{{ if eq (env "KEYCLOAK_ENABLED") "1" }} display_name_template: "{{ "{{ user.name }}" }}"
sso:
client_whitelist: {{ if eq (env "KEYCLOAK2_ENABLED") "1" }}
- https://{{ env "KEYCLOAK_CLIENT_DOMAIN" }} - idp_id: {{ env "KEYCLOAK2_ID" }}
{{ end }} idp_name: {{ env "KEYCLOAK2_NAME" }}
issuer: "{{ env "KEYCLOAK2_URL" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#password_config client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}"
password_config: client_secret: "{{ secret "keycloak2_client_secret" }}"
enabled: {{ env "PASSWORD_LOGIN_ENABLED" }} scopes: ["openid", "profile"]
{{ if (env "KEYCLOAK2_ALLOW_EXISTING_USERS") }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }}
{{ if eq (env "SMTP_ENABLED") "1" }} {{ end }}
email: user_mapping_provider:
smtp_host: {{ env "SMTP_HOST" }} config:
smtp_port: {{ env "SMTP_PORT" }} localpart_template: "{{ "{{ user.preferred_username }}" }}"
smtp_user: {{ env "SMTP_USER" }} display_name_template: "{{ "{{ user.name }}" }}"
smtp_pass: "{{ secret "smtp_password" }}" {{ end }}
require_transport_security: true
notif_from: Your Friendly %(app)s homeserver <{{ env "SMTP_FROM" }}> {{ if eq (env "KEYCLOAK3_ENABLED") "1" }}
app_name: {{ env "SMTP_APP_NAME" }} - idp_id: {{ env "KEYCLOAK3_ID" }}
enable_notifs: true idp_name: {{ env "KEYCLOAK3_NAME" }}
client_base_url: https://{{ env "DOMAIN" }} issuer: "{{ env "KEYCLOAK3_URL" }}"
{{ end }} client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}"
client_secret: "{{ secret "keycloak3_client_secret" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#encryption_enabled_by_default_for_room_type scopes: ["openid", "profile"]
encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }} {{ if (env "KEYCLOAK3_ALLOW_EXISTING_USERS") }}
allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_directory {{ end }}
user_directory: user_mapping_provider:
enabled: {{ env "USER_DIRECTORY_ENABLED" }} config:
search_all_users: {{ env "USER_DIRECTORY_SEARCH_ALL_USERS" }} localpart_template: "{{ "{{ user.preferred_username }}" }}"
prefer_local_users: {{ env "USER_DIRECTORY_PREFER_LOCAL_USERS" }} display_name_template: "{{ "{{ user.name }}" }}"
show_locked_users: {{ env "USER_DIRECTORY_SHOW_LOCKED_USERS" }} {{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_retention
media_retention: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#sso
local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }} {{ if eq (env "KEYCLOAK_ENABLED") "1" }}
remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }} sso:
client_whitelist:
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_metrics - https://{{ env "KEYCLOAK_CLIENT_DOMAIN" }}
enable_metrics: false {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#track_appservice_user_ips # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#password_config
track_appservice_user_ips: false # With MAS (matrix_authentication_service), Synapse rejects password_config.enabled: true — set PASSWORD_LOGIN_ENABLED=false in app .env when MAS_ENABLED=1 (.env.sample).
{{ if (env "PASSWORD_LOGIN_ENABLED") }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forget_rooms_on_leave password_config:
forget_rooms_on_leave: true enabled: {{ env "PASSWORD_LOGIN_ENABLED" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#opentracing-1
opentracing: {{ if eq (env "MAS_ENABLED") "1" }}
enabled: false # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#matrix_authentication_service
matrix_authentication_service:
# https://matrix-org.github.io/synapse/develop/usage/configuration/config_documentation.html#ratelimiting enabled: true
rc_login: endpoint: http://{{ env "STACK_NAME"}}_mas:8080/
address: secret_path: /run/secrets/mas_synapse_shared
per_second: {{ env "LOGIN_LIMIT_IP_PER_SECOND" }} {{ end }}
burst_count: {{ env "LOGIN_LIMIT_IP_BURST" }}
account: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email
per_second: {{ env "LOGIN_LIMIT_ACCOUNT_PER_SECOND" }} {{ if eq (env "SMTP_ENABLED") "1" }}
burst_count: {{ env "LOGIN_LIMIT_ACCOUNT_BURST" }} email:
smtp_host: {{ env "SMTP_HOST" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#web_client_location smtp_port: {{ env "SMTP_PORT" }}
web_client_location: {{ env "WEB_CLIENT_LOCATION" }} smtp_user: {{ env "SMTP_USER" }}
smtp_pass: "{{ secret "smtp_password" }}"
require_transport_security: true
notif_from: Your Friendly %(app)s homeserver <{{ env "SMTP_FROM" }}>
app_name: {{ env "SMTP_APP_NAME" }}
enable_notifs: true
client_base_url: https://{{ env "DOMAIN" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#encryption_enabled_by_default_for_room_type
{{ if (env "ENCRYPTED_BY_DEFAULT") }}
encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_directory
{{ if or (env "USER_DIRECTORY_ENABLED") (env "USER_DIRECTORY_SEARCH_ALL_USERS") (env "USER_DIRECTORY_PREFER_LOCAL_USERS") (env "USER_DIRECTORY_SHOW_LOCKED_USERS") }}
user_directory:
{{ if (env "USER_DIRECTORY_ENABLED") }}
enabled: {{ env "USER_DIRECTORY_ENABLED" }}
{{ end }}
{{ if (env "USER_DIRECTORY_SEARCH_ALL_USERS") }}
search_all_users: {{ env "USER_DIRECTORY_SEARCH_ALL_USERS" }}
{{ end }}
{{ if (env "USER_DIRECTORY_PREFER_LOCAL_USERS") }}
prefer_local_users: {{ env "USER_DIRECTORY_PREFER_LOCAL_USERS" }}
{{ end }}
{{ if (env "USER_DIRECTORY_SHOW_LOCKED_USERS") }}
show_locked_users: {{ env "USER_DIRECTORY_SHOW_LOCKED_USERS" }}
{{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_retention
{{ if or (env "MEDIA_RETENTION_LOCAL_LIFETIME") (env "MEDIA_RETENTION_REMOTE_LIFETIME") }}
media_retention:
{{ if (env "MEDIA_RETENTION_LOCAL_LIFETIME") }}
local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }}
{{ end }}
{{ if (env "MEDIA_RETENTION_REMOTE_LIFETIME") }}
remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }}
{{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_metrics
enable_metrics: false
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#track_appservice_user_ips
track_appservice_user_ips: false
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forget_rooms_on_leave
forget_rooms_on_leave: true
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#opentracing-1
opentracing:
enabled: false
# https://matrix-org.github.io/synapse/develop/usage/configuration/config_documentation.html#ratelimiting
{{ if or (and (env "LOGIN_LIMIT_IP_PER_SECOND") (env "LOGIN_LIMIT_IP_BURST")) (and (env "LOGIN_LIMIT_ACCOUNT_PER_SECOND") (env "LOGIN_LIMIT_ACCOUNT_BURST")) }}
rc_login:
{{ if and (env "LOGIN_LIMIT_IP_PER_SECOND") (env "LOGIN_LIMIT_IP_BURST") }}
address:
per_second: {{ env "LOGIN_LIMIT_IP_PER_SECOND" }}
burst_count: {{ env "LOGIN_LIMIT_IP_BURST" }}
{{ end }}
{{ if and (env "LOGIN_LIMIT_ACCOUNT_PER_SECOND") (env "LOGIN_LIMIT_ACCOUNT_BURST") }}
account:
per_second: {{ env "LOGIN_LIMIT_ACCOUNT_PER_SECOND" }}
burst_count: {{ env "LOGIN_LIMIT_ACCOUNT_BURST" }}
{{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#web_client_location
{{ if (env "WEB_CLIENT_LOCATION") }}
web_client_location: {{ env "WEB_CLIENT_LOCATION" }}
{{ end }}

73
mas.config.yaml.tmpl Normal file
View File

@ -0,0 +1,73 @@
# Docs: https://element-hq.github.io/matrix-authentication-service/
http:
public_base: https://{{ env "DOMAIN" }}/
trusted_proxies:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8
- fd00::/8
- ::1/128
listeners:
- name: web
resources:
- name: discovery
- name: human
- name: oauth
- name: compat
- name: graphql
playground: false
- name: assets
# https://element-hq.github.io/matrix-authentication-service/reference/configuration.html#httplisteners
- name: health
binds:
- address: "[::]:8080"
database:
uri: postgresql://synapse:{{ secret "db_password" }}@{{ env "STACK_NAME" }}_db:5432/mas?sslmode=disable
matrix:
kind: synapse
homeserver: {{ or (env "SERVER_NAME") (env "DOMAIN") }}
endpoint: http://{{ env "STACK_NAME" }}_app:8008/
secret_file: /run/secrets/mas_synapse_shared
secrets:
# Plain hex in file (abra: length=64 charset=hex). See .env.sample modifiers.
encryption_file: /run/secrets/mas_encryption
keys:
- key_file: /run/secrets/mas_signing_rsa
passwords:
enabled: true
schemes:
- version: 1
algorithm: bcrypt
unicode_normalization: true
- version: 2
algorithm: argon2id
{{ if env "MAS_UPSTREAM_PROVIDER_ID" }}
# https://element-hq.github.io/matrix-authentication-service/setup/sso.html
upstream_oauth2:
providers:
- id: {{ env "MAS_UPSTREAM_PROVIDER_ID" }}
{{ if env "MAS_UPSTREAM_SYNAPSE_IDP_ID" }}synapse_idp_id: {{ env "MAS_UPSTREAM_SYNAPSE_IDP_ID" }}{{ end }}
human_name: {{ or (env "MAS_UPSTREAM_HUMAN_NAME") "SSO" }}
issuer: {{ env "MAS_UPSTREAM_ISSUER" }}
client_id: {{ env "MAS_UPSTREAM_CLIENT_ID" }}
client_secret_file: /run/secrets/mas_upstream_client_secret
token_endpoint_auth_method: client_secret_basic
scope: "openid profile email"
claims_imports:
localpart:
action: require
template: "{{ "{{ user.preferred_username }}" }}"
displayname:
action: suggest
template: "{{ "{{ user.name }}" }}"
email:
action: suggest
template: "{{ "{{ user.email }}" }}"
{{ end }}

View File

@ -15,6 +15,14 @@ http {
keepalive 16; keepalive 16;
} }
{{ if eq (env "MAS_ENABLED") "1" }}
upstream mas_upstream {
zone mas_upstream 64k;
server {{ env "STACK_NAME"}}_mas:8080 resolve;
keepalive 8;
}
{{ end }}
server { server {
listen 80; listen 80;
@ -32,7 +40,30 @@ http {
proxy_http_version 1.1; proxy_http_version 1.1;
} }
location ~* ^(\/_matrix|\/_synapse\/client) { {{ if eq (env "MAS_ENABLED") "1" }}
# MAS on same Host as Synapse (public_base = https://$DOMAIN/): browser/OIDC paths live at repo root, not only under /_matrix/
# Router reference: element-hq/matrix-authentication-service crates/router/src/endpoints.rs
# https://element-hq.github.io/matrix-authentication-service/setup/reverse-proxy.html
location ~ ^/(complete-compat-sso/|oauth2/|\.well-known/(openid-configuration|webfinger|change-password)|authorize|login|logout|register(/|$)|account/|upstream/|consent/|link(\?|/|$)|device/|recover(/|$)|assets/|graphql(/|$)|api/) {
proxy_pass http://mas_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
client_max_body_size 50M;
}
# Matrix CS API compat (login / logout / refresh and subpaths, e.g. …/login/sso/redirect) — before generic /_matrix
location ~ ^/_matrix/client/[^/]+/(login|logout|refresh)(/.*)?$ {
proxy_pass http://mas_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
client_max_body_size 50M;
}
{{ end }}
location ~* ^(\/_matrix|\/_synapse\/client|\/_synapse\/mas) {
proxy_pass http://matrix_upstream; proxy_pass http://matrix_upstream;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Proto https;

View File

@ -6,7 +6,7 @@ BACKUP_FILE='/var/lib/postgresql/data/backup.sql'
function backup { function backup {
export PGPASSWORD=$(cat $POSTGRES_PASSWORD_FILE) export PGPASSWORD=$(cat $POSTGRES_PASSWORD_FILE)
pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > $BACKUP_FILE pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} | gzip > $BACKUP_FILE
} }
function restore { function restore {
@ -25,7 +25,7 @@ function restore {
# Recreate Database # Recreate Database
psql -U ${POSTGRES_USER} -d postgres -c "DROP DATABASE ${POSTGRES_DB} WITH (FORCE);" psql -U ${POSTGRES_USER} -d postgres -c "DROP DATABASE ${POSTGRES_DB} WITH (FORCE);"
createdb -U ${POSTGRES_USER} ${POSTGRES_DB} createdb -U ${POSTGRES_USER} ${POSTGRES_DB}
psql -U ${POSTGRES_USER} -d ${POSTGRES_DB} -1 -f $BACKUP_FILE gunzip -c $BACKUP_FILE | psql -U ${POSTGRES_USER} -d ${POSTGRES_DB} -1 -f -
trap - EXIT INT TERM trap - EXIT INT TERM
restore_config restore_config

2
release/7.0.0+v1.149.1 Normal file
View File

@ -0,0 +1,2 @@
WARNING: Backup your database!
This upgrade switches the database image from postgres to pgautoupgrade and performs an in-place database upgrades from version 13 to 17.

1
release/7.1.0+v1.149.1 Normal file
View File

@ -0,0 +1 @@
added matrix-authentication-service as opt-in to the recipe, see readme for details

View File

@ -1,5 +1,8 @@
{ {
"m.homeserver": { "m.homeserver": {
"base_url": "https://{{ env "DOMAIN" }}" "base_url": "https://{{ env "DOMAIN" }}"
} }{{ if eq (env "MAS_ENABLED") "1" }},
"org.matrix.msc2965.authentication": {
"issuer": "https://{{ env "DOMAIN" }}/"
}{{ end }}
} }