Files
upstream-seaweedfs/weed/s3api/policy_engine/README_POLICY_ENGINE.md
upstream-mirror 89f5be005d
Some checks failed
go: build dev binaries / cleanup (push) Successful in 4s
Codespell / Check for spelling errors (push) Failing after 3s
docker: build dev containers / build-rust-binaries (amd64, x86_64-unknown-linux-musl) (push) Failing after 3s
docker: build dev containers / build-dev-containers (push) Has been skipped
docker: build dev containers / build-rust-binaries (arm64, true, aarch64-unknown-linux-musl) (push) Failing after 3s
End to End / FUSE Mount (push) Failing after 2s
EC Integration Tests / EC Integration Tests (push) Failing after 30s
FUSE DLM Integration Tests / FUSE DLM Integration Tests (push) Failing after 3s
FUSE Volume Server Failover Tests / FUSE Volume Server Failover (push) Failing after 3s
FUSE Integration Tests / FUSE Integration Testing (push) Failing after 2s
FUSE P2P Peer Chunk Sharing Integration Tests / FUSE P2P Peer Chunk Sharing (push) Failing after 3s
go: build binary / Go Vet (push) Failing after 2s
go: build binary / Go Vet 32-bit (push) Failing after 3s
go: build binary / Build (push) Failing after 4s
go: build binary / Build cross-platform (freebsd/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (darwin/arm64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/arm64) (push) Failing after 3s
go: build binary / Test (push) Failing after 2s
go: build binary / Test 32-bit (push) Failing after 3s
helm: lint and test charts / lint-test (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (11) (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (17) (push) Failing after 3s
go: build dev binaries / build_dev_linux_windows (amd64, linux) (push) Failing after 2s
go: build dev binaries / build_dev_linux_windows (amd64, windows) (push) Failing after 3s
go: build dev binaries / build_dev_darwin (amd64, darwin) (push) Has been skipped
go: build dev binaries / build_dev_darwin (arm64, darwin) (push) Has been skipped
Java Client Unit Tests / Java Unit Tests (11) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (17) (push) Failing after 2s
Java Client Unit Tests / Java Unit Tests (21) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (8) (push) Failing after 3s
Kafka Quick Test (Load Test with Schema Registry) / Kafka Client Load Test (Quick) (push) Failing after 3s
Kafka Gateway Tests / Kafka Unit Tests (unit-tests-1) (push) Failing after 11s
Kafka Gateway Tests / Kafka Integration Tests (Critical) (integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka End-to-End Tests (with SMQ) (e2e-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Consumer Group Tests (Highly Isolated) (consumer-group-1) (push) Failing after 2s
Kafka Gateway Tests / Kafka Client Compatibility (with SMQ) (client-compat-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka SMQ Integration Tests (Full Stack) (smq-integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Protocol Tests (Isolated) (protocol-1) (push) Failing after 3s
KMS Tests / KMS Provider Integration Tests (push) Failing after 2s
KMS Tests / S3 KMS End-to-End Tests (push) Failing after 3s
Master Cold Start Tests / Master Cold Start Tests (push) Failing after 4s
Metadata Subscribe Integration Tests / Metadata Subscribe Integration Tests (push) Failing after 3s
Multi-Master Tests / Multi-Master Failover Tests (push) Failing after 3s
Performance / CPU and Heap Profile (push) Failing after 2s
Performance / S3 Read/Write Benchmark (rust volume) (push) Failing after 3s
pjdfstest POSIX Compliance / pjdfstest (push) Failing after 2s
Plugin Worker Integration Tests / Plugin Worker: erasure_coding (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: vacuum (push) Failing after 3s
Rust Volume Server Tests / Rust Integration Tests (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 1) (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 1) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 3) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Distributed Tests (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Performance Tests (push) Failing after 3s
Performance / Throughput Benchmark (go volume) (push) Failing after 3s
Performance / Throughput Benchmark (rust volume) (push) Failing after 2s
Performance / S3 Read/Write Benchmark (go volume) (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: volume_balance (push) Failing after 3s
PostgreSQL Gateway Tests / PostgreSQL Basic Tests (push) Failing after 3s
Rust Volume Server Tests / Rust Unit Tests (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 3) (push) Failing after 3s
Rust Plugin Worker Tests / Rust Plugin Worker Build and Unit Tests (push) Failing after 3s
rust: build dev volume server binaries / cleanup (push) Successful in 3s
S3 ETag and ACL Tests / S3 ETag + ACL Integration Tests (push) Failing after 3s
S3 IAM Integration Tests / IAM Unit Tests (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (advanced) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (basic) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (group) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (policy-enforcement) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (sts) (push) Failing after 4s
S3 Keycloak Integration Tests / S3 Keycloak Integration Tests (push) Failing after 3s
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.11) (push) Failing after 3s
S3 PyArrow Parquet Tests / Go Unit Tests (Implicit Directory) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.12) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-amd64, x86_64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-arm64, aarch64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-linux (linux-amd64, x86_64-unknown-linux-gnu) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.9) (push) Has been cancelled
S3 Proxy Signature Tests / S3 Proxy Signature Verification Tests (push) Has been cancelled
S3 SDK V2 Route Disambiguation Tests / S3 SDK V2 Routing Tests (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (quick) (push) Has been cancelled
S3 SSE Tests / S3 SSE Compatibility Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Metadata Persistence Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Copy Operations Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Multipart Upload Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Performance Test (push) Has been cancelled
S3 SSE Tests / S3 Volume Encryption Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (comprehensive) (push) Has been cancelled
Spark Integration Tests / Spark Integration Tests (push) Failing after 2s
Telemetry Integration Tests / telemetry-integration-test (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 1) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 1) (push) Failing after 3s
Ceph S3 tests / Basic S3 tests (KV store) (push) Has been cancelled
Ceph S3 tests / S3 Versioning & Object Lock tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Unit Tests (push) Failing after 3s
Ceph S3 tests / S3 CORS tests (push) Has been cancelled
Ceph S3 tests / SeaweedFS Custom S3 Copy tests (push) Has been cancelled
Ceph S3 tests / Basic S3 tests (SQL store) (push) Has been cancelled
test s3 over https using aws-cli / awscli-tests (push) Has been cancelled
TLS Rotation Integration Tests / TLS Rotation Integration Tests (push) Has been cancelled
Vacuum Integration Tests / Vacuum Integration Tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Variables Integration Tests (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (advanced-policy) (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (basic-policy) (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (contextual-policy) (push) Failing after 4s
S3 Policy Integration Tests / Trusted Proxy Detection Tests (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Shell Integration Tests (push) Failing after 3s
Samba on FUSE Integration / samba-integration (push) Failing after 2s
SFTP Integration Tests / SFTP Integration Testing (push) Failing after 3s
terraform: validate and test modules / fmt, validate, plan-level tests (push) Failing after 3s
terraform: validate and test modules / local cluster smoke test (real weed) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 3) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 2) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 2) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 3) (push) Failing after 5s
mount: windows conformance / WinFsp conformance (push) Has been cancelled
mount: windows / Mount on Windows (push) Has been cancelled
snapshot of https://github.com/seaweedfs/seaweedfs.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 03:23:42 +05:00

10 KiB

SeaweedFS Policy Evaluation Engine

This document describes the comprehensive policy evaluation engine that has been added to SeaweedFS, providing AWS S3-compatible policy support while maintaining full backward compatibility with existing identities.json configuration.

Overview

The policy engine provides:

  • Full AWS S3 policy compatibility - JSON policies with conditions, wildcards, and complex logic
  • Backward compatibility - Existing identities.json continues to work unchanged
  • Bucket policies - Per-bucket access control policies
  • IAM policies - User and group-level policies
  • Condition evaluation - IP restrictions, time-based access, SSL-only, etc.
  • AWS-compliant evaluation order - Explicit Deny > Explicit Allow > Default Deny

Architecture

Files Created

  1. policy_engine/types.go - Core policy data structures and validation
  2. policy_engine/conditions.go - Condition evaluators (StringEquals, IpAddress, etc.)
  3. policy_engine/engine.go - Main policy evaluation engine
  4. policy_engine/integration.go - Integration with existing IAM system
  5. policy_engine/engine_test.go - Comprehensive tests
  6. policy_engine/examples.go - Usage examples and documentation (excluded from builds)
  7. policy_engine/wildcard_matcher.go - Optimized wildcard pattern matching
  8. policy_engine/wildcard_matcher_test.go - Wildcard matching tests

Key Components

PolicyEngine
├── Bucket Policies (per-bucket JSON policies)
├── User Policies (converted from identities.json + new IAM policies)
├── Condition Evaluators (IP, time, string, numeric, etc.)
└── Evaluation Logic (AWS-compliant precedence)

Backward Compatibility

Existing identities.json (No Changes Required)

Your existing configuration continues to work exactly as before:

{
  "identities": [
    {
      "name": "readonly_user",
      "credentials": [{"accessKey": "key123", "secretKey": "secret123"}],
      "actions": ["Read:public-bucket/*", "List:public-bucket"]
    }
  ]
}

Legacy actions are automatically converted to AWS-style policies:

  • Read:bucket/* → s3:GetObject on arn:aws:s3:::bucket/*
  • Write:bucket → s3:PutObject, s3:DeleteObject on arn:aws:s3:::bucket/*
  • Admin → s3:* on arn:aws:s3:::*

New Capabilities

1. Bucket Policies

Set bucket-level policies using standard S3 API:

# Set bucket policy
curl -X PUT "http://localhost:8333/bucket?policy" \
     -H "Authorization: AWS access_key:signature" \
     -d '{
       "Version": "2012-10-17",
       "Statement": [
         {
           "Effect": "Allow",
           "Principal": "*",
           "Action": "s3:GetObject",
           "Resource": "arn:aws:s3:::bucket/*"
         }
       ]
     }'

# Get bucket policy
curl "http://localhost:8333/bucket?policy"

# Delete bucket policy
curl -X DELETE "http://localhost:8333/bucket?policy"

2. Advanced Conditions

Support for all AWS condition operators:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::secure-bucket/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": ["192.168.1.0/24", "10.0.0.0/8"]
        },
        "Bool": {
          "aws:SecureTransport": "true"
        },
        "DateGreaterThan": {
          "aws:CurrentTime": "2023-01-01T00:00:00Z"
        }
      }
    }
  ]
}

3. Supported Condition Operators

  • String: StringEquals, StringNotEquals, StringLike, StringNotLike
  • Numeric: NumericEquals, NumericLessThan, NumericGreaterThan, etc.
  • Date: DateEquals, DateLessThan, DateGreaterThan, etc.
  • IP: IpAddress, NotIpAddress (supports CIDR notation)
  • Boolean: Bool
  • ARN: ArnEquals, ArnLike
  • Null: Null

4. Condition Keys

Standard AWS condition keys are supported:

  • aws:CurrentTime - Current request time
  • aws:SourceIp - Client IP address
  • aws:SecureTransport - Whether HTTPS is used
  • aws:UserAgent - Client user agent
  • s3:x-amz-acl - Requested ACL
  • s3:VersionId - Object version ID
  • s3:ExistingObjectTag/<tag-key> - Value of an existing object tag (see example below)
  • And many more...

5. Object Tag-Based Access Control

You can control access based on object tags using s3:ExistingObjectTag/<tag-key>:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*",
      "Condition": {
        "StringEquals": {
          "s3:ExistingObjectTag/status": ["public"]
        }
      }
    }
  ]
}

This allows anonymous access only to objects that have a tag status=public.

Deny access to confidential objects:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*"
    },
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*",
      "Condition": {
        "StringEquals": {
          "s3:ExistingObjectTag/classification": ["confidential", "secret"]
        }
      }
    }
  ]
}

Supported Operations for Tag-Based Conditions:

Tag-based conditions (s3:ExistingObjectTag/<key>) are evaluated for the following operations:

  • s3:GetObject (GET object)
  • s3:GetObjectVersion (GET object with versionId)
  • s3:HeadObject (HEAD object)

Note: For these conditions to be evaluated, the object must exist and the policy engine re-checks access after fetching the object metadata.

Policy Evaluation

Evaluation Order (AWS-Compatible)

  1. Explicit Deny - If any policy explicitly denies access → DENY
  2. Explicit Allow - If any policy explicitly allows access → ALLOW
  3. Default Deny - If no policy matches → DENY

Policy Sources (Evaluated Together)

  1. Bucket Policies - Stored per-bucket, highest priority
  2. User Policies - Converted from identities.json + new IAM policies
  3. Legacy IAM - For backward compatibility (lowest priority)

Examples

Public Read Bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicRead",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::public-bucket/*"
    }
  ]
}

IP-Restricted Bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::secure-bucket/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "192.168.1.0/24"
        }
      }
    }
  ]
}

SSL-Only Access

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": ["arn:aws:s3:::ssl-bucket/*", "arn:aws:s3:::ssl-bucket"],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

Integration

For Existing SeaweedFS Users

  1. No changes required - Your existing setup continues to work
  2. Optional enhancement - Add bucket policies for fine-grained control
  3. Gradual migration - Move to full AWS policies over time

For New Users

  1. Start with either identities.json or AWS-style policies
  2. Use bucket policies for complex access patterns
  3. Full feature parity with AWS S3 policies

Testing

Run the policy engine tests:

# Core policy tests
go test -v -run TestPolicyEngine

# Condition evaluator tests  
go test -v -run TestConditionEvaluators

# Legacy compatibility tests
go test -v -run TestConvertIdentityToPolicy

# Validation tests
go test -v -run TestPolicyValidation

Performance

  • Compiled patterns - Regex patterns are pre-compiled for fast matching
  • Cached policies - Policies are cached in memory with TTL
  • Early termination - Evaluation stops on first explicit deny
  • Minimal overhead - Backward compatibility with minimal performance impact

Migration Path

Phase 1: Backward Compatible (Current)

  • Keep existing identities.json unchanged
  • Add bucket policies as needed
  • Legacy actions automatically converted to AWS policies

Phase 2: Enhanced (Optional)

  • Add advanced conditions to policies
  • Use full AWS S3 policy features
  • Maintain backward compatibility

Phase 3: Full Migration (Future)

  • Migrate to pure IAM policies
  • Use AWS CLI/SDK for policy management
  • Complete AWS S3 feature parity

Compatibility

  • Full backward compatibility with existing identities.json
  • AWS S3 API compatibility for bucket policies
  • Standard condition operators and keys
  • Proper evaluation precedence (Deny > Allow > Default Deny)
  • Performance optimized with caching and compiled patterns

The policy engine provides a seamless upgrade path from SeaweedFS's existing simple IAM system to full AWS S3-compatible policies, giving you the best of both worlds: simplicity for basic use cases and power for complex enterprise scenarios.

Feature Status

Implemented

Feature Description
Bucket Policies Full AWS S3-compatible bucket policies
Condition Operators StringEquals, IpAddress, Bool, DateGreaterThan, etc.
aws:SourceIp IP-based access control with CIDR support
aws:SecureTransport Require HTTPS
aws:CurrentTime Time-based access control
s3:ExistingObjectTag/<key> Tag-based access control for existing objects
Wildcard Patterns Support for * and ? in actions and resources
Principal Matching *, account IDs, and user ARNs

Planned

Feature GitHub Issue
s3:RequestObjectTag/<key> For tag conditions on PUT requests
s3:RequestObjectTagKeys Check which tag keys are in request
s3:x-amz-content-sha256 Content hash condition
s3:x-amz-server-side-encryption SSE condition
s3:x-amz-storage-class Storage class condition
Cross-account access Access across different accounts
VPC Endpoint policies Network-level policies

For feature requests or to track progress, see the GitHub Issues.