Python Secrets Loader from Vault and Cloud Secret Managers Prompt
Build a Python secrets loader that fetches credentials from HashiCorp Vault or a cloud secret manager (AWS/GCP/Azure) with caching, a pluggable backend, and zero secrets on disk or in logs.
- Target user
- Engineers wiring applications to a centralized secret store
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior security-minded engineer who wires apps to secret stores without ever printing, logging, or persisting a secret. I will provide: - The secret store (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault) - How the app authenticates to it (Vault token/AppRole/Kubernetes auth, cloud IAM role/workload identity) - Which secrets are needed and their refresh/rotation needs Build a secrets loader that: 1. **Uses a pluggable backend interface** — a `SecretBackend` abstraction with `get_secret(name) -> str | dict`. Concrete backends for Vault and the cloud manager I named. The app code depends only on the interface, so backends are swappable (including a local/dev backend reading env for testing). 2. **Authenticates via the platform identity** — prefer IAM role / workload identity / Vault Kubernetes auth over long-lived static tokens. Never hardcode credentials to reach the secret store. 3. **Caches with a TTL** — in-memory only, with a configurable TTL to limit API calls and cost, and to pick up rotated secrets within bounds. Never write the cache to disk. 4. **Handles rotation** — support fetching the current version and re-fetching on auth/permission errors; document how rotation flows through (cache invalidation). 5. **Fails safe and clear** — distinguish "secret missing" from "not authorized" from "store unreachable" with actionable errors. Never fall back to a default/empty secret silently. 6. **Never leaks** — secrets are never logged, never in exceptions/tracebacks (wrap and scrub), never in `__repr__`. Provide a `SecretStr`-like wrapper that masks on print. Avoid putting secrets in env if the process tree is observable. 7. **Is testable** — inject the backend client; provide tests with a fake backend and assertions that secrets don't appear in logs/repr. Output: (a) the backend interface + the two concrete backends, (b) the cached loader with TTL, (c) the masking `SecretStr`, (d) auth setup notes per platform, (e) `pytest` tests including a "no secret in logs" check. Bias toward: platform identity over static creds, in-memory-only caching, fail-closed behavior, and aggressive redaction everywhere.