mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-19 11:06:17 +00:00
fix(kms): fail closed on missing or corrupt key material (#5475)
This commit is contained in:
@@ -851,6 +851,13 @@ impl Operation for DeleteKmsKeyHandler {
|
||||
let status = match &e {
|
||||
KmsError::KeyNotFound { .. } => StatusCode::NOT_FOUND,
|
||||
KmsError::InvalidOperation { .. } | KmsError::ValidationError { .. } => StatusCode::BAD_REQUEST,
|
||||
// Damaged or missing key material is an integrity fault of an existing
|
||||
// key: it must surface as a server error, never as NOT_FOUND (the key
|
||||
// exists) and never as a retryable backend outage.
|
||||
KmsError::MaterialMissing { .. }
|
||||
| KmsError::MaterialCorrupt { .. }
|
||||
| KmsError::MaterialAuthenticationFailed { .. }
|
||||
| KmsError::UnsupportedFormatVersion { .. } => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
};
|
||||
let response = DeleteKmsKeyResponse {
|
||||
@@ -1265,6 +1272,13 @@ impl Operation for DescribeKmsKeyHandler {
|
||||
let status = match &e {
|
||||
KmsError::KeyNotFound { .. } => StatusCode::NOT_FOUND,
|
||||
KmsError::InvalidOperation { .. } => StatusCode::BAD_REQUEST,
|
||||
// Damaged or missing key material is an integrity fault of an existing
|
||||
// key: it must surface as a server error, never as NOT_FOUND (the key
|
||||
// exists) and never as a retryable backend outage.
|
||||
KmsError::MaterialMissing { .. }
|
||||
| KmsError::MaterialCorrupt { .. }
|
||||
| KmsError::MaterialAuthenticationFailed { .. }
|
||||
| KmsError::UnsupportedFormatVersion { .. } => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
};
|
||||
|
||||
|
||||
@@ -538,6 +538,29 @@ mod tests {
|
||||
assert_eq!(api_error.code, S3ErrorCode::InternalError);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_kms_material_faults_map_to_internal_error_not_retryable_or_not_found() {
|
||||
// Missing/corrupt key material is a persistent integrity fault of an existing key.
|
||||
// It must not be disguised as a retryable backend outage (503 invites pointless
|
||||
// retries) nor as NoSuchKey/404 (which suggests the key can be recreated —
|
||||
// recreating it would orphan every DEK wrapped by the original material).
|
||||
let material_faults = [
|
||||
rustfs_kms::KmsError::material_missing("key-a"),
|
||||
rustfs_kms::KmsError::material_corrupt("key-a", "truncated record"),
|
||||
rustfs_kms::KmsError::material_authentication_failed("key-a"),
|
||||
rustfs_kms::KmsError::unsupported_format_version("key-a", "v99"),
|
||||
];
|
||||
|
||||
for fault in material_faults {
|
||||
let description = fault.to_string();
|
||||
let api_error = ApiError::from(StorageError::other(fault));
|
||||
|
||||
assert_eq!(api_error.code, S3ErrorCode::InternalError, "wrong code for: {description}");
|
||||
assert_ne!(api_error.code, S3ErrorCode::ServiceUnavailable, "must not be retryable: {description}");
|
||||
assert_ne!(api_error.code, S3ErrorCode::NoSuchKey, "must not report key-not-found: {description}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_api_error_from_storage_error_mappings() {
|
||||
let test_cases = vec![
|
||||
|
||||
Reference in New Issue
Block a user