From cf5043a9f96dde93a25d1629e3bde1c36b0a73d7 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 28 Jan 2026 17:36:16 -0800 Subject: [PATCH] s3tables: Normalize action names to include service prefix Add automatic normalization of operations to full IAM-style action names (e.g., 's3tables:CreateTableBucket') in CheckPermission(). This ensures policy statements using prefixed actions (s3tables:*) correctly match operations evaluated by permission helpers. Also fixes incorrect r.Context() passed to GetIdentityNameFromContext which expects *http.Request. Now passes r directly. --- weed/s3api/s3tables/handler.go | 2 +- weed/s3api/s3tables/permissions.go | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/weed/s3api/s3tables/handler.go b/weed/s3api/s3tables/handler.go index dbe664abf..d951ff837 100644 --- a/weed/s3api/s3tables/handler.go +++ b/weed/s3api/s3tables/handler.go @@ -161,7 +161,7 @@ func (h *S3TablesHandler) HandleRequest(w http.ResponseWriter, r *http.Request, // This is also used as the principal for permission checks, ensuring alignment between // the caller identity and ownership verification when IAM is enabled. func (h *S3TablesHandler) getAccountID(r *http.Request) string { - if identityName := s3_constants.GetIdentityNameFromContext(r.Context()); identityName != "" { + if identityName := s3_constants.GetIdentityNameFromContext(r); identityName != "" { return identityName } if accountID := r.Header.Get(s3_constants.AmzAccountId); accountID != "" { diff --git a/weed/s3api/s3tables/permissions.go b/weed/s3api/s3tables/permissions.go index 3bd21b403..6fbf7fdf1 100644 --- a/weed/s3api/s3tables/permissions.go +++ b/weed/s3api/s3tables/permissions.go @@ -2,6 +2,7 @@ package s3tables import ( "encoding/json" + "strings" "github.com/seaweedfs/seaweedfs/weed/s3api/policy_engine" ) @@ -39,6 +40,13 @@ func CheckPermission(operation, principal, owner, resourcePolicy string) bool { return false } + // Normalize operation to full IAM-style action name (e.g., "s3tables:CreateTableBucket") + // if not already prefixed + fullAction := operation + if !strings.Contains(operation, ":") { + fullAction = "s3tables:" + operation + } + // Parse and evaluate policy var policy PolicyDocument if err := json.Unmarshal([]byte(resourcePolicy), &policy); err != nil { @@ -55,8 +63,8 @@ func CheckPermission(operation, principal, owner, resourcePolicy string) bool { continue } - // Check if action matches - if !matchesAction(stmt.Action, operation) { + // Check if action matches (using normalized full action name) + if !matchesAction(stmt.Action, fullAction) { continue }