feat: add KMS action taxonomy (#3294)

This commit is contained in:
安正超
2026-06-09 13:06:15 +08:00
committed by GitHub
parent ad9bf41fc8
commit 4fec606dc4
3 changed files with 94 additions and 27 deletions
+43
View File
@@ -698,6 +698,22 @@ pub enum StsAction {
pub enum KmsAction { pub enum KmsAction {
#[strum(serialize = "kms:*")] #[strum(serialize = "kms:*")]
AllActions, AllActions,
#[strum(serialize = "kms:Configure")]
ConfigureAction,
#[strum(serialize = "kms:ServiceControl")]
ServiceControlAction,
#[strum(serialize = "kms:ClearCache")]
ClearCacheAction,
#[strum(serialize = "kms:GenerateDataKey")]
GenerateDataKeyAction,
#[strum(serialize = "kms:DeleteKey")]
DeleteKeyAction,
#[strum(serialize = "kms:RotateKey")]
RotateKeyAction,
#[strum(serialize = "kms:ListKeys")]
ListKeysAction,
#[strum(serialize = "kms:DescribeKey")]
DescribeKeyAction,
} }
#[cfg(test)] #[cfg(test)]
@@ -722,6 +738,33 @@ mod tests {
assert!(wildcard.is_match(&action)); assert!(wildcard.is_match(&action));
} }
#[test]
fn test_kms_action_taxonomy_parses_and_serializes() {
for (raw, expected) in [
("kms:Configure", KmsAction::ConfigureAction),
("kms:ServiceControl", KmsAction::ServiceControlAction),
("kms:ClearCache", KmsAction::ClearCacheAction),
("kms:GenerateDataKey", KmsAction::GenerateDataKeyAction),
("kms:DeleteKey", KmsAction::DeleteKeyAction),
("kms:RotateKey", KmsAction::RotateKeyAction),
("kms:ListKeys", KmsAction::ListKeysAction),
("kms:DescribeKey", KmsAction::DescribeKeyAction),
] {
let action = Action::try_from(raw).expect("Should parse KMS action");
assert_eq!(action, Action::KmsAction(expected));
assert_eq!(<&str>::from(&action), raw);
}
}
#[test]
fn test_kms_wildcard_matches_dedicated_actions() {
let wildcard = Action::try_from("kms:*").expect("Should parse KMS wildcard action");
let action = Action::try_from("kms:GenerateDataKey").expect("Should parse GenerateDataKey action");
assert!(matches!(wildcard, Action::KmsAction(KmsAction::AllActions)));
assert!(wildcard.is_match(&action));
}
#[test] #[test]
fn test_actionset_serialize_single_element() { fn test_actionset_serialize_single_element() {
// Single element should serialize as array for S3 specification compliance // Single element should serialize as array for S3 specification compliance
+22
View File
@@ -1729,6 +1729,28 @@ mod test {
); );
} }
#[test]
fn test_dedicated_kms_statement_without_resource_is_valid() {
let data = r#"
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["kms:GenerateDataKey"]
}
]
}
"#;
let result = Policy::parse_config(data.as_bytes());
assert!(
result.is_ok(),
"KMS-only dedicated Action statement without Resource should be valid, got: {:?}",
result.err()
);
}
#[test] #[test]
fn test_mixed_action_families_are_invalid_even_with_resource() { fn test_mixed_action_families_are_invalid_even_with_resource() {
let data = r#" let data = r#"
+29 -27
View File
@@ -5,17 +5,14 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Current Context ## Current Context
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
- Branch: `overtrue/arch-admin-route-policy` - Branch: `overtrue/arch-kms-action-taxonomy`
- Baseline: `origin/main` at `3d0e6ce0da93de0f4618beb194ae2241df71f344` - Baseline: `upstream/main` at `51c26278a4907449c565c7f1f52c1d9ae0616486`
- PR type for this branch: `contract` - PR type for this branch: `contract`
- Runtime behavior changes: none - Runtime behavior changes: none
- Rust code changes: add `rustfs/src/admin/route_policy.rs` as a pure - Rust code changes: extend `KmsAction` with the dedicated policy action
admin-route policy inventory backed by `rustfs-security-governance` route taxonomy required before handler-level KMS authorization migration.
contract types, with explicit deferred entries for routes that need
contextual, S3-action, multi-action, credential-only, or not-implemented
contract support.
- CI/script changes: none - CI/script changes: none
- Docs changes: record the S-006 route policy handoff. - Docs changes: record the S-011 KMS action taxonomy handoff.
## Phase 0 Tasks ## Phase 0 Tasks
@@ -96,51 +93,56 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
stable admin policy action, deferred inventory records routes that need stable admin policy action, deferred inventory records routes that need
richer contract support, and tests prove the combined inventory covers every richer contract support, and tests prove the combined inventory covers every
registered admin route. registered admin route.
- [x] `S-011` Add KMS action taxonomy.
- Acceptance: `KmsAction` can parse and serialize dedicated configure,
service-control, clear-cache, generate-data-key, delete, rotate, list, and
describe actions; wildcard matching still works.
- Verification: `cargo test -p rustfs-policy action --no-fail-fast`.
## Next PRs ## Next PRs
1. `contract`: add initial policy inventory tables for redaction, serde, or 1. `security-change`: migrate KMS handlers to dedicated actions with explicit
legacy compatibility where required.
2. `contract`: add initial policy inventory tables for redaction, serde, or
supply-chain governance only after the contract shape remains stable. supply-chain governance only after the contract shape remains stable.
## Pre-Push Review Log ## Pre-Push Review Log
| Expert | Status | Notes | | Expert | Status | Notes |
|---|---|---| |---|---|---|
| Quality/architecture | pass | Pure contract inventory module; no runtime route registration, alias canonicalization, or handler auth mutation. Names and deferred reasons are explicit and avoid false policy precision. | | Quality/architecture | pass | Pure policy taxonomy extension; names follow existing `KmsAction` variant style and the branch stays a single `contract` PR. |
| Migration preservation | pass | Aligns with backlog #660: directory and contract boundary first, no global-state migration, no crate split, and no storage hot-path behavior drift. | | Migration preservation | pass | No handler authorization, route policy inventory, startup, global state, crate split, or storage hot-path behavior changes. |
| Testing/verification | pass | Route-policy tests cover validation, public exceptions, table-catalog scope, deferred contextual routes, and every registered admin route. Focused checks, guard scripts, and full pre-commit pass. | | Testing/verification | pass | Baseline action tests, focused policy tests, full `rustfs-policy`, migration guard scripts, `make pre-commit`, nextest, and doctests pass. |
## Verification Notes ## Verification Notes
Passed: Passed:
- `cargo test -p rustfs admin::route_policy` - Baseline `cargo test -p rustfs-policy action --no-fail-fast`
- `cargo fmt --all`
- `cargo fmt --all --check` - `cargo fmt --all --check`
- `cargo check -p rustfs` - `cargo test -p rustfs-policy action --no-fail-fast`
- `cargo test -p rustfs-policy`
- `./scripts/check_architecture_migration_rules.sh` - `./scripts/check_architecture_migration_rules.sh`
- `./scripts/check_metrics_migration_refs.sh`
- `./scripts/check_layer_dependencies.sh` - `./scripts/check_layer_dependencies.sh`
- `./scripts/check_metrics_migration_refs.sh`
- `git diff --check` - `git diff --check`
- Rust quality scans for production `unwrap`/`expect`, narrowing casts,
string errors, boxed dynamic errors, debug printing, and relaxed atomics in
`rustfs/src/admin/route_policy.rs`
- `make pre-commit` - `make pre-commit`
Notes: Notes:
- `cargo test -p rustfs admin::route_policy` passed 7 route-policy tests. - This branch only extends KMS policy taxonomy. It does not change KMS handler
- `make pre-commit` passed all checks, including 5526 nextest tests and authorization, route policy inventory, runtime state, startup order, storage
paths, or compatibility mappings.
- `make pre-commit` passed all checks, including 5672 nextest tests and
workspace doctests. workspace doctests.
## Handoff Notes ## Handoff Notes
- Keep this S-006 branch as a pure `contract` PR. Do not change - Keep this S-011 branch as a pure `contract` PR. Do not change KMS handler
admin route registration, `/minio/admin` alias canonicalization, handler auth authorization, admin route registration, route policy inventory, Config moves,
enforcement, Config moves, Storage API moves, Runtime moves, or ECStore moves. Storage API moves, Runtime moves, or ECStore moves.
- `rustfs` may depend on `rustfs-security-governance` for contract metadata; - `rustfs` may depend on `rustfs-security-governance` for contract metadata;
the security-governance crate must stay independent from implementation the security-governance crate must stay independent from implementation
crates and runtime state. crates and runtime state.
- Do not add temporary compatibility code without a matching - Do not add temporary compatibility code without a matching
`RUSTFS_COMPAT_TODO(<task-id>)` marker and cleanup-register entry. `RUSTFS_COMPAT_TODO(<task-id>)` marker and cleanup-register entry.
- Deferred route policy entries must remain explicit until the contract crate - S-012 must decide any legacy compatibility mapping explicitly instead of
gains richer support for contextual owner checks, S3 actions, multiple silently replacing existing admin actions in this taxonomy PR.
accepted actions, credential-only gates, and not-implemented routes.