KMS.RMK.Local is the default RMK provider. It encrypts RMK-protected KMS secret material with a local file-backed key.
Use it when KMS is the only key authority and host-level controls are enough for your risk model.
Configuration
config :kms, :rmk_provider, KMS.RMK.Local
config :kms, KMS.RMK.Local,
key_path: System.fetch_env!("KMS_RMK_LOCAL_KEY_PATH")Environment:
KMS_RMK_LOCAL_KEY_PATH=/var/lib/kms/rmk.key
Development and test may auto-create the key file with 0600 permissions.
Production requires an explicit existing, non-empty key file. Production startup fails when the configured file is missing, unreadable, or empty.
When to use
Good fit:
- local development and tests;
- single-node or simple deployments;
- deployments where KMS host compromise is already considered total compromise;
- deployments where DB-only compromise is the main risk;
- operators can protect and back up one local secret file.
Poor fit:
- DB compromise cannot be tolerated without a separate key service;
- KMS host and database are managed by different trust domains;
- you need HSM-backed key custody, cloud IAM, or provider audit logs;
- you want separation between database operators and key-custody operators.
Security notes
The local RMK key file is root key material. If an attacker gets both the KMS database and this key file, RMK-protected KMS material can be decrypted.
Protect the key file with:
- strict file permissions (
0600); - host disk encryption where appropriate;
- restricted service user access;
- backups separate from database backups;
- restore drills.
Do not place the key path inside the repo, container image, or database backup volume for production.
Readiness
KMS.RMK.ensure_ready/1 reads and validates the key:
:ok = KMS.RMK.ensure_ready()Provider-specific validation:
:ok = KMS.RMK.Local.validate_key_file!()Caching
Local RMK calls are cheap. Caching still avoids repeated AES-GCM decrypt work, but the main cache concern is memory exposure.
Default:
config :kms, :rmk_cache_ttl_ms, :timer.minutes(5)Disable per call when needed:
KMS.decrypt_alias(encrypted, "alias", rmk_cache_ttl_ms: 0)