From 5a1b0fe9df44ebee09ab5af1609993d4143fda76 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Wed, 19 Aug 2026 22:04:25 +0800 Subject: [PATCH] docs(admin): pin two authorization semantics against a dedup rewrite (#6279) --- rustfs/src/admin/handlers/is_admin.rs | 6 ++++++ rustfs/src/admin/handlers/service_account.rs | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/rustfs/src/admin/handlers/is_admin.rs b/rustfs/src/admin/handlers/is_admin.rs index 4bbc1026a..7e29c4bff 100644 --- a/rustfs/src/admin/handlers/is_admin.rs +++ b/rustfs/src/admin/handlers/is_admin.rs @@ -46,6 +46,12 @@ impl Operation for IsAdminHandler { let access_key_to_check = input_cred.access_key.clone(); + // This endpoint reports a capability; it does not gate on one. The + // `is_allowed` result below becomes the `is_admin` field of a 200 + // response — a caller without admin rights gets `{"is_admin": false}`, + // not a 403. Turning this into a rejection would change the API + // contract, so it must stay out of any shared-gate normalisation + // (backlog#1886). // Check if the user is admin: root user check, then evaluate through the policy engine let is_admin = if let Some(sys_cred) = current_action_credentials() { constant_time_eq(&access_key_to_check, &sys_cred.access_key) diff --git a/rustfs/src/admin/handlers/service_account.rs b/rustfs/src/admin/handlers/service_account.rs index ac5075068..938ba7836 100644 --- a/rustfs/src/admin/handlers/service_account.rs +++ b/rustfs/src/admin/handlers/service_account.rs @@ -359,6 +359,13 @@ impl Operation for AddServiceAccount { return Err(s3_error!(InvalidRequest, "iam not init")); }; + // This family deliberately calls `is_allowed` directly instead of going + // through `validate_admin_request`, and must keep doing so + // (backlog#1886). The shared helper returns as soon as *any* candidate + // action is allowed — an OR. The checks here are an AND: each one must + // pass, and a later stage additionally needs `owner` for the GHSA-5354 + // parent-scope guard and drives `deny_only` dynamically. Replacing these + // with the shared gate would widen authorization. if !iam_store .is_allowed(&Args { account: &cred.access_key,