Skip to content

feat(config): resolve ${file:...} and ${VAR} references in config - #599

Merged
matt-codecov merged 1 commit into
matth/storage-inventory-tracker-4from
matth/serde-vars-config
Aug 26, 2026
Merged

feat(config): resolve ${file:...} and ${VAR} references in config#599
matt-codecov merged 1 commit into
matth/storage-inventory-tracker-4from
matth/serde-vars-config

Conversation

@matt-codecov

@matt-codecov matt-codecov commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Add serde-vars crate to allow ${file:...} and ${VAR} to be used as values in our config for deferred loads.

storage_cogs:
  type: kafka
  override_params:
    sasl.password: ${file:/var/secrets/kafka-password}
    # sasl.password: ${KAFKA_PASSWORD} # alternate

This is helpful for a few reasons:

  • YAML config can be complete. Static YAML can name secrets/runtime values while deferring the actual loading.
  • We don't need to write bespoke file I/O for secrets/configs that are mounted as files (e.g. GCP secrets).
  • Edge case: the sasl.password config key above.

The override_params map is passed verbatim to rdkafka and rdkafka expects keys such as sasl.password. That value is obviously secret, so we can't include it in our config YAML. However, because the config key contains a ., we can't set it with an environment variable and can only set it in YAML. serde-vars lets us configure the secret in YAML while deferring the actual loading of the secret value until later.


Stack created with GitHub Stacks CLIGive Feedback 💬

@matt-codecov
matt-codecov requested a review from a team as a code owner August 11, 2026 23:40
Comment thread objectstore-server/src/config.rs
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.51%. Comparing base (f42ac54) to head (099b212).

Additional details and impacted files
@@                          Coverage Diff                          @@
##           matth/storage-inventory-tracker-4     #599      +/-   ##
=====================================================================
+ Coverage                              88.47%   88.51%   +0.04%     
=====================================================================
  Files                                    104      104              
  Lines                                  17173    17237      +64     
=====================================================================
+ Hits                                   15194    15258      +64     
  Misses                                  1979     1979              
Components Coverage Δ
Rust Backend 92.52% <100.00%> (+0.03%) ⬆️
Rust Client 81.97% <ø> (ø)
Python Client 93.38% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 476aa6d. Configure here.

Comment thread objectstore-server/src/config.rs
Comment thread objectstore-server/src/config.rs
@matt-codecov
matt-codecov force-pushed the matth/serde-vars-config branch from 476aa6d to a012388 Compare August 12, 2026 16:47
@matt-codecov
matt-codecov force-pushed the matth/serde-vars-config branch from a012388 to 3ab8e17 Compare August 15, 2026 03:32
@matt-codecov
matt-codecov force-pushed the matth/serde-vars-config branch from 3ab8e17 to 6da85e0 Compare August 17, 2026 22:02
@matt-codecov
matt-codecov force-pushed the matth/serde-vars-config branch from 6da85e0 to 93f34d9 Compare August 18, 2026 23:07

@sentry-junior sentry-junior Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One real production footgun for the stated secret-file use case:

${file:...} goes through serde_vars::FileSource, which does read_to_string and keeps the raw contents (including a trailing newline). K8s/GCP secret mounts commonly end with \n, so the motivating sasl.password: ${file:...} path can load successfully and then fail SASL with password\n. Please strip trailing whitespace (or at least a single trailing newline) for string file expansions, document that behavior, and add a regression test where the secret file is newline-terminated.

Related secondary trap from the same crate path: FileSource/EnvSource expand_str runs contents through a bool/number parser and errors if a string field expands to something that looks like true/123. Worth a short doc note (or a thin wrapping Source that always yields strings for this config path) so secret values that happen to look numeric do not fail startup oddly.

Otherwise the load shape looks right: figment fully merges first into a Value, then serde_vars::deserialize expands only matching leaf strings in place during the Config walk, with FileSource before EnvSource so ${file:...} is not mistaken for an env var named file:....

Comment thread objectstore-server/src/config.rs
Comment thread objectstore-server/src/config.rs Outdated
@matt-codecov

Copy link
Copy Markdown
Contributor Author

K8s/GCP secret mounts commonly end with \n, so the motivating sasl.password: ${file:...} path can load successfully and then fail SASL with password\n

this isn't a me problem, this is a secret provisioning problem. you should not provision your secrets with incorrect values.

@matt-codecov
matt-codecov force-pushed the matth/serde-vars-config branch from 93f34d9 to 099b212 Compare August 26, 2026 21:42
@matt-codecov
matt-codecov dismissed sentry-junior[bot]’s stale review August 26, 2026 21:44

K8s/GCP secret mounts commonly end with \n, so the motivating sasl.password: ${file:...} path can load successfully and then fail SASL with password\n

this isn't a me problem, this is a secret provisioning problem. you should not provision your secrets with incorrect values.

@matt-codecov
matt-codecov merged commit 44378d9 into main Aug 26, 2026
26 checks passed
@matt-codecov
matt-codecov deleted the matth/serde-vars-config branch August 26, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants