How to use permissions

How are managed access

What is the URN of a resource ?

Hint

Usage of URN is not required anymore as it is possible to use the resource ID or fullName instead of the URN.

The following explanation can be useful to understand how Toolkit works behind the scenes.

The EAI toolkit provides an API to manage access to resources. In addition to their ID, each resource is assigned an explicit URN that indicates its type and ownership. For example, a user is a kind of resource owned by an organization. Assuming you are already logged in, you can get the URN of your user with this:

$ eai user get --field urn
491e3474-8382-4437-a68b-18414701dec3:user:3c0e93a5-4174-4487-bbaa-59138ba24833

Here:

  • 491e3474-8382-4437-a68b-18414701dec2 is the organization and

  • 3c0e93a5-4174-4487-bbaa-59138ba24833 is the user.

How URN are used to build policy expression ?

URNs are useful to express access rules. An access rule simply defines actions allowed on a URN expression. Using the wildcard * character, a rule can refers to a set of resources. For example:

  • 491e3474-8382-4437-a68b-18414701dec2 refers to the organization

  • 491e3474-8382-4437-a68b-18414701dec2:* refers to all resources of the organization

  • 491e3474-8382-4437-a68b-18414701dec2:user:* refers to all users of the organization

Each client access is validated against a set of access rules. You can list your access rules:

$ eai user policy ls --recursive
action     expression
*:get      491e3474-8382-4437-a68b-18414701dec2
*:get      491e3474-8382-4437-a68b-18414701dec2:user:*
*:get      491e3474-8382-4437-a68b-18414701dec2:team:*
user:set   491e3474-8382-4437-a68b-18414701dec2:user:e44ce0fe-446d-4838-946b-9a61f886297b
data:get   491e3474-8382-4437-a68b-18414701dec2:account:3f0905b0-516c-4ac5-8b1f-f606770fc1cb:data:fe731f85-5d20-4bcf-986d-f458180b5000
data:read  491e3474-8382-4437-a68b-18414701dec2:account:3f0905b0-516c-4ac5-8b1f-f606770fc1cb:data:fe731f85-5d20-4bcf-986d-f458180b5000
data:write 491e3474-8382-4437-a68b-18414701dec2:account:3f0905b0-516c-4ac5-8b1f-f606770fc1cb:data:fe731f85-5d20-4bcf-986d-f458180b5000

Let’s go over those.

The first rule explicitly allows the user:set action on yourself. This action correspond to updating user details:

$ eai user set --name joe

The next 3 rules are inherited from the user role attached to your organization. When your user was created, it was authorized to assume the user role for your organization. This enables you to get details about your organization, its users and its teams. This correspond to a number of commands:

$ eai organization get
$ eai user ls
$ eai team ls

How the expression based on URN is replaced ?

Expressions based on the URN are now replaced by 2 input fields to build the expression: - the resource used to build the expression - the cascade boolean to define if the expression is for the resource itself or all its children

Example of generated expression:

Resource

Cascade

Expression Generated

491e3474-8382-4437-a68b-18414701dec2

true

491e3474-8382-4437-a68b-18414701dec2:*

491e3474-8382-4437-a68b-18414701dec2

false

491e3474-8382-4437-a68b-18414701dec2

3c0e93a5-4174-4487-bbaa-59138ba24833

false

491e3474-8382-4437-a68b-18414701dec2:user:3c0e93a5-4174-4487-bbaa-59138ba24833

By doing that, it is now to return the fullName of the resource instead of the expression based on the URN. The previous example with eai user policy ls --recursive is now:

$ eai user policy ls --recursive
id                                   source target               action     resource                  cascades shareable expiration
1b14b003-5986-410a-afe5-856639ec4c14 direct snow.guillaume_smaha *:get      snow                      false    false      -
64d24c13-a9bb-46eb-af31-9ae9b3b71e61 direct snow.guillaume_smaha user:get   snow                      true     false      -
5b07426b-6fca-4ff1-9d51-e569fb78d263 direct snow.guillaume_smaha team:get   snow                      true     false      -
eb6a64e3-b817-4b3d-b0e7-dc25bf07ba60 direct snow.guillaume_smaha user:set   snow.guillaume_smaha      false    false      -
d5091fec-aa57-4faf-9d50-5e411c18e8f0 direct snow.guillaume_smaha data:get   snow.home.guillaume_smaha false    false     -
be113ba2-93a8-44a8-b297-e16d8b87b3f7 direct snow.guillaume_smaha data:read  snow.home.guillaume_smaha false    false     -
be113ba2-93a8-44a8-b297-e16d8b87b3f7 direct snow.guillaume_smaha data:write snow.home.guillaume_smaha false    false     -

Policies

Note

Previously, multiple access rules could be stored in one policy.

Now, rules are merged in policies and one policy is always one rule.

A policy is one statement that allow actions on resources, using syntax <action>@<resource>. Multiple actions and resources can still be defined with the syntaw <action>[+<action>...]@<resource>[+<resource>...], in this case, multiple policies will be created.

It can be attached to clients of the API i.e. users, teams and roles. For example, this explicitely gives root access to the cluster to a single user:

$ eai user policy new 3c0e93a5-4174-4487-bbaa-59138ba24833 '*@*'

Users inherit policies from:

  • policies attached to them

  • policies attached to a team they are a member of directly or indirectly

  • policies attached to a role they can assume

Thus, there is 3 ways to create policies:

$ eai user policy new
$ eai team policy new
$ eai role policy new

Note that adding policies to a user, a team or a role requires access to that resource.

Roles

While it is possible to manage access with policies attached directly to users and teams, the most common way is to use roles. If a user or a team is allowed to assume a role, it inherits the role’s policies. There are a number of roles that are predefined. Since they can be attached to organizations, teams and accounts, they can be listed using:

$ eai organization role ls
$ eai team role ls
$ eai account role ls

For example:

$ eai organization role ls --fields id,name
id                                   name
c53444c6-206e-4ae7-bab7-baacdab5a0a7 admin
e11bb1f4-b85a-4734-a5a4-f52cadd50ca6 user

To assume a role, a user or a team needs to be a member of that role. Thus, the following can be used to list members:

$ eai organization role member ls c53444c6-206e-4ae7-bab7-baacdab5a0a7
id                                   name      type
80db146b-1c79-4ed0-bb8b-db1698fddd58 jerome    user
94731f2a-aa48-443a-b013-c00ea9507d0f guillaume user
0eb96759-aef0-4acc-91a7-202cac71c472 eric      user

Simply use the add or rm commands to manager members:

$ eai organization role member rm c53444c6-206e-4ae7-bab7-baacdab5a0a7 --user 94731f2a-aa48-443a-b013-c00ea9507d0f
id                                   name      type
80db146b-1c79-4ed0-bb8b-db1698fddd58 jerome    user
0eb96759-aef0-4acc-91a7-202cac71c472 eric      user
$ eai organization role member add c53444c6-206e-4ae7-bab7-baacdab5a0a7 --user 94731f2a-aa48-443a-b013-c00ea9507d0f
id                                   name      type
80db146b-1c79-4ed0-bb8b-db1698fddd58 jerome    user
94731f2a-aa48-443a-b013-c00ea9507d0f guillaume user
0eb96759-aef0-4acc-91a7-202cac71c472 eric      user

How to access a python server in toolkit from a CICD

  1. Use a Python framework like FastAPI, Django or Flask to write a small API that does what you want

  2. Build a Docker image that expects to have the model data mounted and that runs the API. Example docker image can be found here

  3. Submit a Toolkit job in the account, with the image and the model data mounted. If you want a long running server (more than 48hrs), use restartable with high bid.

  4. Create a new role, policy and a key (token)

    # create a new role
    $ eai role new account_fullname.job_access
    
    # attach a policy which gives access to the python server
    $ eai role policy new account_fullname.job_access "job:get@$JOB_ID
    
    # create a long lived token to access the python server
    $ eai role key new account_fullname.job_access
    
  5. Use the token to call the API from anywhere (you can find the job’s accessUrl with the eai job info command)

How to Share Data With Other Users

Create Role

Let’s create a new role, named shared_my_data, where we will add policy for our data and where we will add member

Pattern : eai role new ORG.ACCOUNT.ROLE_NAME
eai role new acme.account.shared_my_data

id                                   name               organization    parent
a7202d30-4b45-479f-8b43-67cfe6214e11 shared_my_data     acme            acme.account

Create Policy

A policy is an action on a resource

Here is the pattern of policy creation:

eai role policy new ROLE_ID  ‘action@resource’

In our example, we want to give full access to our data, so the action will be : data:* and the resource the previous URN we get.

If you want to give a specific access, see the Permissions table.

Pattern : eai role policy ROLE_ID `action@resource`
with :
    ROLE_ID : the id returned by eai role new
    action : data:*
    resource : resource ID, fullName or, URN


eai role policy new a7202d30-4b45-479f-8b43-67cfe6214e11  'data:*@acme.account.shared_my_data'

Add member

Before adding a member to that role, we need to get the user ID of the user we want to add. You can find the user by typing the command :

eai user ls

Once you have the user id, you can add it as a member of that role.

Here is the expected pattern : eai role member add ROLE_ID –user USER_ID

eai role member add a7202d30-4b45-479f-8b43-67cfe6214e11 --user 60e9ca7a-4808-50de-b612-3e0fe92db027

How to tell who has specific rights over a resource?

eai rule who-is-allowed <action>@<resource urn>

Who can write to a specific data object:

eai rule who-is-allowed "data:set@$(eai data get <data id> --field urn)"

How to tell if you have specific rights over a resource?

eai rule allowed <action>@<resource urn>

Whether you can write to a specific data object:

eai rule allowed "data:set@$(eai data get <data id> --field urn)"

How to Share

Sharing access to a resource means giving access to it. Here is 2 ways:

Share by Account

Start by creating one:

$ eai account new acme.joe.submarine

Then, allow users or teams to access this new account using the predefined roles. For example, add to the user role:

$ eai account role member ls acme.joe.submarine.user
$ eai account role member add acme.joe.submarine.user --user acme.alice
$ eai account role member add acme.job.submarine.user --team acme.cocos
$ eai account role member ls acme.joe.submarine.user --fields name,type
name  type
alice user
cocos team

Or add to the admin role:

$ eai account role member add acme.job.submarine.admin --user acme.bob

Share by Team

If a team was created for you by the Toolkit admin:

$ eai team new acme.cocos
# alice can now manage the members of the team
$ eai team role member add acme.cocos.admin --user acme.alice

You can manage the members of that team and have an easy way to spread the access to your different project’s account.

If 2 users are part of the same team:

$ eai team member add acme.cocos --user acme.bob
$ eai team member add acme.cocos --user acme.charlie

You can use this team as member of a role:

$ eai role member add acme.myprojectaccount.user --team acme.cocos
$ eai role member add acme.secondproject.user --team acme.cocos

Bob and Charlie have access to both account acme.myprojectaccount and acme.secondproject.

Adding David to the team will grant him access to both accounts too.

$ eai team member add acme.cocos --user acme.david

Team members can now access resources created under the acme.myprojectaccount or acme.secondproject account:

# Can be run by bob, charlie or, david:

# Set default account
$ eai user set --account acme.myprojectaccount

# Create a new data
$ eai data new acme.myprojectaccount.images

# Submit a job
$ eai job submit --data acme.myprojectaccount.images
$ eai job submit --data acme.myprojectaccount.images --account acme.secondproject