12 KiB
12 KiB
MAS Integration Research & Plan
Objectives
- Understand what the Matrix Authentication Service (MAS) needs to replace or augment in the Cloudron Synapse package.
- Capture upstream recommendations for deployment (domains, reverse proxy, database, config) and map them to Cloudron-specific constraints (single app bundle, OpenID provider, Element compatibility).
- Document the next steps to get from the working Synapse package to a MAS-enabled deployment that keeps Element/Element X happy.
Upstream MAS requirements (source: https://element-hq.github.io/matrix-authentication-service/setup/)
- Dedicated authentication service: MAS runs on its own domain (e.g.
auth.example.com) and handles account/session management via OIDC. The homeserver (Synapse) becomes an OIDC relying party. - Assets & binaries: Upstream shipped packages bundle
mas-cli, the frontend assets, policy wasm, templates, translations, etc. These can be overridden via configuration (paths configurable). - Database: MAS maintains its own PostgreSQL database with user/session/registration information. Upstream provides
mas-cli database migrateto manage schema. - Homeserver configuration: Synapse needs to be configured to trust MAS—this includes replacing the
MXID_LOCALPART_REGEXP,oidc_config, and adjustingUser Interactive Authsettings to redirect to MAS endpoints. - Reverse proxy: Both MAS and Synapse must be exposed through a reverse proxy (or Cloudron routing layer) so they can talk over HTTPS. OIDC discovery endpoints must be reachable at sensible URLs.
- SSO / upstream provider: MAS is configurable to use external SSO providers (email, identity providers) but for Cloudron we expect MAS to hook into Cloudron's OpenID provider layer (since Cloudron exposes apps via OpenID for dashboard login).
- CLI tooling:
mas-cliships aconfig,database,manage,server,syn2mas,worker,templates,doctorcommand suite. We'll likely rely on thetemplateassets and thedoctorcheck when packaging. - Templates & policies: The frontend, policy engine (OPA), and default templates drive what flows look like; for Cloudron we should ensure these assets are present and configurable by the package (perhaps via volume mounts or extraction during install).
Cloudron-specific considerations
- Single-app package: Currently the Cloudron Synapse package bundles Synapse (homeserver) and exposes it via
matrix.example.com. MAS needs a separate service but Cloudron apps normally run in a single container. Need to decide: 1) include MAS binary / assets in the same package but run a second process, or 2) run MAS as a child service through Cloudron'srun.yml/start.sh. Need to inspect existing packaging to see how (1) Synapse currently runs (maybestart.sh), (2) if additional processes are possible (should be via background start commands). Cloudron package manifest may need adjustments to expose MAS endpoints via additional subdomain or path.- The existing
start.shis an idempotent bootstrap that provisionshomeserver.yamlfrom the pip-installed Synapse, copies a statichomeserver.yaml.template, writes generated secrets, and configures the database, email, OIDC (if Cloudron-provided), TURN, and logging before finallyexec-ing Synapse withgosu. Adding MAS will require launching a second process (probably before theexec) so we can keepstart.shrunning both MAS and Synapse. Cloudron apps expose a single HTTP port (8008perCloudronManifest.json), so MAS would need to listen on a different port and rely on Cloudron’s reverse proxy rules (manifest may need to expose additionalexposePortsor route via a subpath).
- The existing
- OpenID integration: MAS expects to be an OIDC provider. Cloudron uses OpenID Connect to allow users to log into the dashboard/app. The original Cloudron issue (https://forum.cloudron.io/topic/13648) mentioned
openid uri configuration issue for synapse-s-mas. We need to ensure MAS's.well-known/openid-configurationURL is accessible and correctly registered in Cloudron. This might require adding propermanifest.jsonentries so MAS endpoints are published to Cloudron's OIDC routing layer. - Element/Element X login improvements: MAS unlocks QR-code login, passkeys, etc. Need to ensure the packaged MAS supports the flow required by Element/Element X (i.e., MAS must report as the OIDC server for
matrix.orgdomain). Thehomeserver.yaml.templatemight need updates to point at MAS discovery endpoints. - Cloudron assets: Determine how to ship MAS assets (frontend/policy/manifest) with the package so MAS can locate them without needing network downloads (Cloudron apps need offline reliability). Could use
test/folder to store sample config? Need to ensurestart.shextracts these assets and sets environment variables.
Observations from the current package
CloudronManifest.jsonexposes onlyhttpPort8008, so Synapse listens there. There are addons for localstorage, oidc, postgresql, sendmail, and optional TURN, meaning Cloudron will inject database, mail, and OIDC env vars. Introducing MAS likely requires either:- adding
exposePortsorhttpServiceentries so the reverse proxy knows about MAS’s port, and optionally anoidcaddon entry for MAS’s.well-knownmetadata, or - routing MAS through the same HTTP port but behind a different path (e.g.,
/auth). The docs for MAS mention it should run on a dedicated domain, but we might be able to serve it on a subpath if Cloudron doesn’t allow multiple ports.
- adding
start.shalready uses environment-supplied OIDC configuration when Cloudron provides it. That logic may need to be extended so MAS can either (a) act as the provider and register itself with Cloudron, or (b) rely on Cloudron’s OpenID stack if MAS is configured as a relying party. The script currently does not interact with Cloudron beyond templatinghomeserver.yaml, so we have full control over how MAS is provisioned once we decide where to run it.
Recent implementation notes
CloudronManifest.jsonnow advertises a secondhttpServicenamedmason port4000so a Cloudron TLS route can reach the MAS discovery endpoints at/mas/.well-known.- Added
mas/mas-config.template.yamlplusmas/README.mdso the package now ships an editable MAS config skeleton, expected assets directory, and guidance on where upstream binaries live. start.shgenerates/app/data/configs/mas.yaml, keeps a persistent MAS client secret, and is ready to launchmas-cli server --config ...with proper signal handling.mas/now holds the upstream v1.7.0 release artifacts: themas-clibinary plusshare/assets (frontend, manifest, policy, translations) that the config template points to, enabling MAS to run without building from source.
Manifest & runtime guardrails
- Cloudron manifest v2 gives every app a single declared
httpPort, but you can addhttpServicesentries if you need additional HTTPS-terminating services routed through Cloudron’s reverse proxy. EachhttpServicecan specify aport,path,certificate, andprotocol, making it possible to expose MAS on a different internal port or mount it under a distinct path (e.g.,/auth). Alternatively,exposePortsallows you to expose TCP ports directly if a separate plain TCP route is acceptable. - The existing
oidcaddon signals Cloudron to proxy.well-known/openid-configuration. To surface MAS’s discovery documents we can either: - register MAS as a second HTTP service with its own path for.well-known/, or - keep MAS on the same port and let the reverse proxy forward/auth/.well-known/*to the MAS port.- Since MAS needs to run alongside the homeserver,
start.shnow writes/app/data/configs/mas.yaml, backgroundsmas-cli server --config ..., and installs traps so signals kill both services before the script exits, keeping the container responsive while the MAS service shares the same app lifecycle. - The script also configures Synapse’s
homeserver.yamlto treat MAS as its login provider: password registration is disabled and the MAS OIDC endpoints/secret are templated at startup so Element clients see an OIDC-capable homeserver.
- Since MAS needs to run alongside the homeserver,
Rough plan for MAS implementation
- Gather upstream assets
- Confirm we can download a MAS release tarball as part of the build (prefer Docker image if Cloudron supports it, otherwise pre-built binary).
- Verify what assets need to be packaged (frontend dist, policy wasm, translations, templates,
mas-cli). Document in this repo how they will be bundled.
- Process orchestration
- Update
start.shto launch MAS alongside Synapse (probably via&background process) and ensure proper log capture. - Ensure MAS listens on a different port (e.g.,
4000), while Synapse remains on its port. Cloudron reverse proxy must route/masor assign a subdomain (maybeauth.<app domain>). Need to explore Cloudron manifest to see if multiple ports can be exposed; if not, we may need to run MAS on the same port but separate path? Need to review Cloudron packaging docs. - Sketch a background-run pattern: configure MAS before Synapse, run
/app/pkg/mas/mas-cli server --config ...asgosu cloudron:cloudron ... &, save the child PID, and trap SIGTERM/SIGINT so both MAS and Synapse are terminated when the container stops; the script can thenwaiton Synapse while MAS serves requests in the background.
- Update
- Configuration mapping
- Determine MAS config file structure and defaults. We'll likely need
mas-config.yamlreferencing Synapse endpoints, database credentials, and OIDC discovery data. Need to map Cloudron config variables (domain, TLS cert path) into MAS's config. - Update
homeserver.yaml.templateto include theoidcsettings pointing at MAS (includingclient_id,client_secret,authorization_endpoint, etc.). This may require new templating variables that Cloudron populates at runtime.
- Determine MAS config file structure and defaults. We'll likely need
- Cloudron integration (OpenID provider)
- Evaluate how Cloudron registers OpenID providers for apps; we might need to adjust
CloudronManifest.jsonorstart.shto register MAS's.well-known/openid-configurationwith Cloudron (maybe through environment variables orstart.shhooking into Cloudron's OpenID provider interface). Need to research Cloudron packaging guidelines for apps that expose their own OIDC endpoints. - Identify required scopes and metadata so MAS appears as the identity provider for Element clients used by Cloudron.
- Evaluate how Cloudron registers OpenID providers for apps; we might need to adjust
- Test flows (Element, CLI)
- Ensure Element clients can authenticate via MAS (login flow). Document manual steps to test after packaging.
- Provide instructions for administrators to configure MAS if Cloudron-specific modifications (domain names, secrets) are needed.
- Documentation/Assets
- Update README or create a new
docs/entry explaining how MAS is configured for Cloudron (OAUTH endpoints, necessary environment variables). - Add
POSTINSTALL.mdor similar update to inform Cloudron admins of new MAS dependencies.
- Update README or create a new
Next steps (action items)
- Clarify process/port constraints: confirm whether Cloudron allows exposing two ports or mapping a subpath to MAS; if the manifest must change, note which keys support the MAS discovery endpoints. Ensure
start.shcan launch MAS before Synapseexec. - Fetch latest MAS release (prefer Docker image if Cloudron supports pulling
ghcr.io/element-hq/matrix-authentication-service:latest). Determine how to extract assets and integrate into our package (hopefully by storing release tarball in repo or downloading during install?). - Define MAS config template that references Cloudron environment variables (domain, TLS certs, database credentials). Draft a template config file in
test/or new folder. - Map OpenID requirements: find Cloudron docs for apps that need to expose OIDC metadata. Write down the necessary manifest keys or scripts to register MAS endpoints.
- Document user flows: in this repo, outline how MAS interacts with Synapse and Element (i.e., MAS obtains upstream login info, issues tokens to Synapse, Element authenticates via Synapse -> MAS). This can serve as both reference and testing checklist.
- Additional research: determine if Cloudron's OpenID stack can act as an upstream provider for MAS (i.e., MAS is the relying party to Cloudron's OIDC provider) or if MAS should be the provider and Cloudron just routes to it.
Once the above are addressed, we'll have a clearer technical path for implementing MAS within this package. Let me know if you'd like me to iterate on any of these sections or move into prototyping a MAS-powered build.