Secrets overview
Loom secrets let you pass sensitive values — passwords, tokens, private keys — into jobs at runtime. Workflows store only references, and Loom resolves those references just before execution, keeping secret bytes out of YAML, compiled artifacts, receipts, and logs.
New to secrets? Start with the Secrets concept page for the mental model, then return here for configuration detail.
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, the env var is omitted and the job continues. |
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://<alias>/<db>#<path>:<field> | Alias-based runtime config | KeePass provider |
| 1Password | op://<vault>/<item>/<field> | OP_SERVICE_ACCOUNT_TOKEN | 1Password provider |
All providers follow the same contract: resolve only declared job secrets, return values to the in-memory injection flow, and fail closed on missing or invalid credentials.
Redaction
Resolved secret values are automatically redacted before Loom writes to any output boundary — console streams, receipt stdout/stderr, error fields, and provider lifecycle messages. Redacted output uses stable tokens:
[REDACTED:SECRET_DATABASE_PASSWORD]
Redaction is a defense-in-depth measure. Avoid printing secret-bearing variables in scripts even though redaction is active.
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
Loom enforces several invariants to prevent accidental credential exposure:
- Workflow YAML stores references only — never credential material.
- 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.