feat(config): resolve ${file:...} and ${VAR} references in config - #599
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 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
☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ 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.
476aa6d to
a012388
Compare
a012388 to
3ab8e17
Compare
3ab8e17 to
6da85e0
Compare
6da85e0 to
93f34d9
Compare
There was a problem hiding this comment.
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:....
this isn't a me problem, this is a secret provisioning problem. you should not provision your secrets with incorrect values. |
93f34d9 to
099b212
Compare
K8s/GCP secret mounts commonly end with
\n, so the motivatingsasl.password: ${file:...}path can load successfully and then fail SASL withpassword\n
this isn't a me problem, this is a secret provisioning problem. you should not provision your secrets with incorrect values.

Add
serde-varscrate to allow${file:...}and${VAR}to be used as values in our config for deferred loads.This is helpful for a few reasons:
sasl.passwordconfig key above.The
override_paramsmap is passed verbatim tordkafkaandrdkafkaexpects keys such assasl.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-varslets us configure the secret in YAML while deferring the actual loading of the secret value until later.Stack created with GitHub Stacks CLI • Give Feedback 💬