Skip to main content
← Back to list
01Issue
BugShippedSwamp CLIPublic
Assigneesstack72

Relationships

#3680 Workflow runs ignore defaultVault: step sensitive outputs land in the first vault, and validate predicts a vault the run doesn't use

Opened by stack72 · 10/20/2026· Shipped 10/20/2026

Problem

Workflow runs ignore defaultVault from .swamp.yaml. A workflow step's sensitive outputs land in the first user vault (lowest id) instead of the default vault, while swamp behavior run honours it.

  • DefaultStepExecutor.buildDeps (src/domain/workflows/execution_service.ts, the VaultService.fromRepository(repoDir, { vaultsDir }) call) builds the step's vault service without defaultVaultName. It runs every workflow step, locally and on serve.
  • Every other entry point passes defaultVaultName: marker?.defaultVault: model_method_run.ts, workflow_validate.ts, serve's own vault services, the access and vault libswamp operations.
  • So swamp workflow validate predicts the default vault while the run stores to another one.

Repro (released 20261019.214045.0-sha.6dbc53eb)

  1. swamp repo init --tool none --no-vault, then swamp vault create local_encryption vault-b and swamp vault create local_encryption vault-a, so that vault-a has the lower id (swamp vault list --json).
  2. Add defaultVault: vault-b to .swamp.yaml.
  3. A behavior whose create method writes a resource with a sensitive field.
  4. swamp behavior run <def> create stores the field in vault-b (correct).
  5. A workflow with one step running the same method: swamp workflow run stores it in vault-a.
  6. Add vaults: [vault-b] to that workflow: swamp workflow validate passes, then swamp workflow run is refused before the method runs with "stores sensitive output in vault 'vault-a', which this run may not write: ... not in the vaults list".

Expected

A workflow step resolves sensitive outputs like a behavior run does: field vaultName, then step dataOutputOverrides / definition resources vaultName, then the spec's, then defaultVault, then the first user vault (design/primitives/vaults.md Vault Resolution Order).

Impact

  • In a repo with more than one vault, workflow outputs go to whichever vault sorts first, which can be the vault holding author secrets that design/enablers/access-control.md says to keep out of the outputs vault.
  • Under vault scoping it fails closed: the pre-run check refuses the wrong vault, so validate passes and the run fails.
  • A repo with only the default vault created by repo init is unaffected, since the first vault is the default.

Not a regression

defaultVaultName was never passed into the workflow executor (git log -S defaultVaultName on execution_service.ts). defaultVault came in for behavior execution (swamp PR 1984) and this path was missed.

Suggested fix

Read the repo marker's defaultVault once per run, carry it through StepExecutionContext into buildDeps, and pass it as defaultVaultName. The two read-only fromRepository calls (evaluated-cache replay, workflow resume) only call get and do not need it. Add a workflow-run integration test with two vaults where the default is not the lowest id, next to the swamp-club#3606 tests in integration/sensitive_field_vault_test.ts.

Found while testing swamp-club#3606.

02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 7 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

10/20/2026, 8:59:45 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack7210/20/2026, 6:29:54 PM

Sign in to post a ripple.