From c360da0f8b642d28601a06f2b5c3e072a5dbfca7 Mon Sep 17 00:00:00 2001 From: V02460 Date: Wed, 26 Feb 2025 16:55:10 +0100 Subject: [PATCH] Add worker_replication_secret_path config option (#18191) Workers now get their secrets from files, too! There are not many config options left to pathify :) Includes documentation and unit tests. ### Pull Request Checklist * [x] Pull request is based on the develop branch * [x] Pull request includes a [changelog file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog). The entry should: - Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from `EventStore` to `EventWorkerStore`.". - Use markdown where necessary, mostly for `code blocks`. - End with either a period (.) or an exclamation mark (!). - Start with a capital letter. - Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry. * [x] [Code style](https://element-hq.github.io/synapse/latest/code_style.html) is correct (run the [linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters)) --------- Co-authored-by: Devon Hudson --- changelog.d/18191.feature | 1 + .../configuration/config_documentation.md | 18 +++++++++++++++- synapse/config/workers.py | 21 +++++++++++++++++-- tests/config/test_load.py | 5 +++++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 changelog.d/18191.feature diff --git a/changelog.d/18191.feature b/changelog.d/18191.feature new file mode 100644 index 0000000000..f47c9e2275 --- /dev/null +++ b/changelog.d/18191.feature @@ -0,0 +1 @@ +Add `worker_replication_secret_path` config option. \ No newline at end of file diff --git a/docs/usage/configuration/config_documentation.md b/docs/usage/configuration/config_documentation.md index f5a5aa2eb4..ffee089304 100644 --- a/docs/usage/configuration/config_documentation.md +++ b/docs/usage/configuration/config_documentation.md @@ -3252,7 +3252,7 @@ Example configuration: form_secret_path: /path/to/secrets/file ``` -_Added in Synapse 1.125.0._ +_Added in Synapse 1.126.0._ --- ## Signing Keys @@ -4527,6 +4527,22 @@ Example configuration: ```yaml worker_replication_secret: "secret_secret" ``` +--- +### `worker_replication_secret_path` + +An alternative to [`worker_replication_secret`](#worker_replication_secret): +allows the secret to be specified in an external file. + +The file should be a plain text file, containing only the secret. +Synapse reads the secret from the given file once at startup. + +Example configuration: +```yaml +worker_replication_secret_path: /path/to/secrets/file +``` + +_Added in Synapse 1.126.0._ + --- ### `start_pushers` diff --git a/synapse/config/workers.py b/synapse/config/workers.py index 632cef46ce..5af50ee952 100644 --- a/synapse/config/workers.py +++ b/synapse/config/workers.py @@ -38,6 +38,7 @@ from synapse.config._base import ( ConfigError, RoutableShardedWorkerHandlingConfig, ShardedWorkerHandlingConfig, + read_file, ) from synapse.config._util import parse_and_validate_mapping from synapse.config.server import ( @@ -65,6 +66,11 @@ configuration under `main` inside the `instance_map`. See workers documentation `https://element-hq.github.io/synapse/latest/workers.html#worker-configuration` """ +CONFLICTING_WORKER_REPLICATION_SECRET_OPTS_ERROR = """\ +Conflicting options 'worker_replication_secret' and +'worker_replication_secret_path' are both defined in config file. +""" + # This allows for a handy knob when it's time to change from 'master' to # something with less 'history' MAIN_PROCESS_INSTANCE_NAME = "master" @@ -244,12 +250,23 @@ class WorkerConfig(Config): raise ConfigError(DIRECT_TCP_ERROR, ("worker_replication_port",)) # The shared secret used for authentication when connecting to the main synapse. - self.worker_replication_secret = config.get("worker_replication_secret", None) - if self.worker_replication_secret and not allow_secrets_in_config: + worker_replication_secret = config.get("worker_replication_secret", None) + if worker_replication_secret and not allow_secrets_in_config: raise ConfigError( "Config options that expect an in-line secret as value are disabled", ("worker_replication_secret",), ) + worker_replication_secret_path = config.get( + "worker_replication_secret_path", None + ) + if worker_replication_secret_path: + if worker_replication_secret: + raise ConfigError(CONFLICTING_WORKER_REPLICATION_SECRET_OPTS_ERROR) + self.worker_replication_secret = read_file( + worker_replication_secret_path, "worker_replication_secret_path" + ).strip() + else: + self.worker_replication_secret = worker_replication_secret self.worker_name = config.get("worker_name", self.worker_app) self.instance_name = self.worker_name or MAIN_PROCESS_INSTANCE_NAME diff --git a/tests/config/test_load.py b/tests/config/test_load.py index 14dfa6e59d..a5456ac6f8 100644 --- a/tests/config/test_load.py +++ b/tests/config/test_load.py @@ -139,6 +139,7 @@ class ConfigLoadingFileTestCase(ConfigFileTestCase): "registration_shared_secret_path: /does/not/exist", "macaroon_secret_key_path: /does/not/exist", "form_secret_path: /does/not/exist", + "worker_replication_secret_path: /does/not/exist", "experimental_features:\n msc3861:\n client_secret_path: /does/not/exist", "experimental_features:\n msc3861:\n admin_token_path: /does/not/exist", *["redis:\n enabled: true\n password_path: /does/not/exist"] @@ -170,6 +171,10 @@ class ConfigLoadingFileTestCase(ConfigFileTestCase): "form_secret_path: {}", lambda c: c.key.form_secret.encode("utf-8"), ), + ( + "worker_replication_secret_path: {}", + lambda c: c.worker.worker_replication_secret.encode("utf-8"), + ), ( "experimental_features:\n msc3861:\n client_secret_path: {}", lambda c: c.experimental.msc3861.client_secret().encode("utf-8"),