VAULT_LOCAL_MASTER_KEY (base64, 32 bytes). It does not call AWS. The master key is required. There is no fallback key.
Why
Local development and Jest need envelope encryption without a CMK. The envelope JSON matches AWS KMS so a later provider switch only re-wraps the data key.Setup
-
tooling-vault-localis a workspace dependency ofapps/backend. -
apps/backend/src/configuration/development.tscallsresolveDevelopmentVault(). That returns no vault unlessVAULT_PROVIDER=local. - Environment:
VAULT_PROVIDER=local on backend and consumer, with VAULT_KMS_CAPABILITY=encrypt on the webapp and decrypt on the consumer.
apps/backend/src/configuration/test.tsomits vault so existing suites boot. Tests that enable vault pass a config object.
Local observability
Domain logs use feature loggervault. Provider errors are VaultError codes. The local package does not log plaintext.
Adding a new provider
Add a package underapps/tools/vault/<name>/, a VaultProvider enum value, a Zod branch, and a dynamic import in the loader. Do not import that package from apps/backend except through the loader variable.
Gotchas
- Capability is checked before wrap and unwrap. An encrypt-only process fails
use()withcapability_mismatchand does not unwrap. - A blob whose encryption context does not match fails closed (
decrypt_failed). - Production smoke leaves
VAULT_PROVIDERunset and must still boot.
