OBS RBAC best practices

Technical additional documentation

(updated after October 2023 IAM upgrade https://cloud.orange-business.com/en/release-notes/application-services/10-2023-identity-and-access-management-iam-update/)

Introduction

This article describes the best practices around Role Based Access Control (RBAC) for Object Storage Service (OBS) and Identity and Access Management (IAM) on Flexible Engine (FE).

It summarizes and complements the OBS documentation pages and IAM documentation pages from Flexible Engine Help Center by focusing on practical uses cases.

Before describing those practical use cases it’s important to remind a few principles about Object Storage Service on Flexible Engine.

OBS RBAC principles

OBS consists of buckets and objects.

OBS is a domain level service even if buckets are created in specific regions. OBS service permissions are assigned to users in the global project, and users do not need to switch regions when accessing OBS console.

A bucket is a container for storing objects in OBS. Each bucket belong to a region and has specific access permissions.

Objects in a bucket inherit from bucket access permissions or can have specific access permissions.

The owner of a bucket is the account/domain that created the bucket. If the bucket is created by an IAM user under an account/domain, the bucket owner is the account/domain instead of the IAM user. This is very important to keep that in mind when implementing RBAC for OBS on FE. IAM user often think bucket they have created belong to them but they belong to the account/domain to which they belong and thus access restriction for other IAM users under an account/domain can be tricky to implement.

The owner of an object is the account that uploads the object, who may not be the owner of the bucket to which the object belongs. For example, account B is granted the permission to access a bucket of account A, and account B uploads a file to the bucket. In that case, instead of the bucket owner account A, account B is the owner of the object.

3 differents access control mechanisms are involved when accessing buckets and objects :

  • IAM Policies

IAM policies are used to define IAM user group access permission on OBS service itself (applying on all existing bucket and future ones). It can also be used to define IAM user group access permission on specific buckets using custom IAM policies.

  • Bucket ACL and object ACL

Bucket ACL and Object ACL are used to give access permission on a bucket or an object to other account/domain. It is also used to allow write access to “log delivery user group” when activating access logging on another bucket.

  • Bucket policies and object policies

Bucket policies and object policies are used to define IAM user (from the account/domain or from another one) specific access permission on a bucket or an object. It allows fine grained access control regarding actions on bucket and object. Bucket policies and object polices supplement, and in many cases, replace ACLs of buckets and objects.

 

OBS provides multiple permission control mechanisms, including time-limited access to objects, object ACLs, bucket ACLs, and bucket policies. Some service-level permissions (for example, creating a bucket and listing all buckets) cannot be configured through OBS and can only be configured on IAM. OBS permissions apply only to resources (buckets and objects). To grant both OBS service-level and resource-level permissions, you must use IAM permissions or both IAM and OBS permissions.

Based on the least-privilege principle, access is denied denied by default, and an explicit deny statement always takes precedence over an allow statement.

When multiple access control mechanism coexist the authorization result is summarized in this table:

IAM structure for OBS RBAC

Based on separation of duties principle, the IAM users of an account/domain should be assigned to different groups with different privilege depending on their role and legitimate activities.

FE IAM principles are described in details in this article (IAM and multi tenancy principles on Flexible Engine).

Only a couple of IAM user should be in the “Super Admin” group with full access to all services and resources in the account/domain.

Be aware that IAM user in a “Super Admin” group will always have an access to buckets and objects whatever the rules defined .

If a standard IAM user creates a bucket with a deny bucket policy for all IAM users from the account/domain, a “Super Admin” IAM user will be able to change this bucket policy…

That’s why you should always start by defining an IAM group structure for all IAM users before starting to define RBAC on OBS.

IAM Group permissions are managed through association of policies (system and/or custom) with projects:

  • Global project: Policies for domain level services (IAM, DNS, TMS, OBS, etc)
  • main project of a region: policies associated to main project of a region
  • sub project of a region: policies associated to main project of a region

IAM policies can be associated with “Global service” project, with specific projects (main or sub) or with all existing and future projects.

OBS IAM policies can be associated only with “Global service” project or with all existing and future projects.

IAM system policies are listed here: https://docs.prod-cloud-ocb.orange-business.com/en-us/permissions/index.html

IAM custom policies management is described here: https://docs.prod-cloud-ocb.orange-business.com/usermanual/iam/iam_01_0015.html

IAM user are associated to 1 or several IAM groups.

Here is an example of IAM group structure with associated policies which allow most OBS RBAC use cases:

  • Super_admin: access and manage everything in the domain
Region Project Name Policy
Global Global service Full Access, OBS Full Access
eu-west-0 eu-west-0 Tenant Administrator
eu-west-0 eu-west-0_sub_project Tenant Administrator
eu-west-1 eu-west-1 Tenant Administrator
eu-west-1 eu-west-1_sub_project Tenant Administrator

 

  • Security_manager: manage IAM (project, users, groups, policies) and OBS bucket management (CRUD and RBAC)
Region Project Name Policy
Global Global service Security Administrator, OBS Bucket Manager (1)
eu-west-0 eu-west-0  
eu-west-0 eu-west-0_sub_project  
eu-west-1 eu-west-1  
eu-west-1 eu-west-1_sub_project  

 

  • Project_admin: access and manage everything in one or several projects with with limited permission on IAM and OBS services
Region Project Name Policy
Global Global service TMS Administrator, IAM ReadOnlyAcces,  OBS Buckets Viewer Enhanced (2)
eu-west-0 eu-west-0  
eu-west-0 eu-west-0_sub_project Tenant Administrator
eu-west-1 eu-west-1  
eu-west-1 eu-west-1_sub_project Tenant Administrator

 

Of course, other IAM groups similar to “Project_admin” can be created to limit permissions on specific services for main project and sub projects.

Then instead of the “Tenant Administrator” policy, service specific system policies or custom policies can be used (ex: “VPC Admin”, “ECS Admin”, “EVS Admin”, etc).

But in order to have efficient RBAC policies on OBS buckets, most IAM groups should have limited permission on IAM and OBS using system policy “OBS Buckets Viewer” or using custom policy “OBS Buckets Viewer Enhanced” (2):

"OBS Buckets Viewer Enhanced" (2) custom policy example

{
    "Version": "1.1",
    "Statement": [
        {
            "Action": [
                "obs:bucket:HeadBucket",
                "obs:bucket:ListAllMyBuckets",
                "obs:bucket:GetBucketStorage",
                "obs:bucket:GetBucketQuota",
                "obs:bucket:GetBucketTagging",
                "obs:bucket:GetBucketCustomDomainConfiguration",
                "obs:bucket:GetBucketCORS",
                "obs:bucket:GetLifecycleConfiguration",
                "obs:bucket:GetDirectColdAccessConfiguration",
                "obs:bucket:GetBucketLogging",
                "obs:bucket:GetBucketInventoryConfiguration",
                "obs:bucket:GetReplicationConfiguration",
                "obs:bucket:GetBucketStoragePolicy",
                "obs:bucket:GetBucketPolicy",
                "obs:bucket:GetBucketNotification",
                "obs:bucket:GetBucketAcl",
                "obs:bucket:GetBucketWebsite",
                "obs:bucket:GetEncryptionConfiguration",
                "obs:bucket:GetBucketLocation",
                "obs:bucket:GetBucketVersioning"
            ],
            "Effect": "Allow"
        }
    ]
}

With this custom policy, IAM users can only list buckets without any read or write permission on objects inside them.

Only IAM groups “Super_admin” with “OBS Full Access” system policy and “Security Manager” with “OBS Bucket Manager” (1) custom policy can manage bucket CRUD and RBAC:

"OBS Bucket Manager" (1) custom policy example

{
    "Version": "1.1",
    "Statement": [
        {
            "Action": [
                "obs:bucket:HeadBucket",
                "obs:bucket:ListBucket",
                "obs:bucket:ListBucketMultipartUploads",
                "obs:bucket:ListAllMyBuckets",
                "obs:bucket:PutBucketPolicy",
                "obs:bucket:DeleteBucketPolicy",
                "obs:object:PutObjectAcl",
                "obs:bucket:PutBucketAcl",
                "obs:object:PutObjectVersionAcl",
                "obs:bucket:PutBucketCORS",
                "obs:object:DeleteObjectVersion",
                "obs:bucket:PutEncryptionConfiguration",
                "obs:bucket:PutLifecycleConfiguration",
                "obs:bucket:DeleteReplicationConfiguration",
                "obs:bucket:PutBucketTagging",
                "obs:bucket:DeleteBucketInventoryConfiguration",
                "obs:object:DeleteObject",
                "obs:bucket:PutBucketNotification",
                "obs:object:ModifyObjectMetaData",
                "obs:bucket:DeleteBucketWebsite",
                "obs:bucket:PutBucketLogging",
                "obs:bucket:DeleteBucketTagging",
                "obs:object:RestoreObject",
                "obs:bucket:PutReplicationConfiguration",
                "obs:bucket:PutBucketQuota",
                "obs:bucket:PutBucketVersioning",
                "obs:bucket:CreateBucket",
                "obs:bucket:DeleteBucket",
                "obs:bucket:DeleteDirectColdAccessConfiguration",
                "obs:bucket:PutBucketInventoryConfiguration",
                "obs:bucket:PutBucketWebsite",
                "obs:bucket:DeleteBucketCustomDomainConfiguration",
                "obs:object:AbortMultipartUpload",
                "obs:bucket:PutBucketCustomDomainConfiguration",
                "obs:bucket:PutDirectColdAccessConfiguration",
                "obs:bucket:PutBucketStoragePolicy",
                "obs:bucket:GetBucketStorage",
                "obs:bucket:GetBucketQuota",
                "obs:bucket:GetBucketTagging",
                "obs:object:GetObjectVersionAcl",
                "obs:bucket:GetBucketCustomDomainConfiguration",
                "obs:bucket:GetBucketCORS",
                "obs:object:GetObjectAcl",
                "obs:bucket:GetLifecycleConfiguration",
                "obs:bucket:GetDirectColdAccessConfiguration",
                "obs:bucket:GetBucketLogging",
                "obs:bucket:GetBucketInventoryConfiguration",
                "obs:object:ListMultipartUploadParts",
                "obs:bucket:GetReplicationConfiguration",
                "obs:bucket:ListBucketVersions",
                "obs:bucket:GetBucketStoragePolicy",
                "obs:bucket:GetBucketPolicy",
                "obs:bucket:GetBucketNotification",
                "obs:bucket:GetBucketAcl",
                "obs:bucket:GetBucketWebsite",
                "obs:bucket:GetEncryptionConfiguration",
                "obs:bucket:GetBucketLocation",
                "obs:bucket:GetBucketVersioning"
            ],
            "Effect": "Allow"
        }
    ]
}

With this custom policy, IAM users can only list and delete objects in the buckets in order to be able to manage the buckets without any read or write permission on objects inside them.

All the OBS RBAC use cases described below are based on such IAM structure where most IAM users have limited access to bucket (“OBS Buckets Viewer” or “OBS Buckets Viewer Enhanced”) and only specific users are managing bucket CRUD and RBAC (“OBS Bucket Manager”).

OBS RBAC use case

Bucket accessible only by specific IAM user groups

To implement this use case, IAM user with “OBS Bucket Manager” will create the bucket “obs-test-rbac-group-1” and create a custom IAM policy allowing read and write on all object in the bucket

JSON custom IAM policy related to bucket "obs-test-rbac-group-1"

{
    "Version": "1.1",
    "Statement": [
        {
            "Action": [
                "OBS:*:*"
            ],
            "Resource": [
                "OBS:*:*:bucket:obs-test-rbac-group-1",
                "OBS:*:*:object:obs-test-rbac-group-1/*"
            ],
            "Effect": "Allow"
        }
    ]
}

This custom policy can then be associated with the IAM group which is supposed to have read and write permission on all object inside this bucket.

IAM users in groups associated with “OBS Buckets Viewer” or “OBS Buckets Viewer Enhanced” policies will only be able to list the bucket without read and write access to the objects inside.

Bucket accessible only by specific IAM user

To implement this use case, IAM user with “OBS Bucket Manager” will create the bucket “obs-test-rbac-user-1” and configure the following custom bucket policies:

Custom policy which applies on the bucket :

Policy mode

Customized

Effect

Allow

Principal

Include

Account ID

current account ID

User ID

user ID of the IAM user

Resources

Include

Entire Bucket

Resource Name

 

Actions

Include
Action Name *
Condition  

Custom policy which applies on objects in the bucket:

Policy mode

Customized

Effect

Allow

Principal

Include

Account ID

current account ID

User ID

user ID of the IAM user

Resources

Include

Specific resources

Resource Name

*

Actions

Include
Action Name *
Condition  

 

Custom policy which applies on the bucket and on objects in the bucket:

JSON custom bucket policy associated to bucket "obs-test-rbac-user-1"  

{
   "Statement":[
      {
         "Sid":"CustomBucketPolicy1",
         "Effect":"Allow",
         "Principal":{
            "ID":[
               "domain/<domainID>:user/<userID>"
            ]
         },
         "Action":[
            "*"
         ],
         "Resource":[
            "obs-test-rbac-user-1",
            "obs-test-rbac-user-1/*"
         ]
      }
   ]
}

IAM user in groups associated with “OBS Buckets Viewer” or “OBS Buckets Viewer Enhanced” policies will only be able to list the bucket without read and write access to the objects inside.

Bucket accessible by IAM users from third party domain/account

To implement this use case we can use Bucket ACL (Add):

 
Account

Access to Bucket

Access to ACL

third party account ID

☒ Read

☒ Write

☒ Read

☐ Write

Any IAM user from third party accound ID associated with a group allowing access to OBS service is allowed will have access to the bucket.

Sharing object from private bucket through a public link valid for a limited time

Any object in any bucket can be shared using a public link valid for a limited time.

From OBS console :

  • In the bucket list, click the bucket you want to operate. The overview page of the bucket is displayed.
  • In the navigation pane, click “Objects”.
  • In the “Operation” column of the file to be shared, choose “More” > “Download As”.
  • Right-click the download link and choose “Save link as…”.

Once a temporary URL is generated, it takes effect and has a validity period of 900s. Within the validity period, anyone can use this temporary URL to access the shared file.

You can also use OBS API to generate temporary URL. More info can be found on this page.

Bucket accessible only from one specific VPC with no access from internet or console

To implement this use case, a VPC EndPoint (VPCEP) named “eu-west-0.honey.v4.obsv2.lz02” should be deployed in the VPC from which the bucket will be accessed.

More information about how to deploy a VPC EndPoint can be found in this page.

This will allow a trusted VPC ID Header to be included in all HTTP/HTTPS request to OBS API.

In order to restrict the accessibility of a bucket to the VPC in which “eu-west-0.honey.v4.obsv2.lz02” VPCEP has been deployed , custom bucket policies with a “SourceVPC” condition with VPC ID must be associated to the bucket.

Custom policy which applies on the bucket:

Policy mode

Customized

Effect

Deny

Principal

Include

Account ID

*

User ID

 

Resources

Include

Entire Bucket

Resource Name

 

Actions

Include
Action Name *
Condition

Conditional Operator

Key

Value

StringNotEquals

SourceVpc

VPC ID

 

Custom policy which applies on objects in the bucket:

Policy mode

Customized

Effect

Deny

Principal

Include

Account ID

*

User ID

 

Resources

Include

Specific resources

Resource Name

*

Actions

Include
Action Name *
Condition

Conditional Operator

Key

Value

StringNotEquals

SourceVpc

VPC ID

Custom policy which applies on the bucket and on objects in the bucket:

JSON custom bucket policy associated to bucket "obs-test-rbac-no-internet-1"

{
   "Statement":[
      {
         "Sid":"CustomBucketPolicy2",
         "Effect":"Deny",
         "Principal":{
            "ID":[
               "*"
            ]
         },
         "Action":[
            "*"
         ],
         "Resource":[
            "obs-test-rbac-no-internet-1",
            "obs-test-rbac-no-internet-1/*"
         ],
         "Condition":{
            "StringNotEquals":{
               "SourceVpc":[
                  "<VPCID>"
               ]
            }
         }
      }
   ]
}

Once this custom bucket policy is in place, the bucket and the objects in the bucket can be accessed by any authorised IAM user from the specified VPC ID (ECS, BMS, CCE) only.

Also note that as this is an explicit deny, it will override IAM policy allowing access. Meaning IAM authorized user accessing from outside the specified VPC won’t be allowed.

Warning : with such policies the bucket will not be accessible anymore from FE console !

This custom bucket policy can be combined with other custom bucket policy or custom IAM policy to restrict this access to an IAM users or an IAM group.

More information about this use case can be found on this https://docs.prod-cloud-ocb.orange-business.com/usermanual/obs/obs_03_0384.html.

Bucket accessible only from a specific list of VPCs with no access from internet or console

To implement this use case, a VPC EndPoint (VPCEP) named “eu-west-0.honey.v4.obsv2.lz02” should be deployed in the each VPC from which the bucket will be accessed.

More information about how to deploy a VPC EndPoint can be found in this page.

This will allow a trusted VPC ID Header to be included in all HTTP/HTTPS request to OBS API.

In order to restrict the accessibility of a bucket to the list of VPC in which “eu-west-0.honey.v4.obsv2.lz02” VPCEP has been deployed , we will need to use custom IAM policies.

The first custom IAM policy is used to forbid access to the bucket if it’s not accessed from the list of authorized VPCs using a condition “StringNotEqualsAnyOf” associated with the list of VPCs.

This custom IAM policy will need to be associated to all IAM user groups except the default “admin” group.

JSON custom IAM policy OBS Read Write obs-test-rbac-no-internet-Deny
{
    "Version": "1.1",
    "Statement": [
        {
            "Condition": {
                "StringNotEqualsAnyOf": {
                    "obs:SourceVpc": [
                        "<VPCID>",
                        "<VPCID>"
                    ]
                }
            },
            "Action": [
                "obs:object:GetObjectVersionAcl",
                "obs:object:GetObjectAcl",
                "obs:object:ListMultipartUploadParts",
                "obs:object:GetObject",
                "obs:object:GetObjectVersion",
                "obs:bucket:PutBucketCORS",
                "obs:object:DeleteObjectVersion",
                "obs:bucket:PutEncryptionConfiguration",
                "obs:bucket:PutLifecycleConfiguration",
                "obs:bucket:DeleteReplicationConfiguration",
                "obs:bucket:PutBucketTagging",
                "obs:bucket:DeleteBucketInventoryConfiguration",
                "obs:object:DeleteObject",
                "obs:bucket:PutBucketNotification",
                "obs:object:ModifyObjectMetaData",
                "obs:bucket:DeleteBucketWebsite",
                "obs:bucket:PutBucketLogging",
                "obs:bucket:DeleteBucketTagging",
                "obs:object:RestoreObject",
                "obs:bucket:PutReplicationConfiguration",
                "obs:bucket:PutBucketQuota",
                "obs:bucket:PutBucketVersioning",
                "obs:bucket:CreateBucket",
                "obs:object:PutObject",
                "obs:bucket:DeleteBucket",
                "obs:bucket:DeleteDirectColdAccessConfiguration",
                "obs:bucket:PutBucketInventoryConfiguration",
                "obs:bucket:PutBucketWebsite",
                "obs:bucket:DeleteBucketCustomDomainConfiguration",
                "obs:object:AbortMultipartUpload",
                "obs:bucket:PutBucketCustomDomainConfiguration",
                "obs:bucket:PutDirectColdAccessConfiguration",
                "obs:bucket:PutBucketStoragePolicy",
                "obs:bucket:PutBucketPolicy",
                "obs:bucket:DeleteBucketPolicy",
                "obs:object:PutObjectAcl",
                "obs:bucket:PutBucketAcl",
                "obs:object:PutObjectVersionAcl",
                "obs:bucket:ListBucket",
                "obs:bucket:ListBucketMultipartUploads"
            ],
            "Resource": [
                "OBS:*:*:bucket:obs-test-rbac-no-internet-2",
                "OBS:*:*:object:obs-test-rbac-no-internet-2:*"
            ],
            "Effect": "Deny"
        }
    ]
}

The second custom IAM policy is used to authorize the access to the bucket.

This custom IAM policy will need to be associated to the IAM user group which contains IAM users authorized to access the bucket.

JSON custom IAM policy OBS Read Write obs-test-rbac-no-internet-Allow
{
    "Version": "1.1",
    "Statement": [
        {
            "Action": [
                "obs:bucket:HeadBucket",
                "obs:bucket:ListBucket",
                "obs:bucket:ListBucketMultipartUploads",
                "obs:bucket:PutBucketPolicy",
                "obs:bucket:DeleteBucketPolicy",
                "obs:object:PutObjectAcl",
                "obs:bucket:PutBucketAcl",
                "obs:object:PutObjectVersionAcl",
                "obs:bucket:PutBucketCORS",
                "obs:object:DeleteObjectVersion",
                "obs:bucket:PutEncryptionConfiguration",
                "obs:bucket:PutLifecycleConfiguration",
                "obs:bucket:DeleteReplicationConfiguration",
                "obs:bucket:PutBucketTagging",
                "obs:bucket:DeleteBucketInventoryConfiguration",
                "obs:object:DeleteObject",
                "obs:bucket:PutBucketNotification",
                "obs:object:ModifyObjectMetaData",
                "obs:bucket:DeleteBucketWebsite",
                "obs:bucket:PutBucketLogging",
                "obs:bucket:DeleteBucketTagging",
                "obs:object:RestoreObject",
                "obs:bucket:PutReplicationConfiguration",
                "obs:bucket:PutBucketQuota",
                "obs:bucket:PutBucketVersioning",
                "obs:bucket:CreateBucket",
                "obs:object:PutObject",
                "obs:bucket:DeleteBucket",
                "obs:bucket:DeleteDirectColdAccessConfiguration",
                "obs:bucket:PutBucketInventoryConfiguration",
                "obs:bucket:PutBucketWebsite",
                "obs:bucket:DeleteBucketCustomDomainConfiguration",
                "obs:object:AbortMultipartUpload",
                "obs:bucket:PutBucketCustomDomainConfiguration",
                "obs:bucket:PutDirectColdAccessConfiguration",
                "obs:bucket:PutBucketStoragePolicy",
                "obs:bucket:GetBucketStorage",
                "obs:bucket:GetBucketQuota",
                "obs:bucket:GetBucketTagging",
                "obs:object:GetObjectVersionAcl",
                "obs:bucket:GetBucketCustomDomainConfiguration",
                "obs:bucket:GetBucketCORS",
                "obs:object:GetObjectAcl",
                "obs:bucket:GetLifecycleConfiguration",
                "obs:bucket:GetDirectColdAccessConfiguration",
                "obs:bucket:GetBucketLogging",
                "obs:bucket:GetBucketInventoryConfiguration",
                "obs:object:ListMultipartUploadParts",
                "obs:bucket:GetReplicationConfiguration",
                "obs:bucket:ListBucketVersions",
                "obs:bucket:GetBucketStoragePolicy",
                "obs:bucket:GetBucketPolicy",
                "obs:object:GetObject",
                "obs:bucket:GetBucketNotification",
                "obs:bucket:GetBucketAcl",
                "obs:bucket:GetBucketWebsite",
                "obs:object:GetObjectVersion",
                "obs:bucket:GetEncryptionConfiguration",
                "obs:bucket:GetBucketLocation",
                "obs:bucket:GetBucketVersioning"
            ],
            "Resource": [
                "OBS:*:*:bucket:obs-test-rbac-no-internet-2",
                "OBS:*:*:object:obs-test-rbac-no-internet-2:*"
            ],
            "Effect": "Allow"
        }
    ]
}

Once those custom IAM policy are in place, the bucket and the objects in the bucket can be accessed only by IAM user in autorized IAM user group from the specified VPCs (ECS, BMS, CCE).

Only IAM users in the default “admin” group can access the bucket from outside the specified VPCs.

To forbid the access to IAM user in the default “admin” group, custom bucket policies with explicit deny can be added to the bucket:

JSON custom bucket policy associated to bucket "obs-test-rbac-no-internet-2"
{
   "Statement":[
      {
         "Sid":"CustomBucketPolicy3",
         "Effect":"Deny",
         "Principal":{
            "ID":[
               "domain/<domainID>:user/<userID>"
            ]
         },
         "Action":[
            "*"
         ],
         "Resource":[
            "obs-test-rbac-no-internet-2",
            "obs-test-rbac-no-internet-2/*"
         ]
      }
   ]
}