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>: The provider name, currently onepassword or sops
  • <source>: The source key defined under secret_providers.<provider>
  • <key>: The field or nested key to resolve from that source

Examples:

  • onepassword:production-db:password
  • sops:development:client.id
  • sops: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

How Haloy Maps to 1Password

A 1Password secret reference has two parts: the reusable source you define under secret_providers.onepassword, and the field key you reference from from.secret.

Haloy setting1Password meaningWhere to find or set it
accountThe 1Password account to use. This is optional unless you have multiple 1Password accounts configured.In the 1Password app, select the account or collection at the top of the sidebar. In the CLI, run op account list and use the URL or USER ID value.
vaultThe vault that contains the item. Vaults organize items and control who can access them. The value can be the vault name or vault UUID. Vault names with spaces are supported when quoted in YAML, for example "Production Secrets".In the 1Password app sidebar, choose an existing vault or create one with the plus button next to the account name. In the CLI, run op vault list --account "<account>" --format json to find the vault name and UUID.
itemThe title of the 1Password item that stores the secret fields.Open the vault, create or select an item such as Database Credentials, API Tokens, or Build Secrets, then use that item title in haloy.yaml.
Secret keyThe field label inside the item. This is the third segment of from.secret, for example password in onepassword:production-db:password.Edit the item in 1Password and add or rename fields so their labels match the keys you reference. Field labels are case-sensitive and should be unique within the item.

For example, this reference:

onepassword:production-db:password

means:

  • Use the production-db source under secret_providers.onepassword
  • Read the 1Password item configured by that source
  • Return the item field whose label is password

Set Up a 1Password Item

  1. Open and unlock the 1Password app.
  2. Choose the account you want to use from the top of the sidebar if you have more than one account.
  3. Choose or create a vault for deployment secrets, for example Production Secrets.
  4. Create an item in that vault, for example Database Credentials. A Login, Password, API Credential, Secure Note, or other item type can work as long as it has fields with labels Haloy can read.
  5. Add fields for each value Haloy needs, such as username, password, stripe-key, or sendgrid-key.
  6. Save the item, then use the vault name or UUID, item title, and field labels in haloy.yaml.

You can verify what the 1Password CLI can see before deploying:

op account list op vault list --account "my.1password.com" --format json op item get "Database Credentials" --vault "Production Secrets" --account "my.1password.com" --format json op item get "Database Credentials" --vault "Production Secrets" --account "my.1password.com" --fields label=username,label=password

If you only have one 1Password account, or you already set OP_ACCOUNT, you can omit account in haloy.yaml and leave off the --account flag in manual CLI checks.

Configuration

name: "my-app" secret_providers: onepassword: production-db: account: "my.1password.com" vault: "Production Secrets" 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. For the configuration above:

  • The Database Credentials item in the Production Secrets vault needs username and password fields
  • The Third-party APIs item in the API Services vault needs stripe-key and sendgrid-key fields

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"

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 format is 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 format is 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"

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"

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"

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"

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

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

SOPS File Issues

  • Confirm the file path is correct relative to your Haloy config file
  • Set format explicitly if the extension is uncommon or ambiguous
  • Re-run haloy validate-config --show-resolved-config only 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

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.