Skip to main content

ROUTE SENSITIVE FIELDS TO SPECIFIC VAULTS

This guide shows you how to control which vault receives sensitive field values when a behavior method runs. By default, Swamp stores sensitive fields in the vault named by defaultVault in .swamp.yaml, which swamp repo init sets to the default vault it creates. When you have multiple vaults — for example, separate backends for production and development secrets — you can direct fields to specific vaults at three levels: the repository, the individual behavior definition, and the workflow step.

Prerequisites

Two or more vaults configured in the repository. A new repository already has the default vault; this guide adds two more:

$ swamp vault create local_encryption prod-secrets
INF vault·create: Created vault: "prod-secrets" ("Local Encryption")
$ swamp vault create local_encryption dev-secrets
INF vault·create: Created vault: "dev-secrets" ("Local Encryption")

Set a default vault for the repository

Set defaultVault in .swamp.yaml, replacing default if swamp repo init wrote it:

defaultVault: prod-secrets

All sensitive resource output fields now store in prod-secrets unless a field-level or spec-level override directs them elsewhere.

defaultVault also applies to swamp serve OAuth token storage and device authorization token storage.

Override per resource in a behavior definition

To route a specific resource's sensitive fields to a different vault, add a resources block to the behavior definition YAML. Each key matches the name of a ResourceOutputSpec declared by the behavior type.

To find the available resource spec names for a behavior type:

$ swamp behavior type describe <type>

Then add the override in the definition file:

type: "@acme/cloud-provisioner"
name: my-provisioner
globalArguments:
  region: us-east-1
resources:
  credentials:
    vaultName: prod-secrets
  config:
    vaultName: dev-secrets

In this definition, sensitive fields in the credentials resource store in prod-secrets, while those in config store in dev-secrets.

Override per workflow step

When one definition's outputs should land in different vaults depending on the workflow that runs it — a production vault for a production workflow — set vaultName in the step's dataOutputOverrides:

name: deploy-prod
vaults: [prod-secrets]
jobs:
  - name: deploy
    steps:
      - name: provision
        task:
          type: model_method
          modelIdOrName: my-provisioner
          methodName: provision
        dataOutputOverrides:
          - specName: credentials
            vaultName: prod-secrets

For the same spec, the step's vaultName wins over the definition's resources.<specName>.vaultName. Fields the step leaves out, such as lifetime and garbageCollection, still come from the definition.

To choose the vault per run, use an expression:

inputs:
  properties:
    vault: { type: string }
jobs:
  - name: deploy
    steps:
      - name: provision
        task:
          type: model_method
          modelIdOrName: my-provisioner
          methodName: provision
        dataOutputOverrides:
          - specName: credentials
            vaultName: ${{ inputs.vault }}
$ swamp workflow run deploy --input vault=prod-secrets

If the workflow has a vaults list, the step's vault must be in it. swamp workflow validate reports a fixed vaultName the list does not name, and a run refuses an evaluated one before the method starts.

Verify which vault received a secret

After running a method that produces sensitive output, check that secrets landed in the expected vault:

$ swamp vault list-keys prod-secrets
INF vault·list-keys: Vault "prod-secrets" ("local_encryption"): 2 key(s)
INF vault·list-keys:   - "acme-cloud-provisioner-abc-provision-accessKey"
INF vault·list-keys:   - "acme-cloud-provisioner-abc-provision-secretKey"

Resolution order

The full precedence chain is:

  1. Field-level vaultName (set by the extension author in TypeScript)
  2. Spec-level vaultName (set by the extension author, overridden via resources.<specName>.vaultName in the definition YAML, or overridden per workflow step via dataOutputOverrides, which wins over the definition)
  3. Repo-level defaultVault in .swamp.yaml
  4. First available vault

Refer to the vault resolution order reference for details on each level.