Expand description
§hsh-kms — pepper / KMS integration for hsh
This crate provides the Pepper trait and a small set of
pluggable backends that let an application “pepper” its passwords
with a secret key held outside the password database — typically in
AWS KMS, Google Cloud KMS, Azure Key Vault, or HashiCorp Vault.
§The pepper pattern
A pepper is a server-side secret applied to every password before it is hashed. Unlike a per-password salt (which lives next to the hash), the pepper is the same for every password and lives in a separate trust boundary — usually a KMS / HSM that the password database cannot read.
Concretely, Pepper::apply computes
HMAC-SHA-256(key_at(version), password) and returns the 32-byte
tag, which the hsh crate then feeds into Argon2id / bcrypt /
scrypt as if it were the user’s password.
§Why
- Defence in depth — an attacker who steals only the password DB cannot brute-force credentials offline because they’re missing the pepper.
- Rotatable — bump
KeyVersionperiodically; on each successful login under the old version,hsh::api::verify_and_upgradere-hashes under the new version transparently. - Compliance — PCI DSS 4.0 §3.5.1.1 effectively requires this for PAN hashing; many SOC 2 / ISO 27001 auditors expect it for password storage too.
§Backends
LocalPepper— keys held in process memory. Safe for tests, short-lived workloads, or apps without a KMS.aws::fetch_pepper(featureaws-kms) — fetch a key from AWS KMS via theaws-sdk-kmscrate, returning aLocalPeppersnapshot.gcp::fetch_pepper(featuregcp-kms) — likewise for GCP Cloud KMS.azure::fetch_pepper(featureazure-key-vault).vault::fetch_pepper(featurehashicorp-vault).
Provider implementations are currently stubs that document the intended interface; the real network calls land incrementally as they get integration-tested against the cloud providers.
§Example
use hsh_kms::{KeyVersion, LocalPepper, Pepper};
let pepper = LocalPepper::builder()
.add(KeyVersion::new(1), b"the-server-pepper-v1-DO-NOT-COMMIT".to_vec())
.current(KeyVersion::new(1))
.build()
.unwrap();
let tag = pepper.apply(KeyVersion::new(1), b"correct horse").unwrap();
assert_eq!(tag.len(), 32);Re-exports§
pub use error::PepperError;
Modules§
- error
- Structured error type for the
hsh-kmscrate.
Structs§
- KeyVersion
- A monotonically increasing key version used to identify which pepper was applied to a given password hash. Stored alongside the hash so rotation is non-destructive.
- Local
Pepper - In-memory pepper provider. Keys live in process memory — use a real KMS for production secrets.
- Local
Pepper Builder - Builder for
LocalPepper.
Traits§
- Pepper
- A pepper provider — produces an HMAC-SHA-256 tag over the password
keyed by the secret material for a given
KeyVersion.