How to share private container from object storage to another user

You can create your own private containers in Object Store of your projects and you can grant access to other users.

If you want to limit the access for chosen users to specific containers, the other users have to be the members of other projects (it is recommended one user or group of users per one project).

The project can be in one or more domains.

Otherwise, if the users are members of the same project, they see all containers in that project and you cannot limit access to specific containers.

Prerequisites

No. 1 Hosting

You need a Destination Earth hosting account with Horizon interface https://cloud.central.data.destination-earth.eu.

No. 2 OpenStack client installed and connected to the cloud

The following article will help you install Python and OpenStack client called openstack and will also help you connect to the cloud How to install OpenStackClient for Linux.

No. 3 Knowledge of downloading and working with RC files

To be able to share private containers, you will have to manipulate RC files from the cloud. The following article will provide technical details:

How to activate OpenStack CLI access to the cloud.

No. 4. Using OpenStack Swift module

The OpenStack Object Store module, known as Swift, allows you to store and retrieve data with a simple API. It’s built for scale and is optimized for durability, availability, and concurrency across the entire data set. Swift is ideal for storing unstructured data that can grow without bound.

Assuming that the openstack command is fully operational, install swift module:

$ pip install python-swiftclient # install python swift client

Read more about OpenStack Swift commands here.

Setting up the test example

In the example below there are three projects:

  1. “main”,

  2. “project_1”,

  3. “project_2”.

../_images/projects1.png

… and three users:

  1. “owner” - the user with member role in project “main”,

  2. “user_1” - the user with member role in project “project_1”,

  3. “user_2” - the user with member role in project “project_2”.

../_images/users1.png

The user “owner” has three containers in their project “main”…

  1. c-main-a,

  2. c-main-b,

  3. c-main-d.

../_images/owner_con1.png

…and the following files in the containers:

  • 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 the example below the user “owner” will grant “read only” access to container “c-main-a” for “user_1”

Download the RC file to share permissions with users

Firstly, the user “owner” should login to their domain if they didn’t do it yet:

../_images/owner_login1.png

Then, they should choose the main project:

../_images/owner_main1.png

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

../_images/owner_rc1.png

Note

We shall assume the simplest case in which all three users have access to the cloud with one-factor authentication. If two-factor authentication is enabled, then the owner will have to share the six-digit code that is needed for the second factor of authentication.

You can preview the content of that file in your Linux terminal:

$ cat main-openrc.sh

main-openrc.sh

#!/usr/bin/env bash
# To use an OpenStack cloud you need to authenticate against the Identity
# service named keystone, which returns a **Token** and **Service Catalog**.
# The catalog contains the endpoints for all services the user/tenant has
# access to - such as Compute, Image Service, Identity, Object Storage, Block
# Storage, and Networking (code-named nova, glance, keystone, swift,
# cinder, and neutron).
#
# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
# OpenStack API is version 3. For example, your cloud provider may implement
# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
# only for the Identity API served through keystone.
# unset all currently exported openstack-related environment variables
for var in $(env | sed -n 's/^\(OS.*\)=.*/\1/p'); do unset "$var"; done
export OS_AUTH_URL=https://keystone.cloud.central.data.destination-earth.eu:443/v3
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3
export OS_USERNAME="[email protected]"
export OS_REGION_NAME="DEDL-CENTRAL"
export OS_PROJECT_ID=1db78cc344984e555238a3aee4665b32
export OS_PROJECT_NAME="cloud_username_1"
export OS_PROJECT_DOMAIN_ID="e314c4bfc53b47103fc9bccdf65ca9d7"
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
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
export OS_CLIENT_ID=openstack
export OS_CLIENT_SECRET=IOErV5G54xJdEWZxga4VbJzzOfZ7BXkF
export OS_PROTOCOL=openid
export OS_IDENTITY_PROVIDER=dedl_openid_provider
export OS_AUTH_TYPE=v3oidcpassword
export OS_DISCOVERY_ENDPOINT="https://identity.data.destination-earth.eu/auth/realms/dedl/.well-known/openid-configuration"

Note

The data in the above code have been altered for privacy reasons.

Sharing the RC file with the users

Copy the file main-openrc.sh to your CLI directory.

The user called “user_1” should do the same procedure:

  1. login to their “project_1”

  2. download the “OpenStack RC File” for user “user_1” and project “project_1”

project_1-openrc.sh

#!/usr/bin/env bash
# To use an OpenStack cloud you need to authenticate against the Identity
# service named keystone, which returns a **Token** and **Service Catalog**.
# The catalog contains the endpoints for all services the user/tenant has
# access to - such as Compute, Image Service, Identity, Object Storage, Block
# Storage, and Networking (code-named nova, glance, keystone, swift,
# cinder, and neutron).
#
# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
# OpenStack API is version 3. For example, your cloud provider may implement
# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
# only for the Identity API served through keystone.
# unset all currently exported openstack-related environment variables
for var in $(env | sed -n 's/^\(OS.*\)=.*/\1/p'); do unset "$var"; done
export OS_AUTH_URL=https://keystone.cloud.central.data.destination-earth.eu:443/v3
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3
export OS_USERNAME="[email protected]"
export OS_REGION_NAME="DEDL-CENTRAL"
export OS_PROJECT_ID=1db78cc344984e555238a3aee4665b35
export OS_PROJECT_NAME="cloud_username2_1"
export OS_PROJECT_DOMAIN_ID="g27894bjk54d12503fc9bccdf65ca9d7"
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
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
export OS_CLIENT_ID=openstack
export OS_CLIENT_SECRET=BGErV5G54IOKGFt56ujh3VbJzzOfZ7BXkF
export OS_PROTOCOL=openid
export OS_IDENTITY_PROVIDER=dedl_openid_provider
export OS_AUTH_TYPE=v3oidcpassword
export OS_DISCOVERY_ENDPOINT="https://identity.data.destination-earth.eu/auth/realms/dedl/.well-known/openid-configuration"

“user_2” should perform the same procedure as above.

Owner sources the RC file

Now, each user should open their terminal and source the openrc file:

terminal of user “owner”

$ source main-openrc.sh
Please enter your OpenStack Password for project main as user owner:  <here enter the password for owner>

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

User_1 sources the RC file

terminal of user “user_1”:

$ source project_1-openrc.sh
Please enter your OpenStack Password for project project_1 as user user_1:
 <here enter the password for user_1>

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

User_2 sources the RC file

terminal of user “user_2”:

$ source project_2-openrc.sh
Please enter your OpenStack Password for project project_2 as user user_2: <here enter the password for user_2>

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

Uploading of test files

The user “owner” prepares and uploads test files:

(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_01.png
(owner) $ touch test-main-b.txt
(owner) $ touch test-main-d.txt
(owner) $ swift upload c-main-b test-main-b.txt
test-main-b.txt
../_images/owner_upload_11.png
(owner) $ swift upload c-main-d test-main-d.txt
test-main-d.txt
../_images/owner_upload_11.png

Check the id of user_1:

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

Check the id of user_2:

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

You can check the status of the container “c-main-a”.

“Read ACL” and “Write ACL” are not set yet

(owner) $ swift stat c-main-a
                     Account: v1
                   Container: c-main-a
                     Objects: 2
                       Bytes: 29
                    Read ACL: *:3de5f40b4e6d433792ac387896729ec8
                   Write ACL: *:3de5f40b4e6d433792ac387896729ec8
                     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

Granting access

Grant access to container “c-main-a” for user_1:

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

Get the credentials to access Object Store in “main”:

(owner) $ swift auth | awk -F = '/OS_STORAGE_URL/ {print $2}'
https://s3.central.data.destination-earth.eu/swift/v1

Pass the link:

to “user_1”

“user_1” should create an environmental variable “SURL”

(user_1) $ SURL=https://s3.central.data.destination-earth.eu/swift/v1

Now the “user_1” has access to the “c-main-a” container in the “main” project:

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

But the user “user_1” has no access to other containers in the “main” project:

(user_1) $ swift --os-storage-url="${SURL}" list c-main-b
Container GET failed: https://s3.central.data.destination-earth.eu/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

Similar procedure can be used to grant “write” permission to “user_1”:

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

What To Do Next

These articles can also be of interest:

How to use Object Storage.

Bucket sharing using s3 bucket policy