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
This deployment example uses placeholder URLs. Replace them with your service endpoints before running it. The walkthrough below uses a local file check.
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 tool requires a direct environment value. Loom sets the job variable to a temporary file path and restricts the file to 0600 permissions. This reduces exposure through environment inspection and commands that use only the path. The protection depends on those permissions and Loom's temporary-file cleanup: a tool that reads the contents into a shell trace, process argument, log, or artifact can still expose the value.
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. Save this as .loom/workflow.yml:
version: v1
stages: [ci]
check-secret:
stage: ci
target: linux
secrets:
DEPLOY_TOKEN:
ref: op://Engineering/services/loom/deploy/token
script:
- test -r "$DEPLOY_TOKEN" && test -s "$DEPLOY_TOKEN"
- echo "Secret file is readable and non-empty"
5. Validate and run:
loom check validates structure; the run resolves the secret. The script should print Secret file is readable and non-empty and the run should exit with status 0.
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