Pattern: secrets for local development
Set up secrets for local Loom workflows. Three providers are available today — env:// for quick prototyping, keepass:// for encrypted local vaults, and op:// for 1Password team vaults.
For the full walkthrough, see Getting started with secrets.
When to use this pattern
You have a workflow that needs passwords, tokens, or private keys at runtime and you want to:
- Keep secrets out of workflow YAML — store references, not values.
- Redact exact secret values in supported log and receipt text. Transformed values and raw declared artifact contents still need inspection before sharing.
- Set up once on your dev machine and share the workflow safely with teammates.
Option A: env:// (quickest path)
env:// reads values already exported in the environment of the process that starts Loom.
1) Export secrets in your shell
Export the sample values in the shell used for the run, or source them from a local .env file excluded from version control:
export DEPLOY_TOKEN="ghp_abc123..."
export DATABASE_PASSWORD="s3cret"
Never commit .env files or shell profile excerpts containing real secret values. Add .env to your .gitignore.
2) Reference secrets in your workflow
Save this as .loom/workflow.yml. It checks the injected files without printing their contents:
version: v1
stages: [ci]
deploy:
stage: ci
target: linux
secrets:
DEPLOY_TOKEN:
ref: env://DEPLOY_TOKEN
DATABASE_PASSWORD:
ref: env://DATABASE_PASSWORD
script:
- test -r "$DEPLOY_TOKEN" && test -s "$DEPLOY_TOKEN"
- test -r "$DATABASE_PASSWORD" && test -s "$DATABASE_PASSWORD"
- echo "Secret files are readable and non-empty"
filedefaults totrue— the job sees a file path, not the raw value. Read it withcat "$VAR_NAME".requireddefaults totrue— a missing env var fails the job withSECRETS_REQUIRED_MISSING.
3) Run and verify
loom run --local --workflow .loom/workflow.yml
The job should print Secret files are readable and non-empty and the run should exit with status 0. If an exact token value reaches a supported runtime text output, Loom replaces it with [REDACTED:SECRET_DEPLOY_TOKEN]. Transformed values and raw declared artifacts are not covered; inspect and sanitize evidence before sharing it.
Option B: keepass:// (encrypted local vault)
KeePass provides encrypted local storage so secrets don't depend on exported shell variables. The vault file (.kdbx) stays on your machine; Loom unlocks it at runtime using environment variables.
1) Create a vault
export KEEPASS_PASSWORD="pick-a-strong-master-password"
loom secrets keepass vault create \
--vault-path local/main \
--password-from-env KEEPASS_PASSWORD
2) Configure access and add a secret
export LOOM_KEEPASS_DB_LOCAL_MAIN_PATH="$PWD/.loom/keepass/LOCAL_MAIN.kdbx"
export LOOM_KEEPASS_DB_LOCAL_MAIN_PASSWORD_ENV="KEEPASS_PASSWORD"
export DEPLOY_TOKEN_VALUE="tok_example_abc123"
loom secrets keepass item create \
--vault-path local/main \
--item-path services/deploy \
--field token \
--value-from-env DEPLOY_TOKEN_VALUE
3) Keep the alias mapping available
Item commands and workflow runs both need the environment mapping from step 2. Vault creation writes a database file but does not save a mapping. Keep KEEPASS_PASSWORD set to the password used in step 1.
The alias is uppercased with / replaced by _ to form the variable prefix (local/main → LOOM_KEEPASS_DB_LOCAL_MAIN_).
| Variable | Purpose | Required |
|---|---|---|
LOOM_KEEPASS_DB_<ALIAS>_PATH | Absolute path to the .kdbx file | Yes |
LOOM_KEEPASS_DB_<ALIAS>_PASSWORD_ENV | Name of env var containing the master password | One of password or keyfile |
LOOM_KEEPASS_DB_<ALIAS>_KEYFILE_ENV | Name of env var containing the keyfile path | One of password or keyfile |
Store these exports in a local .env file excluded from version control and source it at the start of each session.
4) Reference secrets with keepass://
Replace the DEPLOY_TOKEN reference in the job above with this entry. The database-password check from Option A still needs its own reference and value if you keep it.
secrets:
DEPLOY_TOKEN:
ref: keepass://local/main#services/deploy:token
URI structure: keepass://<database-alias>#<entry-path>:<field>
| Segment | Description | Example |
|---|---|---|
<database-alias> | Alias from env var config | local/main |
<entry-path> | Group/item path inside the KeePass database | services/deploy |
<field> | Field name to read | token, password |
5) Validate and run
loom check
loom run --local --workflow .loom/workflow.yml
Full provider reference: Workflows secrets: KeePass.
Option C: op:// (1Password team vaults)
1Password provides shared team vaults with access control. Loom resolves op:// references through the 1Password Go SDK at execution time — no op CLI installation required. You need a service account token.
1) Set up a service account
Create a service account at 1Password service accounts and grant it access to the vault(s) your workflows need.
2) Export the token
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
3) Verify vault access
loom secrets op vault list
Expected output:
name=Engineering id=vlt_abc123
4) Store a secret (or use an existing item)
export DEPLOY_TOKEN_VALUE="tok_example_abc123"
loom secrets op item create \
--vault Engineering \
--item-path services/loom/deploy \
--field token \
--value-from-env DEPLOY_TOKEN_VALUE
5) Reference secrets with op://
secrets:
DEPLOY_TOKEN:
ref: op://Engineering/services/loom/deploy/token
URI structure: op://<vault>/<item-path>/<field>
| Segment | Description | Example |
|---|---|---|
<vault> | 1Password vault name or UUID | Engineering |
<item-path> | Item title/path in 1Password | services/loom/deploy |
<field> | Field name to resolve | token, password |
6) Validate and run
loom check
loom run --local --workflow .loom/workflow.yml
Full provider reference: Workflows secrets: 1Password.
Direct injection for tools that require env values
Some tools (e.g., npm publish reading $NPM_TOKEN) expect the secret value directly in the environment, not a file path. Use file: false:
secrets:
NPM_TOKEN:
ref: env://NPM_TOKEN
file: false
Tradeoff: direct injection is more exposed to shell tracing (set -x). Loom hard-fails with SECRETS_UNSAFE_DEBUG_TRACE if CI_DEBUG_TRACE=true and any secret uses file: false.
Prefer file: true (the default) unless your tooling specifically requires a direct environment value.
Provider comparison
| Provider | Auth mechanism | Best for | Docs |
|---|---|---|---|
env:// | Host environment variables | Quick setup, CI runners | Workflows → Secrets |
keepass:// | Local .kdbx file + master password or keyfile | Encrypted local storage, solo dev | KeePass provider |
op:// | OP_SERVICE_ACCOUNT_TOKEN (1Password Go SDK) | Team vaults, shared access control | 1Password provider |
Common pitfalls
| Symptom | Cause | Fix |
|---|---|---|
SECRETS_REQUIRED_MISSING | Env var not exported before running Loom | export VAR_NAME="value" in your shell |
SECRETS_PROVIDER_UNAVAILABLE | Missing alias mapping, vault auth, or expired token | Verify provider env vars; for op://, check token with loom secrets op vault list |
SECRETS_REF_NOT_FOUND | Typo in ref or missing vault entry | Check ref against loom secrets keepass item list or loom secrets op item list --vault <vault> |
SECRETS_REF_INVALID | Malformed URI (wrong scheme, missing segments) | Check URI format for the provider |
| Script fails reading secret | file: true (default) but script expects a direct value | Use cat "$VAR_NAME" or set file: false |
SECRETS_UNSAFE_DEBUG_TRACE | CI_DEBUG_TRACE=true with file: false secrets | Disable debug trace or switch to file: true |
Team workflow
When sharing workflows that use secrets:
- Workflow YAML goes in version control — it contains only references, not values.
- Document required env vars in a
READMEor onboarding doc (e.g., "setDEPLOY_TOKENandDATABASE_PASSWORDbefore running"). - Each developer provides their own values — from their shell, a local
.envfile, or their 1Password account. - Use
required: falsefor optional secrets so the workflow runs even if a teammate doesn't have a particular value configured.
Related docs
- Getting started with secrets — end-to-end walkthrough
- Concepts → Secrets — mental model, redaction, injection modes
- Workflows → Secrets — YAML syntax, provider URIs, validation rules
- Secrets with
env://example — runnable example workflow - Secrets error codes — all
SECRETS_*error codes with fixes