Skip to content

Commit 131607e

Browse files
authored
Add form_secret_path config option (#18090)
I [was told](#17983 (comment)) about another config option with a secret, so I got `form_secret` a companion: `form_secret_path` This PR makes NixOS and Kubernetes users a little bit happy. Includes docs and tests. ### Pull Request Checklist <!-- Please read https://element-hq.github.io/synapse/latest/development/contributing_guide.html before submitting your pull request --> * [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))
1 parent c4e5a58 commit 131607e

4 files changed

Lines changed: 37 additions & 3 deletions

File tree

changelog.d/18090.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add `form_secret_path` config option.

docs/usage/configuration/config_documentation.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,6 +3238,22 @@ Example configuration:
32383238
```yaml
32393239
form_secret: <PRIVATE STRING>
32403240
```
3241+
---
3242+
### `form_secret_path`
3243+
3244+
An alternative to [`form_secret`](#form_secret):
3245+
allows the secret to be specified in an external file.
3246+
3247+
The file should be a plain text file, containing only the secret.
3248+
Synapse reads the secret from the given file once at startup.
3249+
3250+
Example configuration:
3251+
```yaml
3252+
form_secret_path: /path/to/secrets/file
3253+
```
3254+
3255+
_Added in Synapse 1.125.0._
3256+
32413257
---
32423258
## Signing Keys
32433259
Config options relating to signing keys

synapse/config/key.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@
9696
both defined in config file.
9797
"""
9898

99+
CONFLICTING_FORM_SECRET_OPTS_ERROR = """\
100+
Conflicting options 'form_secret' and 'form_secret_path' are both defined in
101+
config file.
102+
"""
103+
99104
logger = logging.getLogger(__name__)
100105

101106

@@ -201,12 +206,19 @@ def read_config(
201206

202207
# a secret which is used to calculate HMACs for form values, to stop
203208
# falsification of values
204-
self.form_secret = config.get("form_secret", None)
205-
if self.form_secret and not allow_secrets_in_config:
209+
form_secret = config.get("form_secret", None)
210+
if form_secret and not allow_secrets_in_config:
206211
raise ConfigError(
207212
"Config options that expect an in-line secret as value are disabled",
208213
("form_secret",),
209214
)
215+
form_secret_path = config.get("form_secret_path", None)
216+
if form_secret_path:
217+
if form_secret:
218+
raise ConfigError(CONFLICTING_FORM_SECRET_OPTS_ERROR)
219+
self.form_secret = read_file(form_secret_path, "form_secret_path").strip()
220+
else:
221+
self.form_secret = form_secret
210222

211223
def generate_config_section(
212224
self,

tests/config/test_load.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ def test_depreciated_identity_server_flag_throws_error(self) -> None:
138138
"turn_shared_secret_path: /does/not/exist",
139139
"registration_shared_secret_path: /does/not/exist",
140140
"macaroon_secret_key_path: /does/not/exist",
141+
"form_secret_path: /does/not/exist",
141142
"experimental_features:\n msc3861:\n client_secret_path: /does/not/exist",
142143
"experimental_features:\n msc3861:\n admin_token_path: /does/not/exist",
143144
*["redis:\n enabled: true\n password_path: /does/not/exist"]
@@ -165,6 +166,10 @@ def test_secret_files_missing(self, config_str: str) -> None:
165166
"macaroon_secret_key_path: {}",
166167
lambda c: c.key.macaroon_secret_key,
167168
),
169+
(
170+
"form_secret_path: {}",
171+
lambda c: c.key.form_secret.encode("utf-8"),
172+
),
168173
(
169174
"experimental_features:\n msc3861:\n client_secret_path: {}",
170175
lambda c: c.experimental.msc3861.client_secret().encode("utf-8"),
@@ -186,7 +191,7 @@ def test_secret_files_existing(
186191
self, config_line: str, get_secret: Callable[[RootConfig], str]
187192
) -> None:
188193
self.generate_config_and_remove_lines_containing(
189-
["registration_shared_secret", "macaroon_secret_key"]
194+
["form_secret", "macaroon_secret_key", "registration_shared_secret"]
190195
)
191196
with tempfile.NamedTemporaryFile(buffering=0) as secret_file:
192197
secret_file.write(b"53C237")

0 commit comments

Comments
 (0)