diff options
| author | Chris Lu <chrislusf@users.noreply.github.com> | 2025-11-12 22:14:50 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-12 22:14:50 -0800 |
| commit | 508d06d9a5c763668ba149a8f1182e8552505c2b (patch) | |
| tree | a34d21d801d2b71dc3c6968cbb4ff8568e0fa8da /weed/s3api/s3api_bucket_config.go | |
| parent | 50f067bcfd99ecf1821ba2d34fc2f109e90428bb (diff) | |
| download | seaweedfs-508d06d9a5c763668ba149a8f1182e8552505c2b.tar.xz seaweedfs-508d06d9a5c763668ba149a8f1182e8552505c2b.zip | |
S3: Enforce bucket policy (#7471)
* evaluate policies during authorization
* cache bucket policy
* refactor
* matching with regex special characters
* Case Sensitivity, pattern cache, Dead Code Removal
* Fixed Typo, Restored []string Case, Added Cache Size Limit
* hook up with policy engine
* remove old implementation
* action mapping
* validate
* if not specified, fall through to IAM checks
* fmt
* Fail-close on policy evaluation errors
* Explicit `Allow` bypasses IAM checks
* fix error message
* arn:seaweed => arn:aws
* remove legacy support
* fix tests
* Clean up bucket policy after this test
* fix for tests
* address comments
* security fixes
* fix tests
* temp comment out
Diffstat (limited to 'weed/s3api/s3api_bucket_config.go')
| -rw-r--r-- | weed/s3api/s3api_bucket_config.go | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/weed/s3api/s3api_bucket_config.go b/weed/s3api/s3api_bucket_config.go index 128b17c06..c71069d08 100644 --- a/weed/s3api/s3api_bucket_config.go +++ b/weed/s3api/s3api_bucket_config.go @@ -14,6 +14,7 @@ import ( "google.golang.org/protobuf/proto" "github.com/seaweedfs/seaweedfs/weed/glog" + "github.com/seaweedfs/seaweedfs/weed/iam/policy" "github.com/seaweedfs/seaweedfs/weed/kms" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" "github.com/seaweedfs/seaweedfs/weed/pb/s3_pb" @@ -32,6 +33,7 @@ type BucketConfig struct { IsPublicRead bool // Cached flag to avoid JSON parsing on every request CORS *cors.CORSConfiguration ObjectLockConfig *ObjectLockConfiguration // Cached parsed Object Lock configuration + BucketPolicy *policy.PolicyDocument // Cached bucket policy for performance KMSKeyCache *BucketKMSCache // Per-bucket KMS key cache for SSE-KMS operations LastModified time.Time Entry *filer_pb.Entry @@ -318,6 +320,28 @@ func (bcc *BucketConfigCache) RemoveNegativeCache(bucket string) { delete(bcc.negativeCache, bucket) } +// loadBucketPolicyFromExtended loads and parses bucket policy from entry extended attributes +func loadBucketPolicyFromExtended(entry *filer_pb.Entry, bucket string) *policy.PolicyDocument { + if entry.Extended == nil { + return nil + } + + policyJSON, exists := entry.Extended[BUCKET_POLICY_METADATA_KEY] + if !exists || len(policyJSON) == 0 { + glog.V(4).Infof("loadBucketPolicyFromExtended: no bucket policy found for bucket %s", bucket) + return nil + } + + var policyDoc policy.PolicyDocument + if err := json.Unmarshal(policyJSON, &policyDoc); err != nil { + glog.Errorf("loadBucketPolicyFromExtended: failed to parse bucket policy for %s: %v", bucket, err) + return nil + } + + glog.V(3).Infof("loadBucketPolicyFromExtended: loaded bucket policy for bucket %s", bucket) + return &policyDoc +} + // getBucketConfig retrieves bucket configuration with caching func (s3a *S3ApiServer) getBucketConfig(bucket string) (*BucketConfig, s3err.ErrorCode) { // Check negative cache first @@ -376,8 +400,14 @@ func (s3a *S3ApiServer) getBucketConfig(bucket string) (*BucketConfig, s3err.Err } else { glog.V(3).Infof("getBucketConfig: no Object Lock config found in extended attributes for bucket %s", bucket) } + + // Load bucket policy if present (for performance optimization) + config.BucketPolicy = loadBucketPolicyFromExtended(entry, bucket) } + // Sync bucket policy to the policy engine for evaluation + s3a.syncBucketPolicyToEngine(bucket, config.BucketPolicy) + // Load CORS configuration from bucket directory content if corsConfig, err := s3a.loadCORSFromBucketContent(bucket); err != nil { if errors.Is(err, filer_pb.ErrNotFound) { |
