Permissions

Toolkit permissions are fairly complex. It’s best to start with reading the Entities and Policy Taxonomy sections. Then you can either read on with the Policies Explained, if you prefer formal documentation, or move to Permission Scenario if you prefer learning through examples. You can also view the Tips section at the end of the page.

Entities

Type

Description

Organization

The top-level concept that pertains to permissions. The root of every Toolkit entity is an organization. By default, ServiceNow automatically get a user created under the snow organization. This is why their full name starts with snow..

User

An entity, uniquely identified via an email, that can authenticate in the system via various authentication methods including email/password, single sign-on and tokens. In Toolkit, aside from default permissions on user creation, permissions are provided via the concept of roles.

Account

The children entities of organizations. They can be subspaced. Their children are roles. Subspaced accounts, data, jobs and registries are tied to accounts.

Role

Live under accounts. They associate users to policies.

Policy

A rule that gives rights over Toolkit resources.

Data

A Toolkit data storage.

Job

A task running inside Toolkit.

Excluding policy, these concepts are resource types on which Toolkit policies can be applied.

All those entities have a matching CLI command.

Policy Taxonomy

  • Policy: <action>@<resource>.
    • action: (<action type>:<action verb>)|* A wildcard means all permissions on all resource types.

      • action type: user|account|role|policy|data|job|registry|* The wildcard means all of them.

      • action verb: get|set|new|*. The wildcard means all of them.
        • get: Read permission.

        • set: Write permission. In many situations, having a “set” permission alone is insufficient, to perform a write operation, because one can hardly write to things that can’t be seen. Hence, the “get” permissions may be needed.

        • new: Create permission.

    • resource: <organization id>:<resource type>:<resource id>[:<resource type>:<resource id>] It is possible to use wildcards. Eg.: snow:user:* means all users under the snow organization. snow:* means all entities under snow.

The taxonomy described here is the one supported by Toolkit. Policies are very liberal and it is possible to create policies unrelated to that taxonomy, as long as they are more or less of the form <left>@<right>. For instance, the following policy can be created but would have no inherent impact on Toolkit: potato@kitchen. However, user developped applications can look it up and take decisions based on it.

Note

There is no delete action. Toolkit resources are permanent.

Policies Explained

All Toolkit entities live in a hierarchy. At the top lives the organization concept. This one is only manageable by Toolkit administrators. Under organization live users and accounts. Under accounts live more accounts, roles, jobs, data and registries. Each of these instances live in a single account. Users can have multiple roles. Finally, policies are bound to roles.

../_images/tk_resources_hierarchy.png

Putting it all together, we have users who have roles. Their roles have policies <action>@<resource>. In plain English, we can say that those users can perform the action on the resource.

Policies are additive. The sum of the policies in the roles in which your user is makes up your permissions.

Shareable Policies

If you run a command that lists policies (eai user policy ls), you may notice there is a shareable column. A shareable policy is a policy that can be propagated by those to which it applies. They can propagate it by running the usual eai role policy new command, which creates the new policy.

Policies created this way are still independent. Deleting the original one will not cascade delete the other ones.

Expirable Policies

When policies are created, an expiration can be set on them either at a target datetime with the --expiration flag or the --duration flag.

Expired policies are not pruned automatically. They are still listed, but don’t take effect.

Accounts, Roles and Policies

When an account is created, it automatically comes up with two roles: admin and user. The creator is automatically added to the admin role and has all permissions on the account and its sub resources. Those permissions are shareable by default. Example.:

eai role policy ls snow.account:demo.admin

policy                               action expression                                                                          shareable expiration
18438923-0ead-4dbe-a62a-7bd6309faa35 *      34545543-8382-4437-a68b-18414701dec2:account:69321629-0990-4072-83c5-ed1050464df1:* true      -
18438923-0ead-4dbe-a62a-7bd6309faa35 *      34545543-8382-4437-a68b-18414701dec2:account:69321629-0990-4072-83c5-ed1050464df1   true      -

We see that this role gives all permissions, as denoted by the * under action on the account itself (the 2nd line) and all resources under it (the 1st line, the expression ending with :*).

No users are added to the user role. It’s automatically created for convenience with get (read) permission on the account itself and its sub resources. Those permissions are not shareable by default. Here is an example of its default policies:

eai role policy ls snow.account:demo.user
policy                               action expression                                                                          shareable expiration
18438923-81f3-4b08-8561-8e56c2ee37a6 *:get  34545543-8382-4437-a68b-18414701dec2:account:69321629-0990-4072-83c5-ed1050464df1:* false     -
18438923-81f3-4b08-8561-8e56c2ee37a6 *:get  34545543-8382-4437-a68b-18414701dec2:account:69321629-0990-4072-83c5-ed1050464df1   false     -

We see that this role gives get permissions, as denoted by the *:get under action on the account itself (the 2nd line) and all resources under it (the 1st line, the expression ending with :*).

Warning

When a user is created, it automatically gets an associated account. These accounts are special. They don’t start with any roles in them. They are bound to their owner and Toolkit internals grants their owner all the permissions over these accounts. To use them, it’s best to create sub accounts, into which the regular admin and user roles will be created and where users will be able to adjust policies.

To view the policies tied to your user, run eai user policy ls.

Multiple Rules Under the Same Policy ID

The command to create policies allows for the creation of many rules at once. In this case, they will all live under the same policy id but be listed as different rules for readability. Example.:

$ # because URNs tend to be very long, this example first export it to a variable to make the command more succint.
$ export URN=34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546
$ eai role policy new snow.account:patate.admin data:get@$URN data:set@$URN
id                                   name statements.actions statements.resources                                                                                                          shareable expiration
54435345-15b7-453f-94d3-9d26f373c073      [data:get]         [34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546] false     -
54435345-15b7-453f-94d3-9d26f373c073      [data:set]         [34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546] false     -

$ eai role policy ls snow.account:patate.admin
policy                               action   expression                                                                                                                  shareable expiration
54435345-15b7-453f-94d3-9d26f373c073 data:get 34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546 false     -
54435345-15b7-453f-94d3-9d26f373c073 data:set 34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546 false     -

In the previous example, two policies were explicitly created within the same command. For convenience, an advanced syntax that does the cartesian product on the action and resource parts of the policy is applied. Each action and resource need to be split with a + character. Here is an example where the equivalent policies as above are created. Notice how the immediate reply from the policy creation command differs.

$ eai role policy new snow.account:patate.admin "data:get+data:set@$URN"
id                                   name statements.actions  statements.resources                                                                                                          shareable expiration
54334523-da26-4017-b75f-dc5abf350f4c      [data:get data:set] [34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546] false     -

$ eai role policy ls snow.account:patate.admin
policy                               action   expression                                                                                                                  shareable expiration
54334523-da26-4017-b75f-dc5abf350f4c data:get 34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546 false     -
54334523-da26-4017-b75f-dc5abf350f4c data:set 34545543-8382-4437-a68b-18414701dec2:account:3e441dbe-ec2a-46d4-98bb-968d9f1e3c85:data:d6404ee5-2b69-4284-ad16-cec8d75ea546 false     -

Warning

The pitfall with these policies is that, even though they are listed over many lines, they are the same policy. Quickly looking at the previous example, someone may want to remove the data:set permission, run the removal command on the policy id, and end up deleting data:get as well because they were bound to the same policy.

Default Policies of the snow Organization

Warning

This is about users joining the snow organization. Users joining other organizations may get different policies.

Default policies are created when users are added to organizations. For snow, there are three of them.

1. Policies affecting the user

  1. The user:set policy is created, having both the user as the source and target, allowing the user to set the associated name.

  2. A policy is created to allow the user to do anything in the associated account.

Example:

% eai user policy ls
policy                               action   expression
12312312-ff56-404b-b320-c7cbaf0abe38 user:set 89089089-8382-4437-a68b-18414701dec2:user:12312312-c35f-4ce8-882a-dd289889bd5d
56756756-a4b3-41c0-96de-a328f2f558a7 *        89089089-8382-4437-a68b-18414701dec2:account:23423434-1714-46b8-90f5-4b3a2afaac5c
56756756-a4b3-41c0-96de-a328f2f558a7 *        89089089-8382-4437-a68b-18414701dec2:account:23423434-1714-46b8-90f5-4b3a2afaac5c:*

2. snow.user role

The user is added to the snow.user role. This gives the permission to get the organization (last policy in the example), to create a new account (the second to last in the example), and to get different types of resources under the organization except listing them.

Example:

$ eai role policy ls snow.user
policy                               action      expression
53409845-9fc0-47d7-b476-0cf7c688adc6 *:get       89089089-8382-4437-a68b-18414701dec2:registry:*
54321981-7080-41e2-86ef-a4c20cbb7759 *:get       89089089-8382-4437-a68b-18414701dec2:policy:*
18930147-f7a9-4cc2-b534-de7ead4619d5 *:get       89089089-8382-4437-a68b-18414701dec2:role:*
12386798-5477-483b-977f-a8eecee1973e *:get       89089089-8382-4437-a68b-18414701dec2:team:*
12389876-aea6-46bb-8bb2-664e93f0dc48 *:get       89089089-8382-4437-a68b-18414701dec2:user:*
84781457-4e21-4faa-a074-886b8f6aeba3 account:new 89089089-8382-4437-a68b-18414701dec2
87774466-2d2f-4dca-9a6e-f1c7a4d7749e *:get       89089089-8382-4437-a68b-18414701dec2

Note

registry:* and policy:* are Toolkit bugs and don’t do anything.

3. snow.everyone role

The user is added to the snow.everyone team. This group is intended to let Toolkit users openly share resources with the whole organization. Anyone willing to share resources with the organization is welcome to create the proper policies between that team and those resources.

Hint

A convenient way to share resources with the snow.everyone team is to create an account for yourself and that purpose. (e.g.: snow.alice.shared) Then you can add snow.everyone to that account user role. (Following the same example, that would be snow.alice.shared.user.)

Examples

To make the commands simpler, IDs are represented as ${<TYPE>_ID}.

1. Allowing a Role to Connect to A Job

eai role policy new snow.account_a.role_r job:get@${ORG_ID}:account:${ACCOUNT_ID}:job:${JOB_ID}

Users in the snow.account_a.role_r can connect (get permission) to the job ${ORG_ID}:account:${ACCOUNT_ID}:job:${JOB_ID}.

You can also use the eai cli to substitute the URN.

eai role policy new snow.account_a.role_r job:get@$(eai job get ${JOB_ID} --field urn)

Hint

This later notation will be used for the following examples.

2. Allowing a Role to Pull Docker Images from a Registry

eai role policy new snow.account_a.role_r registry:get@$(eai account get org.account_b --field urn)

3. Allowing a Role to Read from a Data

eai role policy new snow.account_a.role_r data:get@$(eai account get org.account_b.data_d --field urn)

Permission Scenario

The following series of scenarios will illustrate some of the most fundamental concepts behind the Toolkit. We will start with the addition of a new organization to the toolkit, and make our way step by step to project shared by multiple user profiles who each have different levels of permission accesses.

Step 0: A new organization is created

This step can only be taken by a Toolkit superadmin. It creates the root object for your organization. It will also create two children roles under the organization:

  1. role admin

  2. role user

The Tookit superadmin is automatically assigned to the role admin for the new organization. This is transferable later on to the administrator in the organization. When a user is assigned a role, we say that the user becomes a member of that role.

../_images/step0.png

Step 1: A first user is added to the organization

A user is a resource that can be added as a child to an organization or as a member to a team (more on teams later). Only users with the role of admin on the organization can invite new users. In our scenario, since the EAI_superadmin is still the only administrator for the acme organization, he or she will have to invite a new user from that organization. This is done with the eai user invite command. To add a new user to an organization, all that is needed is an email address.

eai user invite <mail@domain> --organization <organization>

Adding a user to the organization results in a few things happening:

  1. The user is added as a child to the organization and as a member of the user role for that organization. Or it can be renamed thereafter with the command $ eai user set <user id> --name <new name>

  2. A “sandbox” account is added as a child to the organization.

  3. The user will be granted all set and get permissions on that “sandbox” account. This is the user personal account. It can be renamed afterward through $ eai account set <account id> --name <new name>

For the purpose of our scenario, we have added the user alice and named her sandbox account alice_sandbox. Everything is ready for Alice to start using the toolkit, except that she hasn’t logged in yet… Let’s have her login.

../_images/step1.png

Step 2: Starting new project(s)

Alice is now ready to start setting up new projects. On the toolkit, the concepts of “project” and “account” are completely interchangeable. The terminology account was chosen to make it explicit that the use of resources on the toolkit (jobs, services, data, etc.) will be recorded by account.

Alice is about to kick off work on two separate projects, one is for a publication and another one is a proof-of-concept (POC) for a client. She opts to create two new accounts under her account sandbox_account.

eai account new acme.alice_sandbox.publication
eai account new acme.alice_sandbox.poc

Note that objects on the toolkit can be referenced by their 36-character UUID or by the name they have been assigned. To reference an object by its name, one must list all of its parents all the way up to the root. For instance, the reference for the admin role for the publication account below is acme.alice_sandbox.publication.admin

../_images/step2.png

When an account is created, the two standard children roles are also created (admin and user) and the account creator is added as a member of the admin role. In our case, Alice is therefore added as an admin on both new accounts.

Alice can now start working with these accounts. She can:

  • Upload docker images to her accounts ($ eai docker -h)

  • Upload data ($ eai data -h)

  • Run jobs ($ eai job -h)

  • and a lot more.

For most commands, she can specify under which account she is launching the operation. If the flag is not specified, it will take her sandbox account as default.

Note

Accounts can be subspaced. In the current scenario, acme.alice_sandbox, acme.alice_sandbox.publication acme.alice_sandbox.poc are all valid accounts.

For the time being, we will assume Alice knows how to perform all these operations and will move on to how to set up an account that is to be shared with other users.

Step 3: Add another user as a collaborator user on an account

For this step, let’s assume that Bob has been added as a new user to the organization. The organization now holds two users: Alice and Bob. Alice would really like some of Bob’s help with the experiments she is running for her paper publication. She decides to give Bob access to the acme.alice_sandbox.publication account. For that, she will need Bob’s user UUID (Bob can run $ eai user get), or the name he has assigned to his user object. (Bob can run $ eai user set --name bob).

Alice can add Bob as member of the user role of her account with $ eai role member add acme.alice_sandbox.publication.user --user acme.bob

The organization now looks like this (note that some objects such as acme.user and acme.admin are no longer illustrated for simplicity purposes)

../_images/step3.png

Bob can now perform a number of operations under the account acme.alice_sandbox.publication (e.g, download docker images, download data, etc.). By default, the user role for a new account is given get access to all resources. The exact set of permissions assigned to Bob for that account is defined by policies associated with the user role.

Step 4: Creating a team

After a few days, Alice realizes that she will need more help than expected with the experimentations for her paper publication. She decides to add one more user to the acme.alice_sandbox.publication account.

# But this time, she decides to do this through a team, that she is naming avengers.
eai team new acme.avengers

# She adds herself, Bob and Charlie to the team:
eai team member add acme.avengers --user acme.alice --user acme.bob --user acme.charlie

# To check that everyone was added properly to the team, Alice can run:
eai team member ls acme.avengers

# She can then add the team as a member of the user role on the account
eai role member add acme.alice_sandbox.publication.user --team acme.avengers
../_images/step4.png

While it is not depicted in the diagram above for simplicity, creating the team avenger also automatically created an account associated with the team (just like for when a new user is added to the organization). Therefore, the members of the team could, as an alternative, decide to collaborate by using the newly created account.

Step 5: Creating a guest role

Bob is also working on projects of his own. For one of these projects, that he has named account skunkworks, he wants to give other users visibility about what he is doing, but he definitely doesn’t want them to use the account to consume resources. He was granted a limited budget by his boss for this account and would hate for someone else to eat into this budget by running jobs…

First, Bob needs to add a new role to the skunkworks account and set get permissions for that guest role. Here, Bob is allowing guests to access information about jobs launched under the skunkworks account and about the data associated to that account as well. Note that set permissions are not provided, which means that guests won’t be able to launch jobs or overwrite any data under the skunkworks account.

ACCOUNT_URN=$(eai account get acme.skunkworks --field urn)
eai role new acme.skunkworks.guest --policy "*:get@${ACCOUNT_URN}:job:*+${ACCOUNT_URN}:data:*"

Note that we use a shell trick here to save the account URN in a variable to reuse it later.

Also, the + and @ sign combination allows for multiple resources expressions (and/or multiple actions) by applying a cartesian product between the list of actions (on the left of @) and the list of resources (on the right). For example, --policy a+b@c+d+e is equivalent to --policy a@c --policy a@d --policy a@e --policy b@c --policy b@d --policy b@e.

Bob can now add members as guests to the account

eai role member add acme.skunkworks.guest --team acme.avengers
../_images/step5.png

Tips

  • To manage policies tied to a role, run eai role policy --help for more details.

  • To validate rules over resources, you can use eai rule --help. Consult the How To page to find example usages of that command.

  • The eai user policy ls command only lists policies tied to your user account, not all policies tied to all your accounts.