Repository navigation
fix(gateway): a dotted secret module setting gets a nested env name - #5241
Merged
paul-nechifor merged 5 commits intoNov 15, 2026
Merged
Conversation
A secret module setting sent with a dotted path (`auth.token`) went to dimos as MODULE__AUTH.TOKEN. dimos splits environment names on `__`, so it read that as one unknown field and refused the launch. The name is now MODULE__AUTH__TOKEN, which dimos reads as the nested setting.
aa-MONTS
requested review from
Dreamsorcerer,
TomCC7,
aclauer,
bogwi,
jeff-hykin,
leshy,
mustafab0,
paul-nechifor and
spomichter
as code owners
November 12, 2026 07:47
Contributor
[Medium impact] This change appears safe to merge. SummaryThe gateway now turns dots in secret module field paths into
Reviews (1) · Last reviewed commit: "fix(gateway): a dotted secret module set..." · Reviewed by Greptile |
Contributor
There was a problem hiding this comment.
go2 replay realtime (arm64)
Details
| Benchmark suite | Current: da9117f | Previous: 0ac6c52 | Ratio |
|---|---|---|---|
peak memory |
1769.812 MB |
1748.082 MB |
1.01 |
peak threads |
378 threads |
391 threads |
0.97 |
network (transport) |
2729.302 MB |
2732.054 MB |
1.00 |
disk write |
1.641 MB |
1.613 MB |
1.02 |
instructions |
138.09 G |
137.927 G |
1.00 |
This comment was automatically generated by workflow using github-action-benchmark.
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #5241 +/- ##
=======================================
Coverage 84.58% 84.59%
=======================================
Files 1925 1925
Lines 189595 189595
Branches 15503 15503
=======================================
+ Hits 160376 160382 +6
+ Misses 25164 25160 -4
+ Partials 4055 4053 -2
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
paul-nechifor
enabled auto-merge (squash)
November 15, 2026 04:21
Recursively identify and redact secrets, emit nested model leaf flags, and keep secret-bearing collections intact in environment values. Resolve parser targets in the launch checkout with its global overrides and preserve configuration aliases and dictionary keys. Add parser round-trip, catalog introspection, and launch/relaunch regression coverage.
paul-nechifor
approved these changes
Nov 15, 2026
…uments The fake run_child in the gateway test fixture only took dimos_dir and args positionally. State.introspected passes stdin as a third positional argument, so any test that introspects a real blueprint through the client failed with a TypeError. The multi-Go2 catalog tests added on main in #5227 do that, which broke CI on the merge of this branch with main. The fake now forwards any extra positional arguments to the real run_child.
…3.10 On Python 3.10 pydantic leaves a string inside a builtin generic such as list["RecursiveOptions"] unresolved in the field annotation. The blueprint config parser then builds a TypeAdapter for it outside the test module, where the name is unknown, and raises PydanticUserError. Two introspect tests failed that way on the 3.10 CI job only. Quoting the whole annotation makes pydantic resolve it on every version.
Conflicts with #5242 (global flags spelled from validated GlobalConfig values): - experimental/gateway/launches.py: keep LaunchConfig.normalized() from main next to this branch's secret_paths(targets). - experimental/gateway/tests/test_launch_config.py: union of both import lists.
paul-nechifor
deleted the
aa-monts/fix/dim-510-nested-secret-env-names
branch
November 15, 2026 08:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
To be reviewed by @paul-nechifor.
Why do we need this?
Launch a blueprint through the gateway with a secret module setting given as a dotted path, for example
config.modules.cam = {"auth.token": "..."}. The gateway keeps secrets off the command line and passes them in the environment, butmodule_env(experimental/gateway/launches.py:153-160) builds the name asCAM__AUTH.TOKEN.dimos runsplits environment names on__only (dimos/core/coordination/blueprint_config/merging.py:124), so it reads one unknown fieldauth.tokenand refuses the launch withExtra inputs are not permitted.What is this feature?
module_envnow turns each dot of a field name into__, so the name isCAM__AUTH__TOKEN, the formdimos runalready reads for a nested setting (GO2CONNECTION__MUJOCO__STEPS_PER_FRAMEindocs/usage/configuration.md). One production line; the existing secrets test gets a dotted secret.This is only the secret half of DIM-510. The public half is not fixed here and needs a decision: the gateway folds
{"mujoco.steps_per_frame": 3}(or the nested object) into--go2connection.mujoco={"steps_per_frame":3}, which the CLI rejects as an unknown option, while the same folding is what a dict-valued field such ascontrolcoordinator.addressesneeds. The gateway cannot tell the two apart without the blueprint's parser schema. Options:CAM__PROFILE='{"exposure":{"gain":3}}'parses today). Roughly 25 to 55 lines inmerging.py, and a new CLI form.launches.start.How to manually run this
main prints
{'CAM__AUTH.TOKEN': 's3cret'}, this branch{'CAM__AUTH__TOKEN': 's3cret'}.Checked parser-only, with a synthetic module whose config nests a pydantic model (no shipped module has a nested secret field): fed to
BlueprintConfigParser, main's name is rejected and the new name sets the nested field. No gateway was started and nothing was launched. A launch that also carries a dotted public nested setting is still rejected, for the reason above.Which issue(s) does this PR close?
Part of DIM-510: the secret half. The public half stays open.
Checklist