Workflows secrets: 1Password
Wire 1Password-backed secrets into Loom workflows using op:// references. Loom resolves entries through the 1Password Go SDK at execution time — no op CLI installation required.
Prerequisites
- A 1Password service account with access to the target vault(s). Create one at 1Password service accounts.
OP_SERVICE_ACCOUNT_TOKENexported in the shell or CI runner environment.- At least one item stored in an accessible vault.
If you have not set up 1Password with Loom yet, follow Getting started with secrets — Option A: 1Password.
Example job
deploy:
stage: ci
target: linux
secrets:
DEPLOY_TOKEN:
ref: op://Engineering/services/loom/deploy/token
file: true
required: true
API_PASSWORD:
ref: op://Engineering/services/loom/api/password
file: false
script:
- echo "Deploying with credentials..."
- curl -H "Authorization: Bearer $(cat "$DEPLOY_TOKEN")" https://api.example.com/deploy
DEPLOY_TOKEN is file-injected (default) — the variable holds a temp-file path, so the script reads the value with cat. API_PASSWORD uses direct injection (file: false) and is available as a raw environment variable.
URI anatomy
op://<vault>/<item-path>/<field>
└──┬──┘ └────┬────┘ └──┬──┘
vault name item title/ field to
or UUID path segment resolve
| Segment | Description | Example |
|---|---|---|
<vault> | 1Password vault name or UUID. The service account must have access to this vault. | Engineering |
<item-path> | Item title or path segment as stored in 1Password. Use / separators for nested organization. | services/loom/deploy |
<field> | Field name to resolve from the item. | token, password, username |
Full example: op://Engineering/services/loom/deploy/token resolves the token field from the item at services/loom/deploy in the Engineering vault.
Runtime configuration
1Password resolution requires a single environment variable:
| Variable | Purpose | Required |
|---|---|---|
OP_SERVICE_ACCOUNT_TOKEN | Service account token (starts with ops_...) used to authenticate with the 1Password API | Yes |
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
Verify connectivity by listing accessible vaults:
loom secrets op vault list
If the token is missing, expired, or lacks access to the target vault, resolution fails with SECRETS_PROVIDER_UNAVAILABLE.
Script behavior by injection mode
file: true (default) — the variable holds a file path:
TOKEN=$(cat "$DEPLOY_TOKEN")
curl -H "Authorization: Bearer ${TOKEN}" https://api.example.com/deploy
file: false — the variable holds the raw value:
echo "machine api.example.com password ${API_PASSWORD}" >> ~/.netrc
Prefer file: true unless your tooling specifically requires a direct environment value. File injection prevents secret values from appearing in shell traces (set -x), process listings (ps), and command-line argument logs.
For Docker jobs, file-injected secrets are bind-mounted read-only into the container. Scripts inside the container use the same cat "$VAR" pattern.
Complete walkthrough
From service account setup to a successful workflow run:
1. Export the service account token:
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
2. Verify vault access:
loom secrets op vault list
Expected output:
name=Engineering id=vlt_abc123
3. Store a secret (or use an existing item):
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
4. Reference in the workflow:
deploy:
stage: ci
target: linux
secrets:
DEPLOY_TOKEN:
ref: op://Engineering/services/loom/deploy/token
script:
- curl -H "Authorization: Bearer $(cat "$DEPLOY_TOKEN")" https://api.example.com/deploy
5. Validate and run:
loom check
loom run --local --workflow .loom/workflow.yml
Safety checklist
- Keep the service account token outside workflow YAML and
variablesblocks — supply it through the runtime environment only. - Use least-privilege token scoping — grant access only to the vaults and items your workflows require.
- Rotate service account tokens on a defined schedule.
- Prefer
file: truefor lower leakage risk. - Avoid
CI_DEBUG_TRACE=truewhen any secret usesfile: false. - Validate with
loom checkbefore running.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
SECRETS_PROVIDER_UNAVAILABLE | Missing, expired, or invalid OP_SERVICE_ACCOUNT_TOKEN, or token lacks access to the target vault | Verify the token is exported and valid; check vault access with loom secrets op vault list |
SECRETS_REF_NOT_FOUND | Vault, item, or field does not exist in 1Password | List items with loom secrets op item list --vault <vault> and confirm the path and field |
SECRETS_REF_INVALID | Malformed op:// URI (missing vault, item, or field segment) | Check URI format: op://<vault>/<item-path>/<field> |
SECRETS_REQUIRED_MISSING | Required secret could not be resolved and required is true (default) | Fix the provider config, or set required: false if the secret is optional |
| Script gets a file path instead of a value | file: true (default) but script expects raw value | Use cat "$VAR" in the script, or set file: false on the secret |
Read next
- 1Password provider overview — provider architecture, auth model, and configuration reference
- 1Password install and setup — service account creation and token configuration
- 1Password CLI reference —
loom secrets opcommands - Workflows secrets overview — YAML shape, spec fields, and all providers