Secrets overview
Loom passes passwords, tokens, and private keys into jobs at runtime. Workflow secrets entries store provider references, which Loom resolves before execution. Loom redacts exact matches for these values in the text outputs listed below; transformed values and raw declared artifact contents are not covered.
For an introduction, read the Secrets concept page. This page describes the configuration fields.
Declaring a secret
Each secret maps an environment variable name to a provider reference on a job block:
deploy:
stage: ci
target: linux
secrets:
DATABASE_PASSWORD:
ref: keepass://local/main#services/loom/deploy:password
file: true
API_TOKEN:
ref: op://Engineering/services/loom/deploy/token
file: false
required: false
script:
- ./scripts/deploy.sh
Spec fields
| Field | Required | Default | Description |
|---|---|---|---|
ref | Yes | — | Provider URI. Scheme determines which provider resolves the value (env://, keepass://, op://). |
file | No | true | When true, Loom writes the value to a 0600 temp file and sets the env var to the file path. When false, the raw value is placed directly in the env var. |
required | No | true | When true, the job fails if the secret cannot be resolved. When false, Loom skips injection and the job continues. An inherited Host variable with the same name can remain. |
Scoping rules
- Secrets are job-scoped only.
default.secretsis invalid and rejected by the schema validator. - A key cannot appear in both
variablesandsecretson the same job — the validator rejects the overlap.
Injection modes
| Mode | file value | Job sees | When to use |
|---|---|---|---|
| File injection (default) | true | Path to a 0600 temp file containing the secret | Most cases — reduces leakage from shell tracing, ps, and interpolation |
| Direct injection | false | Raw secret value in the environment variable | Only when a tool requires a direct env value and cannot read from a file |
For Docker jobs, file-injected secrets are bind-mounted read-only into the container and rewritten to container-local paths. Scripts inside the container use the same cat "$VAR_NAME" pattern.
Reading a file-injected secret in a script
# file: true (default) — the variable holds a file path
DB_PASS=$(cat "$DATABASE_PASSWORD")
curl -u "admin:${DB_PASS}" https://db.example.com/health
Using a direct-injected secret
# file: false — the variable holds the raw value
echo "machine api.example.com password ${API_TOKEN}" >> ~/.netrc
Supported providers
| Provider | URI scheme | Auth requirement | Documentation |
|---|---|---|---|
| Environment passthrough | env://<VAR_NAME> | None (reads host env) | Providers index |
| KeePass | keepass://<database-alias>#<path>:<field> | Alias-based runtime config | KeePass provider |
| 1Password | op://<vault>/<item>/<field> | OP_SERVICE_ACCOUNT_TOKEN | 1Password provider |
All providers resolve only declared job secrets and return values to the injection flow. Missing or invalid credentials fail the job for required secrets. If an unresolved secret sets required: false, Loom omits it from injection and continues.
Redaction
Loom replaces exact matches for declared secret values in console/event output, receipt stdout/stderr, output-bearing errors, and provider lifecycle messages. Redacted output uses stable tokens:
[REDACTED:SECRET_DATABASE_PASSWORD]
Redaction is a defense-in-depth measure, not a shareability guarantee. It does not match transformed or encoded values and does not inspect raw declared artifact contents. Avoid printing secret-bearing variables, and inspect and sanitize logs, receipts, errors, provider messages, and artifacts before sharing them.
Error codes
When secret resolution fails, Loom reports a deterministic error code:
| Code | Cause | Resolution |
|---|---|---|
SECRETS_PROVIDER_UNAVAILABLE | Provider backend, config, or auth is unavailable | Check provider auth setup — see the relevant provider docs |
SECRETS_REF_INVALID | Malformed or unsupported ref URI | Verify URI scheme and format against the provider's URI anatomy |
SECRETS_REF_NOT_FOUND | Target entry, item, or field does not exist in the provider | Check vault/database contents and confirm the path is correct |
SECRETS_REQUIRED_MISSING | A required: true secret could not be resolved | Either fix the provider config or set required: false if the secret is optional |
SECRETS_UNSAFE_DEBUG_TRACE | CI_DEBUG_TRACE=true combined with a file: false secret | Remove debug trace or switch the secret to file: true |
Security guardrails
The secrets schema accepts provider references, and Loom rejects unsafe debug-trace settings. Keep credential material out of all other workflow fields as well:
- Use provider references in workflow YAML and keep credential values outside committed files.
- Vault credentials (master passwords, keyfiles, service account tokens) must be supplied through runtime environment configuration, not workflow files.
CI_DEBUG_TRACE=truewith anyfile: falsesecret triggers a hard failure before execution.
For the full threat model, controls, and incident response procedures, see Secrets security.
Related pages
- Secrets concept — mental model and comparison with variables.
- Secrets security — threat model, controls, and operational guardrails.
- Providers index — all supported providers with setup guides.
- KeePass in workflows — workflow-level KeePass usage patterns.
- 1Password in workflows — workflow-level 1Password usage patterns.