Skip to main content

LIMIT WHICH VAULTS A RUN CAN USE

This guide shows you how to limit the vaults a serve run can read and write, with vault:<name> grants for the principal that triggers the run, and with a workflow's vaults: list.

Prerequisites

  • A server running with --auth-mode token or oauth
  • admin on access:*, to write grants
  • Every serve replica on the datastore running a release that supports vault grants. An older replica refuses to start on a grant file holding a vault grant, and ignores stored vault grants, denies included
  • No suspended runs started on an older release. Resume or cancel them first: once any vault grant exists, they refuse every vault operation

Scope a principal to the vaults it needs

A principal given any vault allow can use only the vaults its allows name, for the actions they name. Grant every vault the principal needs in the same change.

To let the room-bot token read roomcontrol and no other vault in its runs, add a grant file:

# grants/room-bot.yaml
grants:
  - subject: "user:room-bot"
    effect: allow
    actions: [read]
    resource: "vault:roomcontrol"
  - subject: "user:room-bot"
    effect: allow
    actions: [run, read]
    resource: "workflow:provision-room"

Apply it:

swamp access reload --server wss://swamp.example.com

Check the run-time decision for each vault the bot uses:

swamp access check --subject user:room-bot --action read --on vault:erp \
  --server wss://swamp.example.com
DENY (implicit) — no matching grants for user:room-bot read vault:erp

In serve runs: DENY read vault erp (vault-scoped)

A run the bot triggers that reads erp fails the step:

Failed to resolve vault expression vault.get("erp", "password"): Reading vault 'erp' is refused for user:room-bot: the principal holds vault grants and none allows read on vault:erp; add a vault:erp allow grant for read to this principal

Block one vault without scoping

A deny-only grant blocks the denied vault and leaves the principal's other vaults as they were:

# grants/ci.yaml
grants:
  - subject: "user:ci"
    effect: deny
    actions: [read, write]
    resource: "vault:prod-*"

Write vault denies as vault:<name> grants. A data: deny does not apply to runs, and a data: deny on a vault name now refuses every request for that vault. Move existing vault denies from data:<name> to vault:<name>.

Give scoped principals a vault for sensitive outputs

Storing a sensitive output, and reading it back, needs read and write on the vault it lands in. Keep author secrets out of that vault:

  1. Create a dedicated outputs vault and make it the default in .swamp.yaml:

    defaultVault: bot-outputs

    Or route outputs per model or per step; see Route Sensitive Fields.

  2. Grant scoped principals read and write on it:

    grants:
      - subject: "user:room-bot"
        effect: allow
        actions: [read, write]
        resource: "vault:bot-outputs"

Granting a default vault that also holds author secrets gives the principal those secrets.

Bound scheduled and webhook runs

Scheduled runs act as service:scheduler and webhook runs as service:webhook. A vault grant on either applies to every scheduled or webhook run on the server. To bound one workflow, list its vaults in the workflow file instead:

name: provision-room
vaults: [roomcontrol, bot-outputs]

Validate it:

swamp workflow validate provision-room

validate reports each static vault.get name and sensitive-output vault that is not listed. See Workflows.