RGW ARN naming conventions considerations in multi tenant scenarios
Table of Contents
- Paths in ARNs
- example to identify all objects in a bucket
- example to identify objects by partial name
- example combining wildcard types question mark (?) and an asterix (*)
- example combining wildcards types in multiple segments
- Using rgw-policy-check to verify your policy
- example usage for rgw-policy-check with stdin input
Disclaimer: Links contained herein to external website(s) are provided for convenience only. Red Hat has not reviewed the links and is not responsible for the content or its availability. The inclusion of any link to an external website does not imply endorsement by Red Hat of the website or their entities, products or services. You agree that Red Hat is not responsible or liable for any loss or expenses that may result due to your use of (or reliance on) the external site or content.
Amazon Resource Name (ARN) format
The following are the general formats for ARNs. The specific formats depend on the resource.
Be aware that:
- RGW uses
tenant
instead of the AWS nameaccount ID
-
the ARNs for some resources omit the Region, the tenant, or both the Region and the tenant.
arn:partition:service:region:tenant:resource-id arn:partition:service:region:tenant:resource-type/resource-id arn:partition:service:region:tenant:resource-type:resource-id
refer to the AWS documentation for the detailed explanation of the items that form the ARN.
Evaluating the tenant definition
The AWS documentation is not clear enough on the accepted characters being accepted. One might consider logical separation of for example the source system and the tenant name by adding special characters for separation like $
.
The RGW internally uses special characters for handling logic within the code, and even accepting reserved characters as tenant name one should avoid the use of special characters to not conflict and or break deployments.
Recommendations for naming are to comply with ARN resource-id defined naming conventions as listed below.
Note: tenant name is unique and case-insensitive
- names must be between 3(min) and 64(max) characters long
- names can consist only of letters, numbers, dots(.), and hyphens(-)
- names must not be formatted as an IP address (example, 127.0.0.1)
- names must not start with the prefix
xn--
(punycode)
tenant valid examples
arn:aws:s3::ldap.tenant1
arn:aws:s3::ad-tenant1
tenant invalid examples
arn:aws:s3::ldap$tenant1
arn:aws:s3::ldap%tenant1
Note: policies owned by a tenant cannot grant access to a resource owned by another tenant
Evaluating the resource-id definition
Resource ARNs can be formed similar as a unix style path. Objects can includes slashes (/) as well a wildcard character (*). Resources may not include a double point (:)
resource-id valid examples
arn:aws:s3::ldap.tenant1:bucket/file
arn:aws:s3::ldap.tenant1:bucket/subdirectory/file.txt
arn:aws:s3::ldap.tenant1:bucket/*
resource-id invalid examples
arn:aws:s3::ldap.tenant1:bucket/file:group.txt
arn:aws:s3::ldap.tenant1:bucket*
Paths in ARNs
Resource ARNs can include a path including slashes (/) wildcard character namely an asterisk (*) as well as a question mark (?) to represent any single character. You can use multiple wildcard characters in each segment but a wildcard cannot span segments.
example to identify all objects in a bucket
this example identifies all objects within bucket
of tenant ldap-tenant1
arn:aws:s3::ldap.tenant1:bucket/*
example to identify objects by partial name
this example identifies all objects within bucket
of tenant ldap.tenant1
starting with reports
arn:aws:s3::ldap.tenant1:buckets/reports*
example combining wildcard types question mark (?) and an asterix (*)
this example identifes all objects within bucket
of tenant ldap.tenant1
with a year (YYYY) syntax 20??
and all
extenions
arn:aws:s3::ldap.tenant1:buckets/reports-20??-*
the wildcard characters can be used multiple times to be more or less specific accordingly
this example matching the same files but for all
year (YYYY) syntax report files and containing sa
(eq sales)
arn:aws:s3::ldap.tenant1:buckets/reports-????-sa???-.*
example combining wildcards types in multiple segments
this example identifies all objects within bucket
of tenant ldap.tenant1
with a folder structure matchin 20??
and starting with reports
arn:aws:s3::ldap.tenant1:buckets/20??/reports-*
combining wildcard characters within a segment is possible as seen in example combining wildcard types
Using rgw-policy-check to verify your policy
Red Hat provides a tool called rgw-policy-check
to verify your policy in case it you are not sure on the syntax validity.
The tool expects a tenant
(-t) and accepts one or multiple policies through stdin or files.
example usage for rgw-policy-check with stdin input
Our policy intends to limit the actions:
- Action
s3:ListBucket
s3:GetObject
s3:GetObjectVersion
to grant access to reports of the sales department that are stored in the bucket at and named like:
- Resource
bucket/YYYY/reports-sales.*
for everyone
- Principal
*
as long as the Client is from a corporate Network segment
- aws:SourceIp
10.0.0.1/24
10.0.0.2/24
The policy compiles as follows and is written in json
syntax
{
"Version": "2012-10-17",
"Id": "S3PolicyTest",
"Statement": [
{
"Sid": "publicAccess",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3::ldap.tenant1:/bucket/20??/reports*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"10.0.0.1/24",
"10.0.0.2/24"
]
}
}
}
]
}
now calling the tool on your Red Hat Ceph Cluster to validate the policy, you need to specify the tenant (-t) as specified in the policy in Resource
$ rgw-ceph-policy -t ldap.tenant1
{
"Version": "2012-10-17",
"Id": "S3PolicyTest",
"Statement": [
{
"Sid": "publicAccess",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3::ldap.tenant1:/bucket/20??/reports*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"10.0.0.1/24",
"10.0.0.2/24"
]
}
}
}
]
}
[CTRL+D]
$ echo $?
0
the exit code 0
as well as no stderr
output indicate that the policy is valid and accepted.
invalid policy reported by rgw-policy-check
using the same policy but adding an invalid Resource
specification will report the character offset and the rgw-policy-check will exit with code 1
$ rgw-ceph-policy -t ldap::tenant1
{
"Version": "2012-10-17",
"Id": "S3PolicyTest",
"Statement": [
{
"Sid": "publicAccess",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3::ldap::tenant1:/bucket/20??/reports*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"10.0.0.1/24",
"10.0.0.2/24"
]
}
}
}
]
}
[CTRL+D]
(stdin): At character offset 337, `arn:aws:s3::ldap::tenant1:/bucket/20??/reports*` is not a valid ARN. Resource ARNs should have a format like `arn:aws:s3::tenant:resource' or `arn:aws:s3:::resource`.
$ echo $?
1
example usage for rgw-policy-check with multiple files input
when checking multiple policies stdin might not be sufficient and rgw-policy-check can iterate over a list of files validating and reporting syntax correctness accordingly.
$ rgw-policy-check -t ldap.tenant1 /tmp/policies*
$ echo $?
0
rgw-policy-check will report broken policies accordingly
$ rgw-policy-check -t ldap.tenant1 /tmp/policies*
/tmp/policies1.txt: At character offset 337, `arn:aws:s3::ldap::tenant1:/bucket/20??/reports*` is not a valid ARN. Resource ARNs should have a format like `arn:aws:s3::tenant:resource' or `arn:aws:s3:::resource`.
/tmp/policies3.txt: At character offset 337, `arn:aws:s3::ldap::tenant1:/bucket/20??/reports*` is not a valid ARN. Resource ARNs should have a format like `arn:aws:s3::tenant:resource' or `arn:aws:s3:::resource`.
/tmp/policies4.txt: At character offset 336, Policy owned by tenant `ldap.tenant1` cannot grant access to resource owned by tenant `ldap.tenant2`.
$ echo $?
1