STORING SECRETS
In this tutorial, we will create a vault, store a secret in it, annotate it with
metadata, reference the secret from a model using a vault.get() expression,
and see Swamp automatically redact it from output.
What we will build
We are going to set up a local encrypted vault, store an API token in it, then create a model that uses the token. When the model runs, we will see the secret resolved into the command but redacted from all output — logs, data, and the terminal.
Prerequisites
- Swamp installed (Hello World covers installation)
- A terminal open in an empty directory
Initialize the repository
First, we create a fresh Swamp repo:
$ mkdir vault-tutorial
$ cd vault-tutorial
$ swamp repo init --tool noneYou will see the Swamp banner followed by:
info repo·init Initialized swamp repository at "..." (tools: "none")Create a vault
Vaults store secrets. We create one using the local_encryption type, which
encrypts secrets on disk using your SSH key:
$ swamp vault create local_encryption secretsinfo vault·create Created vault: "secrets" ("Local Encryption")Store a secret
Now we store a secret in the vault. The value is encrypted at rest — it never appears in plain text in any file:
$ swamp vault put secrets api-token my-secret-valueinfo vault·put Stored secret "api-token" in vault "secrets"We can verify it is stored without seeing the value:
$ swamp vault list-keys secretsinfo vault·list-keys Vault "secrets" ("local_encryption"): 1 key(s)
info vault·list-keys - "api-token"Annotate the secret
Secrets accumulate over time and it becomes hard to remember what each one is for. We add metadata — a URL to the settings page where the token was created and a note about its purpose:
$ swamp vault annotate secrets api-token \
--url "https://example.com/settings/api" \
--notes "Production API token"info vault·annotate Annotated "api-token" in vault "secrets" (fields: "url, notes")Now inspect shows the metadata without exposing the value:
$ swamp vault inspect secrets api-tokeninfo vault·inspect Metadata for "api-token" in vault "secrets":
info vault·inspect size: 15 chars (15 bytes)
info vault·inspect url: "https://example.com/settings/api"
info vault·inspect notes: "Production API token"
info vault·inspect updated: "..."
info vault·inspect refresh-hook: (none)Notice we can see the size, URL, notes, and when it was last updated — but never the value itself.
Use the secret in a model
Now we create a model that references the secret. This is where vault.get()
comes in:
$ swamp model create command/shell api-callerOpen the definition file (swamp model edit api-caller) and set the run
global argument to a command that uses the secret:
globalArguments:
run: "echo \"Calling API with token: ${{ vault.get('secrets', 'api-token') }}\""The ${{ vault.get('secrets', 'api-token') }} expression reads the secret from
the vault at evaluation time. The secret is resolved into the command before
execution.
Now run it:
$ swamp model method run api-caller executeinfo model·method·run·api-caller·execute Evaluating expressions
info model·method·run·api-caller·execute Executing method "execute"
info model·method·run·api-caller·execute Calling API with token: ***
info model·method·run·api-caller·execute Method "execute" completed on "api-caller"Notice *** where the token value should be. Swamp detected that the output
contains a vault secret and redacted it automatically.
Check the data
Let us look at the stored data to confirm the secret is redacted there too:
$ swamp data get api-caller resultData: result (v1)
Model: api-caller (command/shell)
Content: application/json, 169B
Lifetime: infinite | GC: 10
Tags: type=resource, specName=result, modelName=api-caller
Owner: model-method (...)
Created: ...
Path: .swamp/data/command/shell/.../result/1/raw
{
"exitCode": 0,
"executedAt": "...",
"command": "echo \"Calling API with token: ***\"",
"durationMs": 5,
"stdout": "Calling API with token: ***",
"stderr": ""
}The secret is *** in the command, in stdout, and everywhere else it appears.
The actual value was used when the shell command ran, but it is never stored in
plain text in the data output.
Verify vault health
Swamp can scan model definitions for secrets that were accidentally stored as plain text instead of vault references:
$ swamp doctor secretsScanning definitions for cleartext sensitive global arguments…
✓ No cleartext sensitive global arguments found (1 definition(s) scanned)What we built
We created a vault, stored a secret, annotated it with metadata for future
reference, used vault.get() to reference it from a model definition, and
confirmed that Swamp automatically redacts vault secrets from all output. We
also ran swamp doctor secrets to verify no cleartext secrets leaked into model
definitions.