# KMS backend security properties RustFS ships several KMS backends. They differ not only in deployment effort but in **where master key material lives and who can read it**. Pick a backend based on the confidentiality boundary you need, not on the name alone. ## Backend comparison | Backend | Config tag | Master key material location | At-rest protection of key material | Rotation | Intended use | | --- | --- | --- | --- | --- | --- | | Local | `Local` | Files under `key_dir`, encrypted with the configured local master key | Local master key (AES-GCM) + file permissions | Rejected (no versioned retention yet) | Development; single-node setups that accept host-level trust | | Static | `Static` | Provided out-of-band via environment/file; never persisted by RustFS | Operator-managed secret distribution | Rejected (read-only backend) | Simple deployments with an external secret manager | | Vault KV2 | `VaultKV2` (legacy alias `Vault`) | Stored **directly** in Vault KV v2 (Base64-encoded plaintext) | Vault ACLs + KV v2 at-rest encryption + TLS only | Rejected (no versioned retention yet) | Deployments that accept Vault KV ACLs as the sole confidentiality boundary | | Vault Transit | `VaultTransit` | Key-encryption keys never leave Vault; only Transit ciphertext is visible outside | Vault Transit engine (cryptographic isolation) | Via Vault Transit key versioning | Deployments that need key material to be unreadable through storage APIs | ## Vault KV2: what the backend does and does not do The Vault KV2 backend uses Vault purely as a **secure storage** service: - Master key material is generated by RustFS and written to KV v2 as a Base64-encoded value (`encrypted_key_material` is an encoding, not a ciphertext). - The backend never calls the Vault Transit engine. The `mount_path` configuration field and the `RUSTFS_KMS_VAULT_MOUNT_PATH` environment variable are deprecated leftovers: they are accepted for compatibility and ignored. - Data-encryption keys (DEKs) handed to the object-encryption path are still wrapped with AES-256-GCM under the master key; the statement above concerns the master key's storage in Vault, not the DEK envelope. - The backend reports this boundary in its `backend_info` metadata as `at_rest_protection: vault-kv2-acl`. - Key rotation is rejected (`InvalidOperation`) until versioned key material retention lands; rotating by overwriting the stored key would orphan every DEK wrapped by the previous version. > **Warning: KV read access is equivalent to holding the master keys.** > Any Vault identity (token, AppRole, or policy) that can `read` the RustFS > key path in KV v2 can recover the plaintext master key material and decrypt > every object protected by those keys. Treat KV read grants on that path with > the same care as handing out the keys themselves. If this is not acceptable, > use the Vault Transit backend instead. ## Minimal Vault policy for the KV2 backend Scope the RustFS token/AppRole to exactly the KV v2 mount and key prefix it is configured with (defaults shown: mount `secret`, prefix `rustfs/kms/keys`), and grant no other identity read access to that subtree: ```hcl # RustFS KMS (Vault KV2 backend) — key storage only, no Transit access needed. path "secret/data/rustfs/kms/keys/*" { capabilities = ["create", "read", "update"] } path "secret/metadata/rustfs/kms/keys/*" { capabilities = ["list", "read", "delete"] } ``` Notes: - `delete` on the metadata path is required for permanent key deletion (`force_immediate`); drop it if you never hard-delete keys. - Do not attach `sudo`, wildcard mounts, or Transit paths to this policy; the KV2 backend does not use them. - Auditing KV reads on the key prefix is strongly recommended: every read event is a potential master-key disclosure. ## Choosing between Vault KV2 and Vault Transit Use **Vault Transit** (`VaultTransit`) when key material must be cryptographically isolated from anyone holding storage-level read access: Transit keeps key-encryption keys inside Vault and only ever returns ciphertext, and supports server-side key versioning/rotation. Use **Vault KV2** only when you accept that the Vault ACL on the key path *is* the confidentiality boundary and you want the operational simplicity of a single KV mount.