cover/Elixir.WalletIntegrations.SecretProvider.EnvSecretProvider.html

1 defmodule WalletIntegrations.SecretProvider do
2 @moduledoc """
3 Behaviour for loading provider credentials at runtime.
4
5 Implementations must never source credentials from plaintext config
6 files committed to source control (ADR 0006 / ADR 0008).
7
8 ## Implementations
9 - `WalletIntegrations.SecretProvider.EnvSecretProvider` — reads from application env.
10 Suitable for development, CI, and secrets-manager-injected env (e.g. AWS SSM, Vault sidecar).
11 """
12
13 @callback get_secret(key :: atom()) :: {:ok, String.t()} | {:error, :secret_not_found}
14
15 @doc "Resolve the configured secret provider module."
16 @spec provider() :: module()
17 def provider do
18 Application.get_env(
19 :wallet_integrations,
20 :secret_provider,
21 WalletIntegrations.SecretProvider.EnvSecretProvider
22 )
23 end
24
25 @doc "Convenience: fetch a secret via the configured provider."
26 @spec get(key :: atom()) :: {:ok, String.t()} | {:error, :secret_not_found}
27 def get(key) do
28 apply(provider(), :get_secret, [key])
29 end
30 end
31
32 defmodule WalletIntegrations.SecretProvider.EnvSecretProvider do
33 @moduledoc """
34 Application-env-backed secret provider.
35
36 In production, these values should be injected by a secrets manager
37 (e.g. AWS SSM Parameter Store, HashiCorp Vault sidecar agent) and never
38 hardcoded in config files.
39
40 Keys used:
41 - `:stripe_secret_key` — Stripe API secret key (sk_test_... or sk_live_...)
42 - `:stripe_webhook_secret` — Stripe webhook signing secret (whsec_...)
43 """
44
45 @behaviour WalletIntegrations.SecretProvider
46
47 @impl true
48 def get_secret(key) do
49 11 case Application.get_env(:wallet_integrations, key) do
50 7 nil -> {:error, :secret_not_found}
51 4 value when is_binary(value) -> {:ok, value}
52
:-(
_ -> {:error, :secret_not_found}
53 end
54 end
55 end
Line Hits Source