Skip to main content

KeePass install and setup

Create a local KeePass vault, map its alias to a database and password, then run a job that checks an injected secret file. The commands below use the alias local throughout.

Prerequisites

  • Loom CLI installed and available in a working Linux workspace (loom version and loom check succeed).
  • A shell session where you can export environment variables.
  • A master password for the vault. If you already have a .kdbx file, use its path and credentials and skip vault creation.

The sample secret value below is for checking the setup. Choose your own master password before storing real credentials.

1. Configure the alias and password

Set the database path and the name of the environment variable that holds its password:

export LOOM_KEEPASS_DB_LOCAL_PATH="$HOME/.config/loom/secrets/local.kdbx"
export LOOM_KEEPASS_DB_LOCAL_PASSWORD_ENV="KEEPASS_LOCAL_PASSWORD"
export KEEPASS_LOCAL_PASSWORD="pick-a-strong-master-password"

LOOM_KEEPASS_DB_LOCAL_PASSWORD_ENV contains the name KEEPASS_LOCAL_PASSWORD; the latter contains the password itself. This keeps credential values out of Loom's alias mapping. The process environment and any file used to set these variables still need secret handling.

The LOCAL key corresponds to the local alias in a reference:

keepass://local#services/loom/deploy:password

Aliases can include path segments. For example, keepass://local/main#services/loom/deploy:password uses the whole alias local/main, whose environment-variable prefix is LOOM_KEEPASS_DB_LOCAL_MAIN_. See alias key conversion.

tip

If you keep these exports in a local .env file, exclude it from version control and source it before using Loom. Use your CI runner's credential configuration to supply the corresponding environment variables in CI.

2. Create the vault

Skip this step if the configured database already exists.

loom secrets keepass vault create \
--vault-path local \
--database-path "$LOOM_KEEPASS_DB_LOCAL_PATH" \
--password-from-env KEEPASS_LOCAL_PASSWORD

This creates the database file. It does not save an alias registration; the environment variables from step 1 provide the mapping for item commands and workflow runs.

Without --vault-path, the CLI derives an alias from the Git remote origin path. Without --database-path, vault creation writes .loom/keepass/<ALIAS_KEY>.kdbx. The explicit flags above keep this walkthrough independent of those defaults.

See CLI reference: vault create for all flags.

3. Add a secret

export DB_SECRET="sample-value-for-local-check"

loom secrets keepass item create \
--vault-path local \
--item-path services/loom/deploy \
--field password \
--value-from-env DB_SECRET

loom secrets keepass item list --vault-path local

The list command prints entry paths and field names, without secret values. See CLI reference: item create for all flags.

4. Reference the secret in a workflow

Save this as .loom/workflow.yml:

version: v1
stages: [ci]

check-secret:
stage: ci
target: linux
secrets:
DATABASE_PASSWORD:
ref: keepass://local#services/loom/deploy:password
script:
- test -r "$DATABASE_PASSWORD" && test -s "$DATABASE_PASSWORD"
- echo "Secret file is readable and non-empty"

File injection is the default (file: true), so DATABASE_PASSWORD contains a temporary file path. This job checks the file without printing its contents. Scripts that need the value can read it with cat "$DATABASE_PASSWORD"; see KeePass in workflows for the exposure limits of each injection mode.

5. Validate and run

Validate the workflow structure:

loom check

loom check does not open the vault, validate provider URI syntax, or check credentials. Run the job to resolve the reference and verify the injected file:

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

The script should print Secret file is readable and non-empty, and the run should exit with status 0. This checks the example's resolution and injection path; it does not test every redaction path. Use the error table below if the run fails.

Using a keyfile

KeePass also accepts a keyfile, either alone or with a password. For an existing database that requires a keyfile, set:

export LOOM_KEEPASS_DB_LOCAL_KEYFILE_ENV="KEEPASS_LOCAL_KEYFILE"
export KEEPASS_LOCAL_KEYFILE="$HOME/.config/loom/secrets/local.key"

The keyfile must already exist. When creating a new vault that uses it, also pass --keyfile-from-env KEEPASS_LOCAL_KEYFILE to vault create.

ModeRuntime configuration
Password only_PASSWORD_ENV names the password variable
Keyfile only_KEYFILE_ENV names the keyfile-path variable; leave _PASSWORD_ENV unset
Password + keyfileBoth variables are set, and the database requires both credentials

At least one credential source must resolve. Use the same credential combination for creation and later access.

Troubleshooting

SymptomLikely causeFix
SECRETS_PROVIDER_UNAVAILABLEMissing or incorrect alias mapping, unreadable database, or invalid credentialsCheck the alias key, database path, and variables named by _PASSWORD_ENV and _KEYFILE_ENV
SECRETS_REF_NOT_FOUNDEntry path or field does not existRun loom secrets keepass item list --vault-path local and compare it with the reference
SECRETS_REF_INVALIDMalformed URI or ambiguous entry pathCheck the URI format; add enough entry-path segments to identify one entry
SECRETS_REQUIRED_MISSINGRequired secret unresolved at runtimeFix the provider configuration; use required: false only if the secret is optional
Credential indirection failsThe variable named by _PASSWORD_ENV or _KEYFILE_ENV is unsetExport both the mapping variable and the credential variable it names

Security checklist

  • Keep master credentials out of workflow YAML and version control.
  • Prefer file injection and tools that accept credential file paths. Reading the file into a traced command can still expose its contents.
  • Disable CI_DEBUG_TRACE for jobs with file: false secrets.
  • Restrict access to .kdbx files and keyfiles; keep them outside version control or use a separately provisioned CI keyfile for encrypted database storage.
  • Inspect and sanitize logs, receipts, errors, provider messages, and artifacts before sharing them. Exact-match redaction does not cover transformed values or raw declared artifact contents.

Next steps