Skip to main content
← Back to list
01Issue
BugShippedSwamp CLI
Assigneeskeeb

Vault CEL expressions replaced with VaultSecretBag sentinels after model type upgrade

Opened by keeb · 4/12/2026· Shipped 4/13/2026

Description

When a model instance references a sensitive global argument via a CEL vault expression (${{ vault.get("vault", "key") }}), bumping the model type version and adding an upgrades entry causes the model YAML to be re-serialized with the in-memory VaultSecretBag sentinel (__SWAMP_VSEC_<hex>_<n>__) instead of the original CEL expression.

The sentinel prefix is per-process random (crypto.getRandomValues in VaultSecretBag), so subsequent invocations cannot resolve it. The literal sentinel string gets sent to upstream APIs as if it were the secret value.

Steps to reproduce

  1. Define a model type with a sensitive global argument (z.string().meta({ sensitive: true }))
  2. Create an instance with a CEL vault expression in the YAML:
    globalArguments:
      apiKey: ${{ vault.get("myvault", "my-api-key") }}
  3. Run any method — succeeds, secret resolves correctly
  4. Bump the model type version and add an upgrade entry (even a no-op):
    upgrades: [{
      fromVersion: "old", toVersion: "new",
      description: "No-op",
      upgradeAttributes: (old) => old,
    }]
  5. Run a method — the upgrade fires
  6. Inspect models/<type>/<id>.yaml:
    globalArguments:
      apiKey: __SWAMP_VSEC_a1b2c3d4_0__
  7. All subsequent method runs send the literal sentinel to the API → auth failures

Expected

The upgrade pipeline should preserve the original CEL vault expression (or a stable vault reference) rather than persisting the transient per-process sentinel.

Workaround

Manually restore ${{ vault.get("vault", "key") }} in the model YAML.

Source pointer

src/domain/vaults/vault_secret_bag.ts — sentinels are valid only within the process that created the bag. The upgrade pipeline appears to capture resolved sentinels into persisted YAML.

Environment

swamp 20260206.200442.0-sha

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 3 MOREPR_MERGEDSHIPPED

Shipped

4/13/2026, 12:49:13 AM

Click a lifecycle step above to view its details.

03Sludge Pulse
keeb assigned keeb4/12/2026, 11:07:36 PM

Sign in to post a ripple.