Skip to content

Feature request: support encrypted or externally-sourced credentials for client-side http_config (password_command / env expansion #8833

@pratikcsp

Description

@pratikcsp

Is your feature request related to a problem? Please describe.

Thanos components that act as HTTP clients (Ruler → Query, Sidecar → Prometheus, Ruler → Alertmanager, etc.) currently support only two ways to supply basic-auth credentials via the shared http_config schema:

  • password: <inline plaintext> — plaintext in the config file
  • password_file: <path> — plaintext file on disk

The server side already supports bcrypt-hashed credentials via basic_auth_users, which is great, but bcrypt is one-way and can't be used for outgoing requests. This leaves operators with no way to satisfy a "no plaintext secrets at rest on disk" requirement for client-side auth without either bringing in a heavyweight secret manager (Vault) or relying on full-disk encryption at the OS layer.

Concrete example from a real deployment (Thanos Ruler → Thanos Query):

# /etc/thanos/ruler-query-client.yml
- http_config:
    basic_auth:
      username: admin
      password_file: /etc/thanos/secrets/thanos_password   # ← plaintext on disk, mode 640
    tls_config:
      insecure_skip_verify: true
  static_configs:
    - mttest02:9091
  scheme: https

The file thanos_password must be plaintext for Thanos to read it. Even with strict permissions, the secret is still recoverable by anyone with disk access (stolen disk, backup tape, restored snapshot, root compromise on the box).

Describe the solution you'd like

Any one of the following would resolve this. Listed in order of preference:

  1. password_command: / bearer_token_command: — run a process and use stdout as the secret. Matches the Docker credential-helper pattern. Lets operators plug in any secret store without Thanos having to integrate with each one:

    basic_auth:
      username: admin
      password_command: "systemd-creds decrypt /etc/credstore.encrypted/thanos.cred -"

    …or vault kv get …, age -d …, aws secretsmanager get-secret-value …, etc.

  2. Environment-variable expansion for credential fields (only) — e.g. password: ${THANOS_QUERY_PASSWORD} resolved at config load. Combines cleanly with systemd LoadCredentialEncrypted=/SetCredentialEncrypted= exposing the secret as an env var to the service.

  3. Native systemd-credentials integration — automatically resolve a password_credential: <name> field against $CREDENTIALS_DIRECTORY/<name> when the env var is set. Zero config on the operator side beyond the unit file.

Option 1 is the most flexible and least invasive; option 3 is the most convenient for the growing share of users on systemd 250+ (Ubuntu 22.10+, Debian 12+, RHEL 9+).

Describe alternatives you've considered

  • LUKS-encrypted partition / loop file auto-unlocked by TPM2 (systemd-cryptenroll) holding /etc/thanos/secrets/. Works, but adds per-host operational complexity and is invisible to the application — Thanos itself still reads what it thinks is a plaintext file.
  • systemd LoadCredentialEncrypted= with password_file: /run/credentials/thanos-ruler.service/thanos_password. Clean for systemd 250+ users, but undocumented as an integration pattern, dependent on host systemd version, and feels like an accidental rather than supported approach.
  • HashiCorp Vault + Vault Agent template rendering the password file. Heavier-weight, adds a daemon and Vault infra, overkill for small on-prem deployments.
  • Living with password_file: + chmod 640. The status quo, and what most production setups quietly do.

Additional context

  • The http_config schema in Thanos appears to come from prometheus/common/config. If the right home for this change is upstream in prometheus/common, happy to file there and link back. Raising it here first because the user-visible surface is Thanos's per-component YAML files (http-config.yml, ruler-query-client.yml, alertmanager-client.yml, the http client files for sidecar and store, etc.).
  • Versions in use: Thanos v0.41.0, Prometheus v2.51.0, Alertmanager v0.27.0, on Ubuntu 22.04 LTS (systemd 249.11, so LoadCredentialEncrypted= is not available — only systemd 250+ has it).
  • Happy to contribute a PR for password_command: if there's directional agreement on the approach.

Environment

  • Thanos version: v0.41.0
  • Prometheus version: v2.51.0
  • OS: Ubuntu 22.04 LTS (Jammy), systemd 249.11
  • Object storage: none (sidecar-only setup, no bucket)
  • Deployment: bare-metal/VM, systemd units (not Kubernetes)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions