Access control
Three things decide whether an S3 request is allowed:
- The account boundary. A bucket belongs to one organization (one account when self-hosting). Keys from elsewhere can't touch it unless its policy says so.
- The key's scope. A key can be limited to some buckets, and to reading.
- The bucket policy. An optional IAM-style document on the bucket that can
deny anyone, or allow everyone (
"*") to do something.
An explicit Deny in a bucket policy wins over everything, the owner
included. The bucket's own keys are allowed within their scope. Anyone else
needs an Allow in the policy. Everything else is refused with
403 AccessDenied.
Scoped keys
In the console, choose the buckets a key may use and whether it is read-only when you create it. When self-hosting:
swiftfs admin key create --account acme --bucket uploads --bucket thumbnails
swiftfs admin key create --account acme --bucket reports --read-onlyGive each application the narrowest key that works: a thumbnailing job that
reads uploads and writes thumbnails needs no access to invoices.
Public read
To serve a prefix to anyone without a signature (images for a website, say),
allow s3:GetObject on it for "*":
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicMedia",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::acme-site/media/*"
}
]
}aws --endpoint-url "$S3_ENDPOINT" s3api put-bucket-policy --bucket acme-site --policy file://policy.json
aws --endpoint-url "$S3_ENDPOINT" s3api get-bucket-policy-status --bucket acme-site # IsPublicAnonymous GET /acme-site/media/logo.png now works. Listing the bucket,
writing, and reading outside media/ are still refused. Anonymous requests
are billed to the bucket's owner and rate-limited per client IP.
Remove the policy to make the bucket private again:
aws --endpoint-url "$S3_ENDPOINT" s3api delete-bucket-policy --bucket acme-siteDenying by network
A Deny with an IP condition keeps everyone, the owner included, to known networks:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::acme-records", "arn:aws:s3:::acme-records/*"],
"Condition": { "NotIpAddress": { "aws:SourceIp": ["203.0.113.0/24"] } }
}
]
}The owner can always read, replace or delete the policy itself, so a mistake can't lock you out.
The policy language
SwiftFS implements a subset of AWS's IAM policy grammar and rejects
anything outside it with MalformedPolicy, rather than quietly ignoring it:
| Element | Supported |
|---|---|
Version | 2012-10-17 (or 2008-10-17) |
Effect | Allow, Deny |
Principal | "*" (or {"AWS": "*"}) only |
Action, NotAction | s3: actions, with * and ? wildcards |
Resource | arn:aws:s3:::bucket and arn:aws:s3:::bucket/key-pattern, this bucket only |
Condition | IpAddress, NotIpAddress on aws:SourceIp |
Grants to specific other accounts are not available yet.
In SwiftFS Cloud
Console roles decide who may manage buckets, keys and members; see organizations and roles. A member's access keys never allow more than their role.