Relationships
#2345 worker secret allowlist rejects caller-chosen vault references resolved at run time (method args carrying {vaultName, secretKey})
Opened by randybias · 9/22/2026
Problem
A worker's secret allowlist is built only from vault.get(...) expressions found in the step's global and method args (dispatch_service.ts:496, extractVaultReferences). A method that is given a vault reference as plain data and resolves it at run time through the capability bridge gets refused:
[WRN] worker·bridge: Bridge "capability.resolveSecret" failed after 4ms (...):
"resolveSecret: secret 'inventory_db_root_password' is not referenced by the dispatched step"
✗ Dispatch 5af91441: @mirantis/inventory-ingest.listReservations failed in 666msThe same workflow and inputs succeed on a local run (loopback), and on serve's loopback.
Why we pass references, not vault.get expressions
We pass {vaultName: ${{ inputs.dbPassVault }}, secretKey: ${{ inputs.dbPassKey }}} so that one definition can run against production and against a test twin with a different vault and key. Our reading was that vault.get() resolves its arguments verbatim, so a run-time input cannot select the vault or key. That gives the choice: either the extension resolves the reference, or the workflow hard-codes the vault. 131 of our 319 workflow files use this pattern. None of them can be placed on a worker.
Reproduction (20260922.011324.0)
A step with workflow-level labels: {pool: x} calls a method with arg dbPassVaultRef: {vaultName: ${{ inputs.v }}, secretKey: ${{ inputs.k }}}. The method resolves the reference through the context vault. Run it via swamp workflow run --server ... with one enrolled worker. The dispatch fails as shown above.
Ask, any one of these
- A declared reference type in the model's arg schema (for example a
vaultRef/sensitiveRefmarker) whose resolved{vaultName, secretKey}values count as static refs inextractVaultReferences. vault.get(${{ inputs.v }}, ${{ inputs.k }})resolving input-driven arguments before dispatch. It would then land instaticRefsafter resolution, with the allowlist computed after expression resolution.- Documentation of the supported way for a method to take a caller-chosen secret under placement.
Open
No activity in this phase yet.