Skip to main content

Famedly Control Synapse

PyPI - Version PyPI - Python Version


Table of Contents

Documentation

This repository contains a Synapse module which allows for creating and managing "managed rooms". Those rooms have the following properties: invite-only, non-federated, cannot be left. Users are associated to groups in an external service and those same groups are associated to rooms in this module. Users are then automatically added to the corresponding rooms. This module is only "half of the work", the other half being in the external service.

The openapi specification is available at openapi-spec.yaml. You can use tools like swagger.io for a more readable format.

Note for users being deactivated: Highly recommended to remove a user from a group before it is deactivated. Upon deactivation, the user will be removed from the room regardless of any group. If the user should be reactivated in the future, it will not automatically re-join any rooms its groups are in.

Worker routing

The HTTP endpoints exposed by this module are only registered on the background task synapse worker (or the main process if no dedicated worker is configured). Requests to these endpoints on any other worker will return 404 NOT_FOUND.

This must be taken into account when configuring a reverse proxy for example; all requests under /_famedlyControl/ must be routed to the background task worker.

Installation

pip install famedly-control-synapse

Configuration

Here are the available configuration options:

# the outer modules section is just provided for completeness, the config block is the actual module config.
modules:
  - module: "famedly_control_synapse.FamedlyControl"
    config:
        famedly_control:
          api_url: str = "", # Prefix of the current famedly control http API
          jwt_auth: # OAuth2 private-key-JWT authentication against the IdP (see "Authentication" below)
            token_endpoint: str = "" # Token exchange endpoint, e.g. https://CUSTOM_DOMAIN/oauth/v2/token
            aud: str = "" # Audience of the JWT assertion; the domain of the Zitadel instance
            iss: str | null = null # Service user id (see below)
            sub: str | null = null # Service user id (see below)
            scopes: list[str] = [] # Extra scopes for the token exchange; "openid" is always added
            token_lifetime: int = 3600 # Lifetime in seconds of the signed JWT assertion
            jwk_path: str | null = null # Signing key source (see below)
            zitadel_service_account_path: str | null = null # Signing key source (see below)
        sync_enabled: bool = true, # Whether to run the background group membership sync loop
        sync_polling_interval_seconds: int = 30, # Interval in seconds between polling requests
        error_retry_queue_enabled: bool = true, # Enable retrying membership changes that previously errored
        error_retry_queue_interval_seconds: int = 30, # Interval in seconds between retrying a failed membership change
        error_retry_queue_log_after_retry_count: int = 3, # The count of error retry queue attempts to start logging warnings
        auth_provider: str = "", # The unique, internal ID of the external identity provider.
        admin_user: str = "", # The localpart of the sole administrator allowed to call the API

Authentication (jwt_auth)

The module authenticates to Famedly Control using the OAuth2 private-key-JWT flow rather than a static token. It signs a short-lived JWT assertion with a private key, exchanges it at token_endpoint for an access token, and uses that as the Bearer credential for API requests. The access token is refreshed automatically before it expires.

The signing key can be provided in one of two ways:

  • zitadel_service_account_path: path to a Zitadel service account JSON (contains the RSA private key, its keyId, and the service userId). iss and sub default to the file's userId when not set explicitly. Internally the key is converted to a JWK.
  • jwk_path: path to a JSON Web Key holding the private key, with kid set (and alg optionally set/inferred). When using a raw JWK, iss and sub are required.

API access restriction

The Famedly Control API is restricted to a single Matrix user, configured via the admin_user option. Every API request from any other user (including other server admins) is rejected with 403 M_FORBIDDEN.

This restriction exists because the module stores its management information in the admin_user's account data. Allowing multiple admins would risk splitting that management state across users. The configured admin_user should be a server admin.

Testing

To create a virtual development environment and install dependencies:

hatch shell

The tests use pytest, with the development environment managed by Hatch. Running the tests can be done like this:

hatch test

Additional optional testing arguments:

Run the tests in parallel: -p

Collect coverage data (automatically output as lcov.info): -c

Running a specific test:

Selecting a specific test to run can be as easy as providing the path to the test. All tests start from the base test directory, tests. If running all tests, this can be left out. For specific tests, see the pytest usage docs for more information.

Code Quality

Use hatch fmt to automatically format code, enforce style rules, and check types using:

  • black and isort for formatting
  • ruff for linting
  • mypy for static type checking

Check Code Without Modifying It

To check code quality without modifying files:

  • Check formatting with isort and black:
    hatch fmt --check -f
    
  • Check types and linting with mypy and ruff:
    hatch fmt --check -l
    
  • Check all of above, formatting, linting, and typing:
    hatch fmt --check
    

Auto-formatting Code

To automatically fix issues in the code:

  • Format only using black and isort:
    hatch fmt -f
    
  • Type checks(mypy) and lint, fixing autofixable ruff issues:
    hatch fmt -l
    
  • Run all tools, format, lint, type-check:
    hatch fmt
    

License

famedly-control-synapse is distributed under the terms of the AGPL-3.0 license.

Metadata

Release files for famedly-control-synapse 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for famedly-control-synapse 0.2.0
File Size Uploaded
famedly_control_synapse-0.2.0.tar.gz 129.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for famedly-control-synapse 0.2.0
File Interpreter ABI Platform
famedly_control_synapse-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 183.8 kB

Release files / famedly_control_synapse-0.2.0.tar.gz

Download URL famedly_control_synapse-0.2.0.tar.gz
Size 129.8 kB
Tags Source
SHA-256 checksum
How to use checksums
dab01fb9f4da7c7fcd0e67e6a91b8f089e3b18a011b3794bbe8a358ae417f061
BLAKE2b-256 checksum
How to use checksums
aca3ae9bb88a0ff4a0f2354541ea23c987a8e78190ec39e08de0b60b50cb988f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / famedly_control_synapse-0.2.0-py3-none-any.whl

Download URL famedly_control_synapse-0.2.0-py3-none-any.whl
Size 54.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d07037dbebcb9719b8f1f729b5e450e2d7be0f214b0fb7755d53c8ff57f0d90d
BLAKE2b-256 checksum
How to use checksums
beab942d47ff3b968cb146ad59bb10314765bf07520b61afb85eb0b971ebe0ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page