Skip to content

secret_store: HashiCorp Vault KV2 backend (covers OVHcloud Secret Manager, Vault, OpenBao) #170

Description

@fheikens

Summary

Add a HashiCorp Vault KV2 backend to the secret_store credential provider. Because KV2 is a de-facto standard wire protocol, one backend covers three targets at once:

  • OVHcloud Secret Manager — GA (2026), exposes a HashiCorp Vault KV2-compatible API; relevant to growing European adoption.
  • HashiCorp Vault — the KV2 secrets engine itself (widely used in EU on-prem / regulated environments).
  • OpenBao — the open-source Vault fork (same KV2 API).

Inherits decisions from the credential-provider epic #92; extends the secret_store provider (#97), sibling to the AWS Parameter Store backend (#157). Frame this as "KV2 protocol backend", not "OVH support" — OVH is one consumer of the same interface.

Do we support it today? No. Current secret_store backends: AWS Secrets Manager, AWS Systems Manager Parameter Store, Azure Key Vault, GCP Secret Manager.

Cross-cutting decision for the epic/keystone (#92 / #93) — read first

This backend departs from a core epic principle and that decision must be made at the umbrella, not silently here:

Open design decisions (resolve in the spec, before code)

  1. Reference disambiguation. A KV2 secret is an HTTPS URL like https://vault.example.com/v1/<mount>/data/<path>, which structurally overlaps the Azure Key Vault form (https://<vault>.vault.azure.net/secrets/<name>). Backend routing currently infers from secret_ref shape, so KV2 needs a clean discriminator — candidates: a vault+kv2:// scheme, or requiring the /v1/.../data/ path marker. (Note: internal/config/secretref_test.go already rejects a bare vault:// scheme — the namespace was anticipated.)
  2. Auth method + where its credential lives. Decide which Vault auth methods to support first (token via VAULT_TOKEN / token file? AppRole? Kubernetes auth?) and how that credential is supplied without putting a long-lived secret in signals.yaml (env/file/mounted, parallel to how the DB password is kept out of config today).
  3. KV2 payload mapping. KV2 returns a versioned JSON object of key/value pairs under data.data. Map onto the existing secret_json_key extraction; decide version selection (latest vs pinned) and how it interacts with the cache/TTL model (KV2 has lease/version semantics).
  4. Transport / topology. Vault CA trust, Vault namespace (Enterprise / HCP), and OVHcloud-specific endpoint/region details.

Scope (STDD — spec first)

  1. Spec: a KV2 sub-spec (or an extension of credential-provider-secret-store.md) covering the ref form, the new auth model + its invariants/failure modes, payload mapping, and NFRs — plus the keystone note on the stored-auth-credential trade-off.
  2. Acceptance cases (normal / boundary / invalid / failure), each referencing a spec ID.
  3. Failing tests with an injected fake KV2 client (no live network, per NFR003).
  4. Implementation: SecretBackendHashiCorpVaultKV2 enum, ref parsing/disambiguation, a hashicorpVaultKV2Fetcher implementing secretFetcher, the Vault auth wiring, config + validation, failure taxonomy, guidance text.
  5. Live smoke (env-gated) against a real Vault/OpenBao and against OVHcloud Secret Manager's KV2 endpoint.
  6. Docs: a per-target recipe in docs/database-connections.md (Vault / OpenBao / OVHcloud), with auth setup and least-privilege policy.

Acceptance criteria

  • A secret_store target with a KV2 reference fetches the DB password from Vault/OpenBao/OVHcloud and connects, with no DB password in config.
  • The KV2 reference is routed unambiguously (no collision with the Azure Key Vault form).
  • The Vault auth credential is supplied out-of-config (env/file/mounted), never inline in signals.yaml.
  • secret_json_key extraction works against the KV2 data.data object.
  • Secret values are never logged/persisted; only metadata.
  • Unit tests pass with a fake KV2 client; live smoke passes against Vault/OpenBao and OVHcloud.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:collectorArq Signals collectors and pipelinearea:securitySecurity hardening, AppSec, compliance controlseffort:LLarge effort (24-80 hours)enhancementNew feature or requestpriority:P2Nice-to-have / can be deferred

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions