Skip to main content

KeePass in workflows

Wire keepass:// secrets into Loom workflow jobs. This page covers declaration syntax, injection modes, optional secrets, multi-secret patterns, Docker job behavior, and validation.

Declaring a KeePass secret

Add a secrets block to any job. Each key becomes an environment variable available to the job's script.

version: v1
stages: [ci]

deploy:
stage: ci
target: linux
secrets:
DATABASE_PASSWORD:
ref: keepass://local/main#services/loom/deploy:password
script:
- ./scripts/deploy.sh

Spec fields

FieldRequiredDefaultDescription
refYesKeePass URI in the format keepass://<alias>#<entry-path>:<field>
fileNotrueWhen 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.
requiredNotrueWhen 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. Declaring secrets under default is invalid and rejected by the schema validator.
  • A key cannot appear in both variables and secrets on the same job — the validator rejects the overlap.

Injection modes

secrets:
DATABASE_PASSWORD:
ref: keepass://local/main#services/loom/deploy:password
file: true

The job environment variable contains a file path. Read the value in scripts:

DB_PASS=$(cat "$DATABASE_PASSWORD")
curl -u "admin:${DB_PASS}" https://db.example.com/health

File injection is the default (file: true). Prefer it because:

  • Secret bytes never appear in the process environment table (not visible to ps or /proc/*/environ).
  • Shell tracing (set -x) prints the file path, not the value.
  • Tools that accept credential files (e.g. --password-file) work directly with the path.

Direct injection (use only when required)

secrets:
API_TOKEN:
ref: keepass://local/main#services/loom/deploy:token
file: false

The job environment variable contains the raw secret value. Use only when a tool requires an environment variable value and cannot read from a file.

echo "machine api.example.com password ${API_TOKEN}" >> ~/.netrc
caution

CI_DEBUG_TRACE=true combined with any file: false secret triggers a hard failure (SECRETS_UNSAFE_DEBUG_TRACE) before job execution. Either disable debug trace or switch the secret to file: true.

Optional secrets

Mark a secret required: false when the workflow should continue even if the secret is unavailable:

secrets:
OPTIONAL_WEBHOOK:
ref: keepass://local/main#services/loom/notifications:webhook
required: false

If resolution fails, the environment variable is omitted entirely — it is not set to an empty string. Scripts can check for its presence:

if [ -n "${OPTIONAL_WEBHOOK+x}" ]; then
curl -X POST "$(cat "$OPTIONAL_WEBHOOK")" -d '{"status": "deployed"}'
fi

Multiple secrets in a single job

Jobs can declare any number of secrets. Each resolves independently.

deploy:
stage: ci
target: linux
secrets:
DATABASE_PASSWORD:
ref: keepass://local/main#services/loom/deploy:password
API_TOKEN:
ref: keepass://local/main#services/loom/deploy:token
file: false
DEPLOY_KEY:
ref: keepass://team#infra/deploy:ssh-key
script:
- ./scripts/deploy.sh

Secrets can reference different aliases (local, team) in the same job. Each alias resolves through its own set of LOOM_KEEPASS_DB_<KEY>_* environment variables.

Docker jobs

For Docker-based jobs (target: docker or jobs with an image field), file-injected secrets are automatically bind-mounted read-only into the container. Loom rewrites the environment variable to the container-local path.

deploy:
stage: ci
target: docker
image: alpine:3.19
secrets:
DATABASE_PASSWORD:
ref: keepass://local/main#services/loom/deploy:password
script:
- DB_PASS=$(cat "$DATABASE_PASSWORD")
- echo "Connected with credentials"

Scripts inside the container use the same cat "$VAR_NAME" pattern — no path translation needed.

URI authoring guidelines

GuidelineExampleRationale
Use environment-specific aliaseslocal, team, prodMakes workflow YAML portable across environments
Use predictable entry pathsservices/loom/<component>Easier to audit and discover with item list
Use explicit field namespassword, token, usernameSelf-documenting; avoids reliance on default fields
Specify enough path segmentsservices/loom/deploy not just deployPrevents ambiguous matches (see entry path matching)

Validation

Always validate before running to catch URI format errors and missing configuration early:

loom check

loom check validates:

  • URI syntax for all keepass:// references.
  • No overlap between secrets and variables keys.
  • No secrets declared under default.

To run the workflow after validation:

loom run --local --workflow .loom/workflow.yml

Troubleshooting

Error codeCauseFix
SECRETS_PROVIDER_UNAVAILABLEAlias mapping or credential environment is misconfiguredVerify LOOM_KEEPASS_DB_<KEY>_* env vars — see Install and setup
SECRETS_REF_NOT_FOUNDEntry path or field does not exist in the .kdbx fileRun loom secrets keepass item list to check available entries
SECRETS_REF_INVALIDMalformed URI or ambiguous entry pathCheck URI format against URI format
SECRETS_REQUIRED_MISSINGA required: true secret could not be resolvedFix the provider config or set required: false for optional secrets
SECRETS_UNSAFE_DEBUG_TRACECI_DEBUG_TRACE=true with a file: false secretRemove debug trace or switch the secret to file: true