Skip to content

[SPIKE]: Explore design space for Vault support #144

Description

@araujof

Summary

Spike to determine how CPEX should integrate with HashiCorp Vault as a SecretProvider backend (see #139), and to decide on a concrete design for the Vault plugin before implementation begins.

Motivation

Vault's official client SDKs are proprietary/BUSL-licensed, which conflicts with deny.toml's strictly permissive allow list (Apache-2.0, MIT, BSD, MPL, ISC, …). Pulling a non-compliant SDK into the dependency graph would create licensing obligations for deployments that don't even use Vault, even if the feature is opt-in.

Vault exposes its own HTTP interface — HashiCorp describes it as "REST like," not a formal REST/JSON:API standard. It's JSON over HTTP with a consistent /v1/-prefixed path scheme and a documented error envelope ({"errors": [...]}), but no fixed success envelope — response shape varies per endpoint. Auth tokens are sent via X-Vault-Token or Authorization: Bearer <token>. Notably, Vault does not promise backward compatibility even on the v1 prefix, which is a real constraint on plugin design, not just a documentation footnote.

If this HTTP interface covers what we need, we can implement the plugin against it directly with a permissively-licensed HTTP client (e.g. reqwest), avoiding the SDK entirely. Vault also publishes a generated OpenAPI document (per-path via ?help=1, or the full spec via /v1/sys/internal/specs/openapi) — worth evaluating as a source for a generated client instead of hand-writing one.

Questions to Answer

  1. Does Vault's HTTP interface cover what we need?

    • Secret read (KV v1/v2), authentication (token, AppRole, or other methods relevant to CPEX deployments), and renewal/lease handling.
    • Any gaps that would force us back toward an SDK?
  2. How do we manage the no-backward-compatibility risk?

    • Vault reserves the right to change v1 endpoints without notice. Do we pin against a specific Vault version range, hand-write a minimal client against only the endpoints we use, or lean on the OpenAPI spec to detect drift?
  3. Is codegen from Vault's OpenAPI spec worth it?

    • Could reduce hand-maintained HTTP glue, but adds a codegen step and a dependency on the spec's stability/quality. Worth prototyping against KV + one auth method before deciding.
  4. What does the plugin design look like?

    • How does VaultProvider implement the SecretProvider trait from [FEATURE]: Secret management plugin (Vault / Infisical) #139 using only HTTP calls?
    • Auth method(s) to support initially (token vs. AppRole vs. Kubernetes auth, etc.) and how credentials/tokens are supplied and refreshed.
    • Caching/TTL behavior — how do we respect Vault lease durations when refreshing cached secrets?
    • Error handling/retry behavior for transient Vault unavailability, using Vault's {"errors": [...]} envelope.
    • Cargo feature gating so the HTTP client and Vault-specific code stay out of the default build (mirroring valkey's full-only opt-in).
  5. License check

    • Confirm the HTTP client and any supporting crates are on the deny.toml allow list; flag anything that needs a new entry.

Deliverable

A short design writeup (in this issue or a linked doc) covering the API surface used, versioning/compatibility approach, auth flow, caching strategy, and feature-flag structure — enough to hand off to implementation without further discovery. Feeds back into #139's SecretProvider/VaultProvider scope.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

Projects

Status
Backlog

Relationships

None yet

Development

No branches or pull requests

Issue actions