feat(admin): add KMS key lifecycle endpoints and deletion reference gate (#5496)

* feat(kms): add key lifecycle operations to the backend contract

Add enable_key/disable_key/rotate_key to KmsBackend with conservative
defaults returning the typed UnsupportedCapability error, mirroring
remove_expired_key. KmsManager gains matching pass-through methods and
drops cached key metadata after every successful state mutation so the
next describe observes backend truth. The local backend overrides
enable/disable, delegating to its state-machine-gated client methods;
rotation stays rejected, matching its advertised capabilities. New
dedicated policy actions kms:EnableKey and kms:DisableKey complete the
KMS action taxonomy alongside the existing kms:RotateKey.

* feat(admin): add KMS key enable/disable/rotate endpoints

POST /v3/kms/keys/enable, /v3/kms/keys/disable and /v3/kms/keys/rotate,
following the existing /v3/kms/keys handler conventions: key_id body
with keyId query fallback, {success, message, key_id, key_metadata}
responses, and 503 JSON while the KMS service is absent. Error mapping
keeps InvalidOperation/ValidationError at 400 like the sibling handlers
and surfaces UnsupportedCapability as 501 so a backend capability gap is
never mistaken for a missing key. Existing /v3/kms/keys handlers are
untouched apart from a visibility change on a private query helper.

* feat(kms): gate scheduled key deletion on bucket encryption references

Implement the DeletionReferenceChecker seam left by the deletion worker:
before any material is destroyed, every bucket's SSE configuration is
checked for a default KMS key reference and a hit blocks the removal.
The gate fails closed - an unpublished object store, a failed bucket
listing or an unreadable per-bucket encryption config all report a
blocking reference - because destroying key material is irreversible
while a blocked removal is simply retried on the next sweep. Registered
during init_kms_system before the service can start, so every worker
spawn observes it. Storage access goes through a new kms section of the
root storage facade.
This commit is contained in:
Zhengchao An
2026-07-31 09:37:07 +08:00
committed by GitHub
parent cad8246ffb
commit a2fe5d7d88
14 changed files with 780 additions and 2 deletions
+6
View File
@@ -718,6 +718,10 @@ pub enum KmsAction {
GenerateDataKeyAction,
#[strum(serialize = "kms:DeleteKey")]
DeleteKeyAction,
#[strum(serialize = "kms:EnableKey")]
EnableKeyAction,
#[strum(serialize = "kms:DisableKey")]
DisableKeyAction,
#[strum(serialize = "kms:RotateKey")]
RotateKeyAction,
#[strum(serialize = "kms:ListKeys")]
@@ -755,6 +759,8 @@ mod tests {
("kms:ClearCache", KmsAction::ClearCacheAction),
("kms:GenerateDataKey", KmsAction::GenerateDataKeyAction),
("kms:DeleteKey", KmsAction::DeleteKeyAction),
("kms:EnableKey", KmsAction::EnableKeyAction),
("kms:DisableKey", KmsAction::DisableKeyAction),
("kms:RotateKey", KmsAction::RotateKeyAction),
("kms:ListKeys", KmsAction::ListKeysAction),
("kms:DescribeKey", KmsAction::DescribeKeyAction),