Table of Contents
- S3 Policy Variables
- Overview
- Supported Variable Types
- Usage Examples
- User Isolation with ${aws:username}
- Combining Allow and Deny
- JWT Claims in Resources
- Variables in Conditions
- Account-Based Access Control
- LDAP Integration
- Principal ARN Parsing
- Best Practices
- 1. Use Explicit Deny for Security
- 2. Test Policies Thoroughly
- 3. Use Conditions for Complex Logic
- 4. Document Variable Expectations
- Troubleshooting
- Related Documentation
S3 Policy Variables
SeaweedFS supports AWS S3 policy variables, allowing you to create dynamic, flexible bucket policies that adapt based on the requester's identity and context.
Overview
Policy variables enable you to write a single policy that applies to multiple users by substituting values at request time. Instead of creating separate policies for each user, you can use variables like ${aws:username} that get replaced with the actual username during policy evaluation.
Supported Variable Types
AWS Context Variables
These variables are automatically extracted from the principal ARN:
| Variable | Description | Available For |
|---|---|---|
${aws:username} |
Username or role name | IAM Users, IAM Roles, Assumed Roles |
${aws:userid} |
User ID | IAM Users, Assumed Roles only |
${aws:principaltype} |
Type of principal | IAM Users, IAM Roles, Assumed Roles |
${aws:PrincipalAccount} |
AWS account ID | IAM Users, Assumed Roles only |
Principal Type Values
IAMUser- For IAM user ARNs (arn:aws:iam::account:user/username)IAMRole- For IAM role ARNs (arn:aws:iam::account:role/rolename)AssumedRole- For assumed role ARNs (arn:aws:sts::account:assumed-role/role/session)
Important
: IAM Roles do NOT have
aws:useridoraws:PrincipalAccountvariables. These are only available for IAM Users and Assumed Roles.
JWT Claim Variables
Access any JWT claim using the ${jwt:claim-name} syntax:
| Variable | Description |
|---|---|
${jwt:preferred_username} |
Preferred username from JWT |
${jwt:sub} |
Subject (user ID) from JWT |
${jwt:email} |
Email address from JWT |
${jwt:*} |
Any custom JWT claim |
LDAP Claim Variables
Access LDAP attributes using the ${ldap:attribute} syntax:
| Variable | Description |
|---|---|
${ldap:username} |
LDAP username |
${ldap:dn} |
LDAP distinguished name |
${ldap:*} |
Any custom LDAP attribute |
S3 Request Variables
Standard S3 condition variables can also be used:
| Variable | Description |
|---|---|
${s3:prefix} |
Prefix parameter from ListBucket |
${aws:SourceIp} |
Source IP address |
${aws:SecureTransport} |
Whether request uses HTTPS |
Usage Examples
User Isolation with ${aws:username}
Allow each user to access only their own folder:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/${aws:username}/*"
}
]
}
When user alice makes a request, the policy evaluates as:
- Resource:
arn:aws:s3:::my-bucket/alice/*
When user bob makes a request:
- Resource:
arn:aws:s3:::my-bucket/bob/*
Combining Allow and Deny
Explicitly allow own folder and deny everything else:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowOwnFolder",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/${aws:username}/*"
},
{
"Sid": "DenyOtherFolders",
"Effect": "Deny",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"NotResource": "arn:aws:s3:::my-bucket/${aws:username}/*"
}
]
}
JWT Claims in Resources
Use JWT claims for dynamic path isolation:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::uploads/${jwt:preferred_username}/*"
}
]
}
Variables in Conditions
Use variables in condition blocks:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"StringLike": {
"s3:prefix": ["${aws:username}/*"]
}
}
}
]
}
Account-Based Access Control
Restrict access to specific AWS accounts:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringNotEquals": {
"aws:PrincipalAccount": ["123456789012"]
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
LDAP Integration
Use LDAP attributes for access control:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::data/${ldap:username}/*"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::data/*",
"Condition": {
"StringEquals": {
"ldap:dn": "cn=manager,dc=example,dc=org"
}
}
}
]
}
Principal ARN Parsing
SeaweedFS automatically extracts variables from principal ARNs:
IAM User ARN
arn:aws:iam::123456789012:user/alice
Extracts:
aws:username=aliceaws:userid=aliceaws:principaltype=IAMUseraws:PrincipalAccount=123456789012
IAM User with Path
arn:aws:iam::123456789012:user/division/team/alice
Extracts:
aws:username=alice(last segment)aws:userid=aliceaws:principaltype=IAMUseraws:PrincipalAccount=123456789012
IAM Role ARN
arn:aws:iam::123456789012:role/MyRole
Extracts:
aws:username=MyRoleaws:principaltype=IAMRole
Note: IAM Roles do NOT have aws:userid or aws:PrincipalAccount.
Assumed Role ARN
arn:aws:sts::123456789012:assumed-role/MyRole/session-alice
Extracts:
aws:username=session-alice(session name)aws:userid=session-aliceaws:principaltype=AssumedRoleaws:PrincipalAccount=123456789012
Best Practices
1. Use Explicit Deny for Security
Combine Allow and Deny statements to prevent unauthorized access:
{
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket/${aws:username}/*"
},
{
"Effect": "Deny",
"Action": "s3:*",
"NotResource": "arn:aws:s3:::bucket/${aws:username}/*"
}
]
}
2. Test Policies Thoroughly
Test with different users to ensure variables substitute correctly (ensure $S3_ENDPOINT is set, e.g., export S3_ENDPOINT=http://localhost:8333):
# Test as alice
aws --endpoint-url $S3_ENDPOINT s3 cp file.txt s3://bucket/alice/file.txt --profile alice
# Test as bob
aws --endpoint-url $S3_ENDPOINT s3 cp file.txt s3://bucket/bob/file.txt --profile bob
# Verify isolation
aws --endpoint-url $S3_ENDPOINT s3 ls s3://bucket/alice/ --profile bob # Should fail
3. Use Conditions for Complex Logic
Combine variables with conditions for fine-grained control:
{
"Condition": {
"StringLike": {
"s3:prefix": ["${aws:username}/*"]
},
"StringEquals": {
"aws:principaltype": "IAMUser"
}
}
}
4. Document Variable Expectations
Clearly document which JWT/LDAP claims your policies expect:
{
"Comment": "Requires JWT claims: preferred_username, department",
"Statement": [
{
"Resource": "arn:aws:s3:::data/${jwt:department}/${jwt:preferred_username}/*"
}
]
}
Troubleshooting
Variables Not Substituting
Problem: Variables appear as literal strings in logs
Solution: Ensure the variable exists in the request context. Check:
- Principal ARN format is correct
- JWT claims are present in the token
- LDAP attributes are mapped correctly
Access Denied Despite Matching Path
Problem: User can't access their own folder
Solution: Check for conflicting Deny statements. Remember that Deny always wins:
{
"Statement": [
{
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/${aws:username}/*"
},
{
"Effect": "Deny",
"NotResource": "arn:aws:s3:::bucket/${aws:username}/*"
}
]
}
IAM Role Variables Missing
Problem: aws:userid or aws:PrincipalAccount not available for IAM Roles
Solution: This is expected behavior. IAM Roles only have aws:username and aws:principaltype. Use Assumed Roles if you need these variables.
Related Documentation
- Amazon S3 API - S3 API compatibility
- S3 Credentials - Managing S3 credentials
- OIDC Integration - JWT-based authentication
- Amazon IAM API - IAM API support
Introduction
API
Configuration
- Replication
- Store file with a Time To Live
- Failover Master Server
- Erasure coding for warm storage
- Server Startup via Systemd
- Environment Variables
Filer
- Filer Setup
- Directories and Files
- File Operations Quick Reference
- Data Structure for Large Files
- Filer Data Encryption
- Filer Commands and Operations
- Filer JWT Use
- TUS Resumable Uploads
Filer Stores
- Filer Cassandra Setup
- Filer Redis Setup
- Super Large Directories
- Path-Specific Filer Store
- Choosing a Filer Store
- Customize Filer Store
Management
Advanced Filer Configurations
- Migrate to Filer Store
- Add New Filer Store
- Filer Store Replication
- Filer Active Active cross cluster continuous synchronization
- Filer as a Key-Large-Value Store
- Path Specific Configuration
- Filer Change Data Capture
FUSE Mount
WebDAV
Cloud Drive
- Cloud Drive Benefits
- Cloud Drive Architecture
- Configure Remote Storage
- Mount Remote Storage
- Cache Remote Storage
- Cloud Drive Quick Setup
- Gateway to Remote Object Storage
AWS S3 API
- Amazon S3 API
- S3 Conditional Operations
- S3 CORS
- S3 Object Lock and Retention
- S3 Object Versioning
- S3 API Benchmark
- S3 API FAQ
- S3 Bucket Quota
- S3 Rate Limiting
- S3 API Audit log
- S3 Nginx Proxy
- Docker Compose for S3
S3 Table Bucket
S3 Authentication & IAM
- S3 Configuration - Start Here
- S3 Credentials (
-s3.config) - OIDC Integration (
-s3.iam.config) - S3 Policy Variables
- Amazon IAM API
- AWS IAM CLI
Server-Side Encryption
S3 Client Tools
- AWS CLI with SeaweedFS
- s3cmd with SeaweedFS
- rclone with SeaweedFS
- restic with SeaweedFS
- nodejs with Seaweed S3
Machine Learning
HDFS
- Hadoop Compatible File System
- run Spark on SeaweedFS
- run HBase on SeaweedFS
- run Presto on SeaweedFS
- Hadoop Benchmark
- HDFS via S3 connector
Replication and Backup
- Async Replication to another Filer [Deprecated]
- Async Backup
- Async Filer Metadata Backup
- Async Replication to Cloud [Deprecated]
- Kubernetes Backups and Recovery with K8up
Metadata Change Events
Messaging
- Structured Data Lake with SMQ and SQL
- Seaweed Message Queue
- SQL Queries on Message Queue
- SQL Quick Reference
- PostgreSQL-compatible Server weed db
- Pub-Sub to SMQ to SQL
- Kafka to Kafka Gateway to SMQ to SQL
Use Cases
Operations
Advanced
- Large File Handling
- Optimization
- Volume Management
- Tiered Storage
- Cloud Tier
- Cloud Monitoring
- Load Command Line Options from a file
- SRV Service Discovery
- Volume Files Structure
Security
- Security Overview
- Security Configuration
- Cryptography and FIPS Compliance
- Run Blob Storage on Public Internet