Secret Providers
Haloy integrates with external secret providers to securely resolve credentials during configuration resolution. Define reusable sources under secret_providers, then reference individual values with from.secret.
Secret Reference Format
Secret references use this format:
<provider>:<source>:<key>
<provider>:<source>:<key>
<provider>: The provider name, currentlyonepasswordorsops<source>: The source key defined undersecret_providers.<provider><key>: The field or nested key to resolve from that source
Examples:
onepassword:production-db:passwordsops:development:client.idsops:development:users.0.name
This replaces the earlier provider:source.key proposal. Update existing configurations to the new provider:source:key syntax.
1Password Integration
Configure 1Password to pull item fields during config resolution.
Prerequisites
- 1Password CLI (
op) installed and authenticated - The referenced vault items must exist with fields matching the keys you use in
from.secret
Configuration
name: "my-app"
secret_providers:
onepassword:
production-db:
account: "my-account"
vault: "Production"
item: "Database Credentials"
api-keys:
vault: "API Services"
item: "Third-party APIs"
env:
- name: "DB_PASSWORD"
from:
secret: "onepassword:production-db:password"
- name: "DB_USERNAME"
from:
secret: "onepassword:production-db:username"
- name: "STRIPE_API_KEY"
from:
secret: "onepassword:api-keys:stripe-key"
- name: "SENDGRID_API_KEY"
from:
secret: "onepassword:api-keys:sendgrid-key"
name: "my-app"
secret_providers:
onepassword:
production-db:
account: "my-account"
vault: "Production"
item: "Database Credentials"
api-keys:
vault: "API Services"
item: "Third-party APIs"
env:
- name: "DB_PASSWORD"
from:
secret: "onepassword:production-db:password"
- name: "DB_USERNAME"
from:
secret: "onepassword:production-db:username"
- name: "STRIPE_API_KEY"
from:
secret: "onepassword:api-keys:stripe-key"
- name: "SENDGRID_API_KEY"
from:
secret: "onepassword:api-keys:sendgrid-key"
1Password Item Structure
Your 1Password item fields should match the keys you reference:
usernamepasswordstripe-keysendgrid-key
SOPS Integration
Haloy can resolve secrets from SOPS-encrypted YAML, JSON, and dotenv files. The file is decrypted locally during config resolution, and the requested values are injected into the resolved target config.
Prerequisites
- SOPS CLI (
sops) installed and available in your PATH - Your SOPS file must be decryptable with the keys available on your machine (e.g. an age key in
~/.config/sops/age/keys.txt, or cloud KMS credentials configured)
Configuration
SOPS sources are defined under secret_providers.sops. File paths are resolved relative to your haloy.yaml.
name: "my-app"
secret_providers:
sops:
development:
file: "./secrets.dev.yaml"
deploy-tokens:
file: "./deploy.tokens.env"
format: "dotenv"
env:
- name: "CLIENT_ID"
from:
secret: "sops:development:client.id"
- name: "CLIENT_SECRET"
from:
secret: "sops:development:client.secret"
- name: "HALOY_API_TOKEN"
from:
secret: "sops:deploy-tokens:HALOY_API_TOKEN"
name: "my-app"
secret_providers:
sops:
development:
file: "./secrets.dev.yaml"
deploy-tokens:
file: "./deploy.tokens.env"
format: "dotenv"
env:
- name: "CLIENT_ID"
from:
secret: "sops:development:client.id"
- name: "CLIENT_SECRET"
from:
secret: "sops:development:client.secret"
- name: "HALOY_API_TOKEN"
from:
secret: "sops:deploy-tokens:HALOY_API_TOKEN"
Key Resolution
- YAML and JSON files support nested lookup with dot notation, for example
sops:development:client.id - Arrays use numeric segments, for example
sops:development:users.0.name - Dotenv files use direct keys, for example
sops:deploy-tokens:HALOY_API_TOKEN - If
formatis omitted, Haloy infers it from the file extension
Validation and Limitations
- Binary SOPS files are not supported for key-based lookup
- Structured keys containing
.are rejected to avoid ambiguous lookups - If
formatis omitted, the file extension must be enough to infer it - Validation, read, decrypt, and parse failures include source context to make troubleshooting easier
Registry Authentication with Secrets
Use 1Password to store registry credentials:
name: "my-app"
image:
repository: "ghcr.io/your-org/private-app"
tag: "latest"
registry:
username:
from:
secret: "onepassword:registry-credentials:username"
password:
from:
secret: "onepassword:registry-credentials:password"
secret_providers:
onepassword:
registry-credentials:
vault: "Infrastructure"
item: "GitHub Container Registry"
name: "my-app"
image:
repository: "ghcr.io/your-org/private-app"
tag: "latest"
registry:
username:
from:
secret: "onepassword:registry-credentials:username"
password:
from:
secret: "onepassword:registry-credentials:password"
secret_providers:
onepassword:
registry-credentials:
vault: "Infrastructure"
item: "GitHub Container Registry"
API Token with Secrets
Store your Haloy API token in a SOPS-encrypted dotenv file:
name: "my-app"
server: "api.haloy.dev"
api_token:
from:
secret: "sops:deploy-tokens:HALOY_API_TOKEN"
secret_providers:
sops:
deploy-tokens:
file: "./deploy.tokens.env"
format: "dotenv"
name: "my-app"
server: "api.haloy.dev"
api_token:
from:
secret: "sops:deploy-tokens:HALOY_API_TOKEN"
secret_providers:
sops:
deploy-tokens:
file: "./deploy.tokens.env"
format: "dotenv"
Build Arguments with Secrets
Pass secrets to Docker build as build arguments:
name: "my-app"
image:
repository: "my-app"
tag: "latest"
build_config:
context: "."
args:
- name: "NPM_TOKEN"
from:
secret: "onepassword:build-secrets:npm-token"
- name: "GITHUB_TOKEN"
from:
secret: "onepassword:build-secrets:github-token"
secret_providers:
onepassword:
build-secrets:
vault: "Development"
item: "Build Tokens"
name: "my-app"
image:
repository: "my-app"
tag: "latest"
build_config:
context: "."
args:
- name: "NPM_TOKEN"
from:
secret: "onepassword:build-secrets:npm-token"
- name: "GITHUB_TOKEN"
from:
secret: "onepassword:build-secrets:github-token"
secret_providers:
onepassword:
build-secrets:
vault: "Development"
item: "Build Tokens"
Multi-Target with Different Secrets
Use different SOPS files for different deployment targets:
name: "my-app"
secret_providers:
sops:
production:
file: "./secrets.production.yaml"
staging:
file: "./secrets.staging.yaml"
targets:
production:
server: "prod.myapp.com"
env:
- name: "DB_PASSWORD"
from:
secret: "sops:production:database.password"
staging:
server: "staging.myapp.com"
env:
- name: "DB_PASSWORD"
from:
secret: "sops:staging:database.password"
name: "my-app"
secret_providers:
sops:
production:
file: "./secrets.production.yaml"
staging:
file: "./secrets.staging.yaml"
targets:
production:
server: "prod.myapp.com"
env:
- name: "DB_PASSWORD"
from:
secret: "sops:production:database.password"
staging:
server: "staging.myapp.com"
env:
- name: "DB_PASSWORD"
from:
secret: "sops:staging:database.password"
Validation
Validate your configuration and verify secrets are resolved correctly:
# Validate config (doesn't show secret values)
haloy validate-config
# Show resolved config with secrets (use with caution!)
haloy validate-config --show-resolved-config
# Validate config (doesn't show secret values)
haloy validate-config
# Show resolved config with secrets (use with caution!)
haloy validate-config --show-resolved-config
Warning: --show-resolved-config displays all secrets in plain text. Only use in secure environments.
Troubleshooting
1Password CLI Not Authenticated
# Check authentication status
op account list
# Sign in if needed
op signin
# Check authentication status
op account list
# Sign in if needed
op signin
SOPS File Issues
- Confirm the
filepath is correct relative to your Haloy config file - Set
formatexplicitly if the extension is uncommon or ambiguous - Re-run
haloy validate-config --show-resolved-configonly in a secure environment to verify resolved keys
Secret Not Found
For 1Password, verify the item exists and contains the expected field:
# Verify the item exists
op item get "Database Credentials" --vault "Production"
# List item fields
op item get "Database Credentials" --vault "Production" --fields label
# Verify the item exists
op item get "Database Credentials" --vault "Production"
# List item fields
op item get "Database Credentials" --vault "Production" --fields label
Permission Denied
Ensure your 1Password account has access to the specified vault and item.
Next Steps
Stay updated on Haloy
Get notified about new docs, deployment patterns, and Haloy updates.