fix(ess-pro/compose): align with matrix-stack 26.6.1 and fix routing/security gaps

Verified the role against the real matrix-stack Helm chart (pulled 26.6.1)
and fixed divergences found during review.

Bugs:
- Add MAS OIDC discovery router: /.well-known/openid-configuration must hit
  the MAS root listener (8082), not web (8080) — was 404, breaking OIDC login
- Add Synapse ip_range_blacklist (full SSRF blocklist for all outbound
  federation/identity requests; previously only url-preview blacklist present)
- Make federation_client_minimum_tls_version unconditional (chart sets it in
  shared-underrides; role only set it when federation was enabled)
- Restart only rendered fed-reader replicas in the handler instead of the
  whole compose project (missing services: filter)

Chart alignment (26.5.1 -> 26.6.1):
- Bump chart version and all image tags (mas -> matrix-authentication-service
  -pro:1.18.0, postgres 17, synapse v1.154.0-pro.1, element-web v1.12.21, etc.)
- redis maxmemory 256mb -> chart default 40mb (configurable)
- Add element-web map_style_url (configurable)

Hardening / hygiene:
- Validate ess_rtc_external_ip is a real IP (regex, no extra collection dep)
- Read admin password from the in-container secret file instead of passing it
  on the host process list during mas-cli register-user
- apt cache_valid_time, postgres first-boot-only comment, haproxy failover note
- Add meta/argument_specs.yml documenting all public variables
- README: chart version, service count, OIDC discovery verification step

Signed-off-by: Simon Bärlocher <simon@whatwedo.ch>
This commit is contained in:
Simon Bärlocher 2026-06-15 16:34:03 +02:00
parent 32eca6b923
commit ba220d6cd6
No known key found for this signature in database
GPG key ID: 63DE20495932047A
13 changed files with 331 additions and 46 deletions

View file

@ -0,0 +1,197 @@
# SPDX-License-Identifier: MIT-0
---
argument_specs:
main:
short_description: Deploy the full Element Server Suite Pro stack (matrix-stack v26.6.1) via Docker Compose.
description:
- Renders the complete ESS Pro topology (Synapse main + Rust Pro
federation-reader worker, MAS, HAProxy, Element Web/Admin, LiveKit
SFU + lk-jwt, Postgres, Redis) as a single Compose project, modelled
1:1 on the official C(matrix-stack) Helm chart.
- Cryptographic secrets are generated locally on first run; registry
and OIDC credentials are sourced from OpenBao.
options:
ess_chart_version:
type: str
default: "26.6.1"
description: matrix-stack chart version this role models. Informational.
# ---- Project layout --------------------------------------------------
ess_compose_dir:
type: path
default: /opt/ess
description: Root project directory on the target host.
ess_compose_project_name:
type: str
default: ess
ess_compose_conf_dir:
type: path
description: Rendered config dir. Defaults to C({{ ess_compose_dir }}/conf).
ess_compose_secrets_dir:
type: path
description: Generated-secrets dir (0700). Defaults to C({{ ess_compose_dir }}/secrets).
ess_compose_data_dir:
type: path
description: Runtime data dir. Defaults to C({{ ess_compose_dir }}/data).
# ---- Networks --------------------------------------------------------
ess_compose_traefik_network:
type: str
default: proxy
description: External Traefik network the public services attach to.
ess_compose_traefik_entrypoint:
type: str
default: websecure
ess_compose_traefik_certresolver:
type: str
default: letsencrypt
description: Traefik certresolver. Set to empty string to skip TLS cert resolution labels.
ess_compose_internal_network:
type: str
default: ess_internal
# ---- Matrix identity -------------------------------------------------
ess_server_name:
type: str
required: true
description: Matrix serverName (domain part of C(@user:serverName)). Immutable after first deploy.
ess_hostnames:
type: dict
description:
- Per-component FQDNs. Defaults derive from C(ess_server_name)
(matrix./account./chat./admin./mrtc.). Override individual keys
to change prefixes.
options:
synapse:
type: str
mas:
type: str
element_web:
type: str
element_admin:
type: str
matrix_rtc:
type: str
# ---- Images ----------------------------------------------------------
ess_images:
type: dict
description: Container image references, version-aligned to the chart. Override individual entries to pin/upgrade.
# ---- Registry --------------------------------------------------------
ess_registry_url:
type: str
default: registry.element.io
ess_registry_username:
type: str
required: true
description: Element registry username (from OpenBao).
ess_registry_token:
type: str
required: true
description: Element registry token (from OpenBao).
# ---- Federation reader ----------------------------------------------
ess_synapse_fed_reader_replicas:
type: int
default: 1
description: Number of Rust Pro federation-reader worker instances.
# ---- Delegated auth (OIDC) ------------------------------------------
ess_oidc_enabled:
type: bool
default: false
description: Enable upstream OIDC delegation in MAS. Requires issuer + client_secret.
ess_oidc_issuer:
type: str
default: ""
description: Upstream OIDC issuer URL. Required when C(ess_oidc_enabled).
ess_oidc_client_id:
type: str
default: ess-mas
ess_oidc_client_secret:
type: str
default: ""
description: Upstream OIDC client secret (from OpenBao). Required when C(ess_oidc_enabled).
ess_oidc_provider_name:
type: str
default: Digitalboard
ess_oidc_provider_ulid:
type: str
default: "01JBADAUTHENTIKDIGITALBOARD01"
ess_oidc_scopes:
type: str
default: "openid profile email"
# ---- Matrix RTC / Element Call --------------------------------------
ess_rtc_tcp_port:
type: int
default: 30001
ess_rtc_udp_port:
type: int
default: 30002
ess_rtc_external_ip:
type: str
required: true
description: Public NAT IP advertised in ICE candidates. Must be a valid IPv4/IPv6 address.
ess_livekit_key:
type: str
default: matrix-rtc
# ---- Registration / federation --------------------------------------
ess_enable_registration:
type: bool
default: false
ess_enable_federation:
type: bool
default: true
ess_admin_contact:
type: str
description: Defaults to C(mailto:admin@{{ ess_server_name }}).
# ---- Initial admin user ---------------------------------------------
ess_admin_localpart:
type: str
default: localadmin
ess_create_admin_user:
type: bool
default: true
# ---- Admin allow-list ------------------------------------------------
ess_admin_allow_ips:
type: list
elements: str
default:
- "0.0.0.0/0"
- "::/0"
description: Source CIDRs allowed to hit C(/_synapse/admin/). Lock down for production.
# ---- Postgres sizing -------------------------------------------------
ess_postgres_max_connections:
type: int
default: 256
ess_postgres_shared_buffers:
type: str
default: "1024MB"
ess_postgres_effective_cache_size:
type: str
default: "3840MB"
# ---- Synapse media ---------------------------------------------------
ess_synapse_max_upload_size:
type: str
default: "100M"
ess_synapse_url_previews_enabled:
type: bool
default: true
# ---- Redis -----------------------------------------------------------
ess_redis_maxmemory:
type: str
default: "40mb"
description: Redis maxmemory limit. Chart default; pub/sub only, no persistence.
# ---- Element Web -----------------------------------------------------
ess_element_web_map_style_url:
type: str
description: MapTiler style URL for location sharing. Ships the chart's demo key; replace for production.