Getting started with secrets
Add your first secret to a Loom workflow in under ten minutes. This guide walks through end-to-end setup using 1Password (recommended for teams), then covers KeePass and environment passthrough as alternatives.
What you will do
- Configure a 1Password service account token.
- Create or verify a secret in your 1Password vault.
- Reference the secret in a workflow.
- Run the workflow and confirm the secret is resolved and redacted.
Prerequisites
- Loom CLI available (run
loom --versionto confirm). - A working Loom workspace (
loom checksucceeds). - A shell session where you can export environment variables.
Option A: 1Password (recommended)
1Password is the recommended secrets provider for team workflows. It provides centralized vault management, access control, and audit logging out of the box. Loom resolves op:// references through the 1Password Go SDK — no op CLI installation is needed.
A1. Export your service account token
Create a 1Password service account if you do not have one. The token starts with ops_....
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
Verify connectivity by listing accessible vaults:
loom secrets op vault list
You should see output like:
name=Engineering id=vlt_abc123
name=Platform id=vlt_def456
A2. Create a secret (or use an existing one)
If you already have an item in your vault, skip to A3.
Store a deploy token using the Loom CLI:
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
Expected output:
item field created: vault=Engineering item=services/loom/deploy field=token
Verify the item exists (no secret values are printed):
loom secrets op item list --vault Engineering
services/loom/deploy token
A3. Reference the secret in a workflow
Add a secrets block to a job. The ref URI tells Loom which vault entry to resolve:
version: v1
stages: [ci]
deploy:
stage: ci
target: linux
secrets:
DEPLOY_TOKEN:
ref: op://Engineering/services/loom/deploy/token
script:
- echo "Token file path is $DEPLOY_TOKEN"
- curl -H "Authorization: Bearer $(cat $DEPLOY_TOKEN)" https://api.example.com/deploy
Key points:
refformat:op://<vault>/<item-path>/<field>.filedefaults totrue:$DEPLOY_TOKENcontains a path to a temp file. Read the value withcat "$DEPLOY_TOKEN".requireddefaults totrue: if the secret cannot be resolved, the job fails before script execution.- No credentials in YAML: the token value never appears in workflow files.
A4. Validate and run
loom check
loom run --local --workflow .loom/workflow.yml
What to expect:
- The job starts and the secret is resolved from 1Password.
- Console output shows
$DEPLOY_TOKENas a file path (e.g./tmp/loom-secret-DEPLOY_TOKEN-0). - Any output that contains the actual token value is redacted to
[REDACTED:SECRET_DEPLOY_TOKEN]. - Runtime logs under
.loom/.runtime/logs/<run_id>/contain only redacted output.
Option B: KeePass (local encrypted vaults)
KeePass is ideal when you need offline, encrypted secret storage without external services. Loom manages .kdbx databases through alias-driven configuration.
B1. Create a KeePass vault
export KEEPASS_PASSWORD="pick-a-strong-master-password"
loom secrets keepass vault create \
--password-from-env KEEPASS_PASSWORD
Expected output:
vault created: alias=<your-repo-path> path=.loom/keepass/<ALIAS>.kdbx
The vault alias defaults to your Git remote origin path (e.g. group/project/repo). Override with --vault-path <alias>.
B2. Configure runtime access
The CLI creates the .kdbx file, but runtime resolution requires environment variables. Before running loom check or loom run, export:
export LOOM_KEEPASS_DB_GROUP_PROJECT_REPO_PATH="$PWD/.loom/keepass/GROUP_PROJECT_REPO.kdbx"
export LOOM_KEEPASS_DB_GROUP_PROJECT_REPO_PASSWORD_ENV="KEEPASS_PASSWORD"
export KEEPASS_PASSWORD="pick-a-strong-master-password"
Replace GROUP_PROJECT_REPO with the uppercase, underscore-delimited version of your vault alias.
Store these exports in a local .env file (excluded from version control) and source it at the start of each session.
B3. Add a secret and reference it
export DEPLOY_TOKEN_VALUE="ghp_abc123_your_real_token"
loom secrets keepass item create \
--item-path services/deploy \
--field token \
--value-from-env DEPLOY_TOKEN_VALUE
Reference it in your workflow:
deploy:
stage: ci
target: linux
secrets:
DEPLOY_TOKEN:
ref: keepass://<alias>#services/deploy:token
script:
- curl -H "Authorization: Bearer $(cat $DEPLOY_TOKEN)" https://api.example.com/deploy
B4. Validate and run
loom check
loom run --local --workflow .loom/workflow.yml
Option C: Environment passthrough (env://)
The simplest option — reads a value directly from the host environment. No vault setup required.
deploy:
stage: ci
target: linux
secrets:
DEPLOY_TOKEN:
ref: env://DEPLOY_TOKEN
script:
- curl -H "Authorization: Bearer $(cat $DEPLOY_TOKEN)" https://api.example.com/deploy
Before running:
export DEPLOY_TOKEN="ghp_abc123"
loom run --local --workflow .loom/workflow.yml
Use env:// for quick prototyping or when secrets are already managed by your CI runner.
Injection modes
By default, $SECRET_NAME holds a path to a temp file containing the value. Some tools expect the raw value in the env var instead.
| Mode | file setting | Job sees | When to use |
|---|---|---|---|
| File injection (default) | true | Path to a 0600 temp file | Most cases — lower leakage risk |
| Direct injection | false | Raw secret value | Only when a tool cannot read from a file |
Example: direct injection for npm publish
secrets:
NPM_TOKEN:
ref: env://NPM_TOKEN
file: false
Tradeoff: direct injection is more exposed to shell tracing (set -x). If CI_DEBUG_TRACE=true is set and any secret uses file: false, Loom hard-fails with SECRETS_UNSAFE_DEBUG_TRACE to prevent accidental exposure.
Optional secrets
Mark a secret required: false when the job should succeed even if the secret is unavailable:
secrets:
SLACK_WEBHOOK:
ref: op://Engineering/notifications/webhook
required: false
Your script should handle the missing-variable case:
if [ -n "$SLACK_WEBHOOK" ]; then
curl -X POST "$(cat $SLACK_WEBHOOK)" -d '{"text":"Deploy complete"}'
fi
Validation rules
| Rule | What happens on violation |
|---|---|
A key cannot be in both variables and secrets for the same job | Schema validation error (fail-fast) |
default.secrets is not allowed | Schema validation error |
Secret names must match ^[A-Z_][A-Z0-9_]*$ | Schema validation error |
ref must use a supported URI scheme | SECRETS_REF_INVALID |
| Missing required secret | SECRETS_REQUIRED_MISSING — job fails |
CI_DEBUG_TRACE=true with file: false secrets | SECRETS_UNSAFE_DEBUG_TRACE |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
SECRETS_PROVIDER_UNAVAILABLE | Auth config missing or invalid for the provider | Check OP_SERVICE_ACCOUNT_TOKEN or LOOM_KEEPASS_DB_* env vars |
SECRETS_REQUIRED_MISSING | Env var not exported (env://), or vault entry missing | Export the variable or verify the vault item exists |
SECRETS_REF_NOT_FOUND | Entry path or field does not match vault contents | Verify ref against loom secrets op item list or keepass item list |
SECRETS_REF_INVALID | Typo in URI scheme or malformed ref | Verify scheme is env://, keepass://, or op:// |
| Script fails reading secret value | file: true (default) but script expects a direct value | Use cat "$VAR_NAME" in scripts, or set file: false |
Schema error: key in both variables and secrets | Same name in both blocks for one job | Remove the key from variables |
SECRETS_UNSAFE_DEBUG_TRACE | CI_DEBUG_TRACE=true with file: false secrets | Disable debug trace or switch to file: true |
What to read next
- Secrets overview — complete reference for the secrets model.
- Secrets security — threat model, controls, and incident response.
- 1Password CLI reference — vault and item management commands.
- KeePass CLI reference — database, entry, and field commands.
- Secrets error codes — full error code reference.