The StorageGRID Webscale system implements a subset of the S3 REST API policy language that you can use to control access to buckets and objects within those buckets.
Policy statements are built using this structure to specify permissions: Grant <Effect> to allow/deny <Principal> to perform <Action> on <Resource> when <Condition> applies.
Each policy element is used for a specific function:
Element | Description |
---|---|
Sid | The Sid element is optional. The Sid is only intended as a description for the user. It is stored but not interpreted by the StorageGRID Webscale system. |
Effect | Use the Effect element to establish whether the specified operations are allowed or denied. You must identify operations you allow (or deny) on buckets or objects using the supported Action element keywords. |
Principal/NotPrincipal | You can allow users, groups, and accounts to access specific resources and perform specific actions. If no S3 signature is included in the request, anonymous access is allowed by specifying the wildcard character (*) as the principal. By default, only the account root has access to resources owned by the account. You only need to specify the Principal element in a bucket policy. For group policies, the group to which the policy is attached is the implicit Principal element. |
Resource/NotResource | The Resource element identifies buckets and objects. You can allow or deny permissions to buckets and objects using the uniform resource name (URN) to identify the resource. |
Action/NotAction | The Action and Effect elements are the two components of permissions. When a group requests a resource, they are either granted or denied access to the resource. Access is denied unless you specifically assign permissions, but you can use explicit deny to override a permission granted by another policy. |
Condition | The Condition element is optional. Conditions allow you to build expressions to determine when a policy should be applied. |
s3:*Object
In the Resource element, you can use the wildcard characters (*) and (?). While the asterisk (*) matches 0 or more characters, the question mark (?) matches any single character.
In the Principal element, wildcard characters are not supported except to set anonymous access, which grants permission to everyone. For example, you set the wildcard (*) as the Principal value.
"Principal":"*"
In the following example, the statement is using the Effect, Principal, Action, and Resource elements. This example shows a complete bucket policy statement that uses the Effect "Allow" to give the Principals, the admin group federated-group/admin and the finance group federated-group/finance, permissions to perform the Action s3:ListBucket on the bucket named "mybucket" and the Action s3:GetObject on all objects inside that bucket.
{ "Statement": [ { "Effect": "Allow", "Principal": { "SGWS": [ "urn:sgws:identity::27233906934684427525:federated-group/admin", "urn:sgws:identity::27233906934684427525:federated-group/finance" ] }, "Action": [ "s3:ListBucket", "s3:GetObject" ], "Resource": [ "urn:sgws:s3:::mybucket", "urn:sgws:s3:::mybucket/*" ] } ] }
The bucket policy has a size limit of 20,480 bytes, and the group policy has a size limit of 5,120 bytes.
Group and bucket policy updates are eventually consistent. To change the consistency guarantees for a bucket policy update, set the "Consistency-Control" header as required for the PUT bucket policy request or set the bucket consistency level as required using the PUT bucket consistency request. Only consistency ALL is supported. Consistency ALL is applied to bucket policies, and anything else is rejected (if specified in a header for the PUT bucket consistency request) or ignored (if set at the bucket level). Once a policy change becomes consistent, group policies can take an additional 15 minutes, and bucket policies can take an additional 8 seconds before taking effect due to policy caching.
urn:sgws:s3:::bucket_name urn:sgws:s3:::bucket_name/object_key
urn:sgws:identity::account_id:root urn:sgws:identity::account_id:user/user_name urn:sgws:identity::account_id:group/group_name urn:sgws:identity::account_id:federated-user/user_name urn:sgws:identity::account_id:federated-group/group_name
The HTTP request body for the PUT Bucket policy operation must be encoded with charset=UTF-8.
For example:
"Resource": "urn:sgws:s3:::mybucket/*"
"Resource": "urn:sgws:s3:::mybucket/home/${sgws:username}/*"
See Specifying variables in a policy for a list of available policy variables.
The resource value can specify a bucket that does not yet exist when a group policy is created.
"Principal": { "SGWS": "account_id"} "Principal": { "SGWS": "identity_urn" }
"Principal": { "SGWS": "27233906934684427525" }
"Principal": { "SGWS": "urn:sgws:identity::27233906934684427525:root" }
"Principal": { "SGWS": "urn:sgws:identity::27233906934684427525:federated-user/Bob" }
"Principal": { "SGWS": "urn:sgws:identity::27233906934684427525:federated-group/Managers" }
"Principal": "*"
urn:sgws:identity::27233906934684427525:user-uuid/de305d54-75b4-431b-adb2-eb6b9e546013
The principal value can specify a group/user name that does not yet exist when a bucket policy is created.
In a policy, the Action element is used to allow/deny permissions to a resource. There are a set of permissions that you can specify in a policy, which are denoted by the element "Action," or alternatively, "NotAction" for exclusion. Each of these elements maps to specific S3 REST API operations.
Permissions applicable to buckets:
Permissions | S3 REST API operations |
---|---|
s3:CreateBucket | PUT Bucket |
s3:DeleteBucket | DELETE Bucket |
s3:DeleteBucketPolicy | DELETE Bucket policy |
s3:GetBucketAcl | GET Bucket ACL |
s3:GetBucketConsistency | GET Bucket Consistency |
s3:GetBucketLastAccessTime | GET Bucket Last Access Time |
s3:GetBucketLocation | GET Bucket location |
s3:GetBucketPolicy | GET Bucket policy |
s3:GetBucketVersioning | GET Bucket versioning |
s3:ListAllMyBuckets | GET Service, GET Storage Usage |
s3:ListBucket | GET Bucket (List Objects), HEAD Bucket |
s3:ListBucketMultipartUploads | List Multipart Uploads |
s3:ListBucketVersions | GET Bucket versions |
s3:PutBucketConsistency | PUT Bucket Consistency |
s3:PutBucketLastAccessTime | PUT Bucket Last Access Time |
s3:PutBucketPolicy | PUT Bucket policy |
s3:PutBucketVersioning | PUT Bucket versioning |
Permissions applicable to objects:
Permissions | S3 REST API operations |
---|---|
s3:AbortMultipartUpload | Abort Multipart Upload |
s3:DeleteObject | DELETE Object, DELETE Multiple Objects |
s3:DeleteObjectVersion | DELETE Object (a specific version of the object) |
s3:GetObject | GET Object, HEAD Object |
s3:GetObjectAcl | GET Object ACL |
s3:GetObjectVersion | GET Object (a specific version of the object) |
s3:ListMultipartUploadParts | List Parts |
s3:PutObject | PUT Object, PUT Object - Copy, Initiate Multipart Upload, Complete Multipart Upload, uploading parts (Upload Part and Upload Part - Copy) |
s3:PutOverwriteObject | PUT Object, PUT Object - Copy, Complete Multipart Upload |
The PutOverwriteObject permission applies to operations that create or update objects (for example, PUT new objects or PUT Copy to update metadata). The setting of this permission determines whether the client can overwrite an object's data or metadata. Possible settings include Allow (client can overwrite an object) or Deny (client cannot overwrite an object). The default setting is Allow. When this permission is not present, the effect is the same as if Allow were set.
When set to Deny, this permission works as follows.
For an example using the PutOverwriteObject permission, see Example: PutOverwriteObject permission.
You can use conditions to allow policies to take effect based on request values.
Conditions use key-value pairs for evaluation. A Condition element can contain multiple conditions, and each condition can contain multiple key-value pairs. The condition block uses the following format:
Condition: { condition_type: { condition_key: condition_values
In the following example, the IpAddress condition uses the SourceIp condition key.
"Condition": { "IpAddress": { "sgws:SourceIp": "54.240.143.0/24" ... }, ...
Supported condition operators:
Condition operators | Description |
---|---|
StringEquals | Compares a key to a string value based on exact equality (case sensitive). |
StringNotEquals | Compares a key to a string value based on exact non-equality (case sensitive). |
StringEqualsIgnoreCase | Compares a key to a string value based on exact equality (ignores case). |
StringNotEqualsIgnoreCase | Compares a key to a string value based on exact non-equality (ignores case). |
StringLike | Compares a key to a string value and provides access if there is an exact match (case sensitive). Can include * and ? wildcard characters. |
StringNotLike | Compares a key to a string value and provides access to all except the specified string (case sensitive). Can include * and ? wildcard characters. |
NumericEquals | Compares a key to a numeric value and provides access if there is an exact match. |
NumericNotEquals | Compares a key to a numeric value and provides access to all except the specified value. |
NumericGreaterThan | Compares a key to a numeric value and provides access if there is a "greater than" matching. |
NumericGreaterThanEquals | Compares a key to a numeric value and provides access if there is a "greater than or equals" matching. |
NumericLessThan | Compares a key to a numeric value and provides access if there is a "less than" matching. |
NumericLessThanEquals | Compares a key to a numeric value and provides access if there is a "less than or equals" matching. |
Bool | Compares a key to a Boolean value and provides access based on a "true or false" matching. |
IpAddress | Compares a key to a numeric value and provides access if there is a match to an IP or range of IP addresses. |
NotIpAddress | Compares a key to a numeric value and provides access to all addresses except the specified IP or range of IP addresses. |
Null | Checks if a condition key is present in the current request context. |
Supported condition keys:
Category | Applicable condition keys | Description |
---|---|---|
IP operators | sgws:SourceIp | Will compare to the IP address from which the request was sent. Can be used for bucket or object operations. |
Resource/Identity | sgws:username | Will compare to the sender's username from which the request was sent. Can be used for bucket or object operations. |
S3:ListBucket and S3:ListBucketVersions permissions |
s3:delimiter | Will compare to the delimiter parameter specified in a GET Bucket or GET Bucket Object versions request. |
s3:max-keys | Will compare to the max-keys parameter specified in a GET Bucket or GET Bucket Object versions request. | |
s3:prefix | Will compare to the prefix parameter specified in a GET Bucket or GET Bucket Object versions request. |
You can use variables in policies to populate policy information when it is available. You can use policy variables in the Resource element and in string comparisons in the Condition element.
In this example, the variable ${sgws:username} is part of the Resource element:
"Resource": "urn:sgws:s3:::bucket-name/home/${sgws:username}/*"
In this example, the variable ${sgws:username} is part of the condition value in the condition block:
"Condition": { "StringLike": { "s3:prefix": "${sgws:username}/*" ... }, ...
Variable | Description |
---|---|
${sgws:SourceIp} | Uses the SourceIp key as the provided variable. |
${sgws:username} | Uses the username key as the provided variable. |
${s3:prefix} | Uses the service-specific prefix key as the provided variable. |
${s3:max-keys} | Uses the service-specific max-keys key as the provided variable. |
${*} | Special character. Uses the character as a literal * character. |
${?} | Special character. Uses the character as a literal ? character. |
${$} | Special character. Uses the character as a literal $ character. |
Sometimes a policy can grant permissions that are dangerous for security or dangerous for continued operations, such as locking out the root user of the account. The StorageGRID Webscale S3 REST API implementation is less restrictive during policy validation than Amazon, but equally strict during policy evaluation.
Policy description | Policy type | Amazon behavior | StorageGRID behavior |
---|---|---|---|
Deny self any permissions to the root account | Bucket | Valid and enforced, but root user account retains permission for all S3 bucket policy operations | Same |
Deny self any permissions to user/group | Group | Valid and enforced | Same |
Allow a foreign account group any permission | Bucket | Invalid principal | Valid, but permissions for all S3 bucket policy operations return a 405 Method Not Allowed error when allowed by a policy |
Allow a foreign account root or user any permission | Bucket | Valid, but permissions for all S3 bucket policy operations return a 405 Method Not Allowed error when allowed by a policy | Same |
Allow everyone permissions to all actions | Bucket | Valid, but permissions for all S3 bucket policy operations return a 405 Method Not Allowed error for the foreign account root and users | Same |
Deny everyone permissions to all actions | Bucket | Valid and enforced, but root user account retains permission for all S3 bucket policy operations | Same |
Principal is a non-existent user or group | Bucket | Invalid principal | Valid |
Resource is a non-existent S3 bucket | Group | Valid | Same |
Principal is a local group | Bucket | Invalid principal | Valid |