How to share a private object storage container with another user on CloudFerro Cloud

You can create private containers in Object Store and grant access to selected users.

If you want to limit access to specific containers, the other users should be members of other projects. A common pattern is to use one project per user or one project per group of users.

The project can be in one or more domains.

If users are members of the same project, they can see all containers in that project. In that case, you cannot limit their access to only one specific container.

Prerequisites

No. 1 Hosting account

You need a CloudFerro Cloud hosting account with access to the Horizon interface: https://portal.cloudferro.com/.

No. 2 OpenStackClient installed and connected to the cloud

You need OpenStackClient installed on your computer.

How to install OpenStackClient for Linux on CloudFerro Cloud

No. 3 Knowledge of downloading and using RC files

To share private containers, you need to work with OpenStack RC files downloaded from Horizon.

How to activate OpenStack CLI access to CloudFerro Cloud cloud using one- or two-factor authentication

No. 4 Knowledge of OpenStack Object Storage / Swift

The OpenStack Object Store service, also known as Swift, allows you to store and retrieve data through an API. It is designed for durability, availability, concurrency, and storing large amounts of unstructured data.

How to access object storage using OpenStack CLI on CloudFerro Cloud

Setting up the test example

In the example below, there are three projects:

  1. main

  2. project_1

  3. project_2

../_images/projects.png

There are also three users:

  1. owner – the user with the member role in project main.

  2. user_1 – the user with the member role in project project_1.

  3. user_2 – the user with the member role in project project_2.

../_images/users.png

The user owner has three containers in project main:

  1. c-main-a

  2. c-main-b

  3. c-main-d

../_images/owner_con.png

The containers contain the following files:

  • c-main-a

    • test-main-a1.txt

    • test-main-a2.txt

  • c-main-b

    • test-main-b.txt

  • c-main-d

    • test-main-d.txt

In this example, the user owner grants read-only access to container c-main-a for user_1.

Download the RC file for the owner project

First, the user owner signs in to Horizon:

../_images/owner_login.png

Then, they choose the main project:

../_images/owner_main.png

After that, they download the OpenStack RC File for user owner and project main:

../_images/owner_rc.png

Note

This article assumes the simplest case, where all three users access the cloud with one-factor authentication. If two-factor authentication is enabled, adjust the authentication workflow according to your environment.

You can preview the content of the RC file in a Linux terminal:

$ cat main-openrc.sh

Example main-openrc.sh file:

#!/usr/bin/env bash
unset OS_TENANT_ID
unset OS_TENANT_NAME
export OS_AUTH_URL=https://keystone.cloudferro.com:5000/v3
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3
export OS_USERNAME="owner"
export OS_REGION_NAME="WAW4-1"
export OS_PROJECT_ID=ab0c8e1710854b92b0be2b40b31a615a
export OS_PROJECT_NAME="main_project"
export OS_PROJECT_DOMAIN_ID="119f4676f307434eaf28daab5ba3cc92"
if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi
echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "
read -sr OS_PASSWORD_INPUT
export OS_PASSWORD=$OS_PASSWORD_INPUT
export OS_AUTH_TYPE=password
export OS_USER_DOMAIN_NAME="cloud_00373"

Note

If OS_USER_DOMAIN_NAME is missing from your RC file, add it according to your environment.

Download RC files for the receiving users

The user user_1 should follow the same procedure:

  1. Sign in to Horizon.

  2. Choose project project_1.

  3. Download the OpenStack RC File for user user_1 and project project_1.

Example project_1-openrc.sh file:

#!/usr/bin/env bash
unset OS_TENANT_ID
unset OS_TENANT_NAME
export OS_AUTH_URL=https://keystone.cloudferro.com:5000/v3
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3
export OS_USERNAME="user_1"
export OS_REGION_NAME="WAW4-1"
export OS_PROJECT_ID=4d488c376c0b4bc79a60b56bc72834e8
export OS_PROJECT_NAME="p_project_1"
export OS_PROJECT_DOMAIN_ID="119f4676f307434eaf28daab5ba3cc92"
if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi
echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "
read -sr OS_PASSWORD_INPUT
export OS_PASSWORD=$OS_PASSWORD_INPUT
export OS_AUTH_TYPE=password
export OS_USER_DOMAIN_NAME="cloud_00373"

The user user_2 should follow the same procedure for project project_2.

Source the RC files

Each user should open their terminal and source their own RC file.

For user owner:

$ source main-openrc.sh
Please enter your OpenStack Password for project main as user owner:

(owner) $ swift list
c-main-a
c-main-b
c-main-d

For user_1:

$ source project_1-openrc.sh
Please enter your OpenStack Password for project project_1 as user user_1:

(user_1) $ swift list
c-project_1-a
c-project_1-b

For user_2:

$ source project_2-openrc.sh
Please enter your OpenStack Password for project project_2 as user user_2:

(user_2) $ swift list
c-project_2-a
c-project_2-b

Upload test files

The user owner prepares and uploads test files.

Create and upload two files to c-main-a:

(owner) $ touch test-main-a1.txt
(owner) $ touch test-main-a2.txt
(owner) $ swift upload c-main-a test-main-a1.txt
test-main-a1.txt
(owner) $ swift upload c-main-a test-main-a2.txt
test-main-a2.txt
../_images/owner_upload_0.png

Create and upload one file to c-main-b:

(owner) $ touch test-main-b.txt
(owner) $ swift upload c-main-b test-main-b.txt
test-main-b.txt
../_images/owner_upload_1.png

Create and upload one file to c-main-d:

(owner) $ touch test-main-d.txt
(owner) $ swift upload c-main-d test-main-d.txt
test-main-d.txt
../_images/owner_upload_1.png

Find user IDs

To grant access, you need the user ID of the receiving user.

User user_1 checks their ID:

(user_1) $ openstack user show --format json "${OS_USERNAME}" | jq -r .id
3de5f40b4e6d433792ac387896729ec8

User user_2 checks their ID:

(user_2) $ openstack user show --format json "${OS_USERNAME}" | jq -r .id
fb4ec0de674d4c5ba608ee75cc6da918

Check the current container ACL

The owner can check the current status of container c-main-a:

(owner) $ swift stat c-main-a
                     Account: v1
                   Container: c-main-a
                     Objects: 2
                       Bytes: 29
                    Read ACL:
                   Write ACL:
                     Sync To:
                    Sync Key:
                 X-Timestamp: 1655199342.39064
X-Container-Bytes-Used-Actual: 8192
            X-Storage-Policy: default-placement
             X-Storage-Class: STANDARD
               Last-Modified: Tue, 14 Jun 2022 13:41:32 GMT
                  X-Trans-Id: tx000000000000003964e44-0062b17ebb-17404e6b-default
      X-Openstack-Request-Id: tx000000000000003964e44-0062b17ebb-17404e6b-default
               Accept-Ranges: bytes
                Content-Type: text/plain; charset=utf-8

In this example, Read ACL and Write ACL are not set yet.

Grant read access

Grant read access to container c-main-a for user_1. Replace the user ID with the value obtained for your user.

(owner) $ swift post --read-acl "*:3de5f40b4e6d433792ac387896729ec8" c-main-a

Get the Object Storage URL

The owner gets the Object Storage URL from their authenticated session:

(owner) $ swift auth | awk -F = '/OS_STORAGE_URL/ {print $2}'
https://s3.waw4-1.cloudferro.com/swift/v1

Pass the resulting URL to user_1.

For reference, the URL format is:

https://s3.waw4-1.cloudferro.com/swift/v1

Access the shared container as user_1

The user user_1 creates an environment variable named SURL.

(user_1) $ SURL=https://s3.waw4-1.cloudferro.com/swift/v1

Now user_1 can list the shared container c-main-a in the main project:

(user_1) $ swift --os-storage-url="${SURL}" list c-main-a
test-main-a1.txt
test-main-a2.txt

The user user_1 still has no access to other containers in the main project.

For example, listing c-main-b should fail:

(user_1) $ swift --os-storage-url="${SURL}" list c-main-b
Container GET failed: https://s3.waw4-1.cloudferro.com/swift/v1/c-main-b?format=json 403 Forbidden [first 60
chars of response] b'{"Code":"AccessDenied","BucketName":"c-main-b","RequestId":"'
Failed Transaction ID: tx00000000000000397edda-0062b186ef-17379d9b-default

Grant write access

A similar procedure can be used to grant write permission to user_1.

Replace the user ID with the value obtained for your user:

(owner) $ swift post --write-acl "*:3de5f40b4e6d433792ac387896729ec8" c-main-a

After this change, user_1 can upload or modify objects in c-main-a, depending on the permissions available in your environment.

What to do next

These articles may also be useful: