feat(kms): add backup manifest and responsibility contract types (#5483)

Contract-only module for KMS backup/restore (no handler or backend
wiring): versioned manifest schema with completeness marker and sealed
digest, the (backend, at-rest protection) responsibility matrix, typed
fail-closed errors, and the zero-write restore dry-run report. Fields
whose shape depends on in-flight contracts are reserved and reject data
in format version 1.
This commit is contained in:
Zhengchao An
2026-07-31 01:49:21 +08:00
committed by GitHub
parent 7051a5ce41
commit b457c6abcc
8 changed files with 1890 additions and 6 deletions
+11 -6
View File
@@ -69,11 +69,14 @@ fn validate_key_id(key_id: &str) -> Result<()> {
}
const LOCAL_KMS_MASTER_KEY_SALT_FILE: &str = ".master-key.salt";
const LOCAL_KMS_MASTER_KEY_SALT_LEN: usize = 16;
const LOCAL_KMS_MASTER_KEY_LEN: usize = 32;
const LOCAL_KMS_ARGON2_M_COST_KIB: u32 = 19 * 1024;
const LOCAL_KMS_ARGON2_T_COST: u32 = 2;
const LOCAL_KMS_ARGON2_P_COST: u32 = 1;
// The KDF parameters are pub(crate) so the backup manifest contract
// (`crate::backup`) records the exact compiled-in derivation instead of a
// copy that could drift.
pub(crate) const LOCAL_KMS_MASTER_KEY_SALT_LEN: usize = 16;
pub(crate) const LOCAL_KMS_MASTER_KEY_LEN: usize = 32;
pub(crate) const LOCAL_KMS_ARGON2_M_COST_KIB: u32 = 19 * 1024;
pub(crate) const LOCAL_KMS_ARGON2_T_COST: u32 = 2;
pub(crate) const LOCAL_KMS_ARGON2_P_COST: u32 = 1;
/// Strict matcher for leftover commit temp files (`<prefix>.tmp-<uuid>`).
///
@@ -396,9 +399,11 @@ pub struct LocalKmsClient {
key_write_locks: Mutex<HashMap<String, Arc<tokio::sync::Mutex<()>>>>,
}
// pub(crate) so the backup contract tests can anchor the manifest's
// protection-state wire names against the marker values written to disk.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
enum StoredKeyProtection {
pub(crate) enum StoredKeyProtection {
#[default]
LegacyUnspecified,
EncryptedMasterKey,