Skip to main content

Crate hsh_kms

Crate hsh_kms 

Source
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 KeyVersion periodically; on each successful login under the old version, hsh::api::verify_and_upgrade re-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 (feature aws-kms) — fetch a key from AWS KMS via the aws-sdk-kms crate, returning a LocalPepper snapshot.
  • gcp::fetch_pepper (feature gcp-kms) — likewise for GCP Cloud KMS.
  • azure::fetch_pepper (feature azure-key-vault).
  • vault::fetch_pepper (feature hashicorp-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-kms crate.

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.
LocalPepper
In-memory pepper provider. Keys live in process memory — use a real KMS for production secrets.
LocalPepperBuilder
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.