Basics of role based access control (RBAC)
Role-based access control is an access control mechanism defined around roles and privileges. This security model pivots around the concept or a Role. Users (called principals in Tachyon) can be assigned to a Role and it's through a Role they gain permissions to perform actions. Each element of Tachyon's security system leads back to a Role.
RBAC objects in Tachyon
Tachyon has several types of objects that are part of its RBAC system. This section serves as a brief description of these objects and their purpose.
Principals
Principals are identical to users. They're not called users because the word 'user' is traditionally associated with a person. A principal is, from a technical standpoint, an Active Directory account which may be a user account or a computer account. It can also be an AD group.
Tachyon allows access only to principals authenticated through Windows authentication and known to Tachyon itself. Depending on the request, Tachyon establishes the permissions of the calling principal by looking at the roles that principal is assigned to. By default, a fresh installation of Tachyon has a principal representing the user account installing it and another principal for the "NT AUTHORITY\Network Service", which many of Tachyon's services will be running as.
Roles
All permissions lead to roles. Principals must have roles assigned to them before using the system.
Permissions
A permission is an ability to perform an operation on a securable type.
Securable Types
A Securable Type represents a type of an object that can have permissions assigned to it. For example, Instructions can have permissions, as can Consumers and Management Groups. Security itself is an object principals need permissions to, so they can modify it, it will also have a Securable Type. If an element of Tachyon has security defined for it, it must have a securable type.
Instances
An Instance is one, specifc copy of an object of a given Securable Type. This can, for instance, be a single Instruction Set.
While most permissions work on Securable Types as a general thing, where if a Principal is assigned a Permission on a given Securable Type they can work with any object of that type, some Securable Types allow Permissions to be specified on just one given instance of a Securable Type object, giving a more granular control over access to that Securable Type.
As of version 5.0 only InstructionSet securable type supports instances.
Operations
An Operation (also called Applicable Operation) represents the type of an action that can be performed on a securable type, like "Read" or "Write".
Example how to read permissions
Marc (Principal) through his Global Questioners (Role) has Questioner (Applicable Operation) permission on Instructions (Securable type).
A Principal will have a specific permission on given securable type through a role the principal belongs to. This is the only way principals can obtain permissions and permissions are always for a specific operation on a given type.
To establish the full permission set of a given principal you have to combine all permissions from all the roles assigned to that principal.
Retrieving RBAC objects
In this section we will look at endpoints that allow you to examine existing RBAC objects.
Getting Principals
The most basic functionality is to retrieve all Principals:
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Principals will yield following response:
| Use Principals object inside the Tachyon connector instance.
"principals" object will contain the same data you can see in the JSON response on the left. |
Or just a single Principal by their Id. Here we'll look for "SomeDomain\\Jane.Doe", who in has the Id of 3:
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Principals/3 will yield following response:
| Use Principals object inside the Tachyon connector instance.
"principal" object will contain the same data you can see in the JSON response on the left. |
You can also retrieve all Principals that have a specific Role assigned to them. Here we'll get all Principals who are "Global Administrators", which has the Id of 1:
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Principals/Role/1 will yield following response:
| Use Principals object inside the Tachyon connector instance.
"principals" object will contain the same data you can see in the JSON response on the left. |
Getting Roles
Much like with Principals, you can retrieve all Roles in the system:
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Roles will yield following response:
| Use Roles object inside the Tachyon connector instance.
"roles" object will contain the same data you can see in the JSON response on the left. |
But unlike the Principals, roles also have an endpoint that supports filtering, sorting and paging. In the example below we'll look for custom roles and sort them by name.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/Roles/Search with following payload:
Yields following response:
| Use Roles object inside the Tachyon connector instance.
"searchResults" object will contain the same data you can see in the JSON response on the left. |
You can also retrieve a singel Role by its Id, here we'll retrieve the Global Administrators role which has the Id of 1.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Roles/1 will yield following response:
| Use Roles object inside the Tachyon connector instance.
"role" object will contain the same data you can see in the JSON response on the left. |
Lastly, we'll look at retrieving all Roles given Principal has assigned to them using that Principal's Id. Here we'll get all the Roles that "SomeDomain\Jane.Doe" has assigned and that Principal's Id is 3:
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Roles/Principal/3 will yield following response:
| Use Roles object inside the Tachyon connector instance.
"roles" object will contain the same data you can see in the JSON response on the left. |
Getting Securable Types
You can retrieve all Securable Types with following call:
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/SecurableTypes will yield following response:
| Use SecurableTypes object inside the Tachyon connector instance.
"secTypes" object will contain the same data you can see in the JSON response on the left. |
You can also retrieve a specific Securable Type by either its Name or Id.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
If you wish to use the Id, make a GET request to https://my.tachyon.server/Consumer/SecurableTypes/1 If you wish to use the Name instead, make a GET request to https://my.tachyon.server/Consumer/SecurableTypes/Name/InstructionSet Both yield following response:
| Use SecurableTypes object inside the Tachyon connector instance. To retrieve a Securable Type using its Id use:
To retrieve a Securable Type using its Name use:
"secType" object will contain the same data you can see in the JSON response on the left. |
Getting Applicable Operations
Applicable Operations work in the context of a Securable Type, which is why Tachyon allows you to retrieve all Applicable Operations for given Securable Type. You can use either Name or Id to specify which Securable Type you want Applicable Operations for.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
If you wish to use the Id, make a GET request to https://my.tachyon.server/Consumer/ ApplicableOperations/SecurableTypeId/1 If you wish to use the Name instead, make a GET request to https://my.tachyon.server/Consumer/ ApplicableOperations/SecurableType Name/InstructionSet Both yield the following response:
| Use ApplicableOperations object inside the Tachyon connector instance. To retrieve Applicable Operations for a Securable Type using the type's Id use:
To retrieve Applicable Operations for a Securable Type using the type's Name use:
"operations" object will contain the same data you can see in the JSON response on the left. |
Getting Permissions
You can retrieve permissions in several different ways, for example for a Principal, a Role or a Securable Type.
Some APIs perform checks for the calling user by pulling the user information from the HTTP request itself. Other APIs allow you to specify which object you want to get permissions for.
Getting permissions for a Principal
Getting all Permissions
Retrieving a principal's permissions is done using the account name (for example "somedomain\jane.doe") of that principal. When directly using the API, you have to encode that account name into base64 before sending it. C# Consumer API SDK will do the encoding for you.
In general, any GET endpoint requires you to base64 encode the principal name, due to the fact that principal names can contain characters that are not allowed in URIs.
When you request permissions for a specific Principal, you'll get the permissions that Principal has stemming from any of their roles.
The following examples use the "somedomain\jane.doe" account.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer /Permissions/Principal/c29tZWRvbWFpblxqYW5lLmRvZQ== will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
Checking for a specific Permission
You can also retrieve permissions given a Principal has on a particular Securable Type.
In the example below, we'll look at InstructionSet related permissions "somedomain\jane.doe" account has.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer /Permissions/Principal/c29tZWRvbWFpblxqYW5lLmRvZQ==/Type/InstructionSet will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
If given Securable Type supports Instances, you can also check a Principal's permissions on a specific instance.
In the example below we'll use a different account called "somedomain\john.doe" and check what permissions it has on Instruction Set with the Id of 1.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer /Permissions/Principal/c29tZWRvbWFpblxqb2huLmRvZQ==/Type/InstructionSet/1 will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
If the given Principal has no permissions or does not have permissions on given Securable Type and/or instance, an empty collection is returned.
Getting permissions for a Role
You can retieve Role's permissions by using the role Id.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Permissions/Role/16 will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
You can also retrieve all permissions given Role has on a specific Securable Type.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Permissions/Role/16 /Type/ProcessLog will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
And for Securable Types that support Instances, you can also check Permissions on a specific Instance.
Here we'll get permissions for a custom Role that's been assigned a 'Viewer' permissions on an Instruction Set.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Permissions/Role/30 /Type/InstructionSet/1 will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
Getting permissions for a Securable Type
You can retrieve permissions granted on a Securable Type using the type's Id. This will return a collection of all permissions on a given type assigned to any of the Roles.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Permissions/ Securable/1 will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
You can also retrieve permissions granted on a specific Instance of a Securable Type.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/Permissions/Securable/1/1 will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
Helper APIs
Consumer API has a number of endpoints that are not directly involved with its RBAC system but instead provide various utility functions around the general principal and permission area.
Who am I?
You can ask the API to return the information about the user who's making the request. The API examines the incoming request, retrieves the name of the user from it, makes sure the user is authenticated, and returns information summary about the user, like user's principal name, SID, display name and email.
This endpoint is useful for systems that cannot assume they're running under a particular account, like a browser or an application running in the context of launching user. In those cases this endpoint can be used to obtain the name of the user, which is then fed to the Permissions endpoint seen above in order to retrieve the permissions of the caller.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/PrincipalSearch/whoami will yield following response:
| Use PrincipalSearch object inside the Tachyon connector instance.
"user" object will contain the same data you can see in the JSON response on the left. |
Anchor | ||||
---|---|---|---|---|
|
Because in order to add a Principal to Tachyon you have to know the SID of the user, Tachyon's Consumer API exposes endpoints that help you look up users in Active Directory and retrieve information about them, including their SID.
You can perform a search for Active Directory accounts whose common name or sAMAccountName contain given phrase. Details of what exact search is performed are beyond the scope of this page and depend on type of objects being searched for, like users, groups and computers and whether your Tachyon installation is using GC or LDAP.
In the examples below we'll be looking for accounts that contain the phrase "Administrator". How you perform this search depends on your version of Tachyon.
Tachyon versions up to and including 4.1
You simply provide a base64 encoded search string and issue a GET request.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/PrincipalSearch/ QWRtaW5pc3RyYXRvcg== will yield following response:
| Use PrincipalSearch object inside the Tachyon connector instance.
"results" object will contain the same data you can see in the JSON response on the left. |
Tachyon versions 5.0 and newer
Here you have greater control over the search. A POST request should be used and in its payload you can specify, apart from the search string, number of results returned, sort column and order.
You can search for "user" and "group" object types and sort in either ascending (using "ASC") or descending order (using "DESC") on following columns: "cn", "mail", "sAMAccountName", "description", "objectSid", "displayName". Column names, object types and sorting direction string are not case sensitive.
You have to provide the SearchText (the text to search for) and at least one object type. Pagesize and sort are optional and if not provided will default to respectively 100 and ascending sorting on display name.
One things that you have to keep in mind when it comes to PageSize property is that, due to internal implementation, it defines the size of the page returned by Active Directory. This means that you can get fewer results than you requested, even if there would have been more to return because Tachyon filters out users already in the system. As an example, if you define the page size to be 10 and the Active Directory has 18 entries that match your search string, it will return 10 entries. Now let us assume that out of those 10 entries 1 user is already in Tachyon. This user will be filtered out of the return data set, so you will receive only 9 entries.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/PrincipalSearch with following payload:
will yield following response:
| Use PrincipalSearch object inside the Tachyon connector instance.
"results" object will contain the same data you can see in the JSON response on the left. |
Retrieving Active Directory information about a specific account
You can also retrieve user's information by their principal name, though this endpoint only returns authenticated users who are also Principals in Tachyon (either directly or throught group membership).
This means that in order to obtain information about somedomain\jane.doe using this endpoint, somedomain\jane.doe has to be a domain account that's either a Principal in Tachyon, or belongs to an Active Directory group that is a Principal in Tachyon.
When using the API directly, the principal name has to be base64 encoded. Using the SDK encoding is not necessary because the SDK will perform the encoding internally.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/PrincipalSearch/user/c29tZWRvbWFpblxqYW5lLmRvZQ== will yield following response:
| Use PrincipalSearch object inside the Tachyon connector instance.
"results" object will contain the same data you can see in the JSON response on the left. |
Retrieving members of an Active Directory group
You can ask Tachyon to retrieve members of an Active Directory group. This group does not have to be a principal in Tachyon for this functionality to work.
When using the API directly the group name has to be base64 encoded. Using the SDK encoding is not necessary because the SDK will perform the encoding internally.
In the example below we'll use an AD group called "Tachyon users" and retrieve its members.
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a GET request to https://my.tachyon.server/Consumer/PrincipalSearch/GetMembers/VGFjaHlvbiB1c2Vycw== will yield following response:
| Use PrincipalSearch object inside the Tachyon connector instance.
"results" object will contain the same data you can see in the JSON response on the left. |
Configuring Tachyon RBAC through the Consumer API
In this section we will look at configuring RBAC emphasizing operations on Principals, Roles and Permissions but also covering Securable Types and Operations later on.
Adding Principals from Active Directory
Adding Principals to Tachyon will be one of the first things you'll do after installing the system. A fresh installation of Tachyon (which in this context means an installation where there was no previous Master database or such database was dropped) will have two Principals - the account used to install the Tachyon Server (and created the database to be specific) and NT AUTHORITY\Network Service account.
These accounts have limited permissions so to properly use the system you should add more Principals. In order to add a principal to Tachyon you will need an External Id, also called SID, for an active directory account that you wish to add as a principal. Although you can obtain account details through various means. In Active Directory search we've seen Tachyon exposes endpoints that return this information and enables you to search for Active Directory accounts.
Here we'll assume you already have the account details and focus on adding an account as a Principal to Tachyon.
In the example below we'll "SomeDomain\Jane.Doe" account and add it to Tachyon.
To add an account as a Principal you'll at the very least need to supply an ExternalId (SID) and Principal Name, though its advised to also supply a Display Name. Also, unless you set the Enabled flag to true, the newly created account will be disabled by default.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/Principals with following payload:
Will yield following response:
| Use Principals object inside the Tachyon connector instance.
"principal" object will contain the same data you can see in the JSON response on the left. |
Note |
---|
You cannot add a Principal with the same PrincipalName or ExternalId as another Principal that's already in the system, because both of those values must be unique. |
Updating a Principal
Updating a Principal is very similar to adding one. You have to use a PUT verb instead of a POST if using the API directly, or Update method instead of Add if you're using the SDK. You also have to provide an Id that belongs to an existing Principal. Remember, you cannot modify system Principals.
Again, you have to remember that ExternalId and PrincipalName must remain unique so you cannot change Principal's PrincipalName or ExternalId to one that matches another Principal's.
Configuring Roles
Roles are the pivotal point of an RBAC system.
Tachyon comes with a number of pre-defined roles, which should be sufficient to start with, but in time you will most likely create custom roles, either to restrict access to instruction sets or to cover sets of permission required by specific roles within your organization.
Adding, Editing and Removing a Role
First let's look at creating a Role. This can be done either in isolation, where just the role is created and any permissions must be assigned in subsequent call(s), or as a more complete package, where a Role is created along with a set of Permissions, which can include Management Groups.
Regardless of which approach is used, Principals have to be assigned separately.
To create a Role all you require is a name, and this name must be unique. Description can optionally be provided and you can't create system roles.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/Roles with following payload:
Will yield following response:
| Use Roles object inside the Tachyon connector instance.
"role" object will contain the same data you can see in the JSON response on the left. |
Creating a Role with Permissions is possible by joining Role creation we've just seen with creating permissions, which is described a bit later.
This effectively means that we take a regular Role creation payload and add a 'Permissions' property to it. That propery is an array of permissions, which we are yet to look at in greater details.
The example below creates a role, which has "Viewer" and "Approver" permissions on Instruction Set with the Id of 1 and "Actioner", "Questioner", "Viewer" and "Approver" permissions on Instruction Set with the Id of 2. It also has permissions on three Management Groups.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/Roles/Complete with following payload:
Will yield following response:
| Use Roles object inside the Tachyon connector instance.
"role" object will contain the same data you can see in the JSON response on the left. |
To update a Role you should use PUT versions of the two endpoints seen above and provide one additional property in the JSON payload - the Id of the Role being modified. If you're using the Consumer SDK, you should call Update method instead of Add and you must provide an Id in the payload object sent to the API.
Since the names of Roles have to be unique, you won't be able to change the name of a Role to one that is the same as another Role.
Changing the Role details with https://my.tachyon.server/Consumer/Roles (or using the Update method in Consumer SDK that takes Role object type) will change just the details of the role will not change the permissions in any way. It will not change which Mangement Groups or Principals are assigned to the Role either.
Changing the Role via https://my.tachyon.server/Consumer/Roles/Complete will not change which Principals are assigned to the Role, but it will change the Permissions and Management Groups. When using this endpoint with PUT verb (or using the Update method in Consumer SDK that takes RoleWithPermissionsAndManagementGroups object type), all of the Permissions for given Role will be replaced with Permissions provided in the payload and all Management Groups will be replaced with Management Groups provided in the payload. This means that if you do not provide Permissions (omit the property, provide a null value or an empty array), all Permissions will be removed from the Role. Likewise, if you do not provide ManagementGroups all Management Groups will be unassigned from the Role.
Deleting a role is straightforward and you just need its Id. You can also delete multiple Roles in one call by providing a collection of Role Ids. In either case, you cannot delete a system Role.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
To delete a single Role make a DELETE request to https://my.tachyon.server/Consumer/Roles/31 ,which will delete the Role with the Id of 31. To delete multiple Roles, make a DELETE request and send an array of Ids to https://my.tachyon.server/Consumer/Roles. To delete Roles with Ids 31, 32, 33 and 34 you would send this payload:
| Use Roles object inside the Tachyon connector instance.
To delete multiple Roles:code
|
Assigning and unassigning Principals to Roles
As we've seen above when we covered retrieving Principals and Roles, the association between Principals and Roles can be examined from either end: which Principals are assigned to a given Role or which Roles given Principal has assigned.
Looking at the issue from the perspective of a Principal, you can assign or unassign Roles(s) to a Principal, or replace any Roles that Principal has with a given set of Roles.
First, let's pick a Principal that we will assign Roles to. In the example below I'll use "SomeDomain\\Jane.Doe", which has the Id of 3 and I'll assign 4 Roles to that Principal: Instruction Set Administrators, Permissions Administrators, Infrastructure Administrators, Global Questioners which have respective Ids of 2, 3, 4 and 6.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/PrincipalRoles/Principal/3 with following payload:
will yield following response:
| Use PrincipalRoles object inside the Tachyon connector instance.
"roles" object will contain the same data you can see in the JSON response on the left. |
Now let's replace the Roles for that Principal with 2 other Roles: Custom Properties Administrators and Consumer Administrators, which have Ids 9 and 10 respectively.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a PUT request to https://my.tachyon.server/Consumer/PrincipalRoles/Principal/3 with following payload:
will yield following response:
| Use PrincipalRoles object inside the Tachyon connector instance.
"roles" object will contain the same data you can see in the JSON response on the left. |
Lastly, I'll remove the assiciation to Custom Properties Administrators Role from the Principal
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a DELETE request to https://my.tachyon.server/Consumer/PrincipalRoles/Principal/3 with following payload:
will yield following response:
| Use PrincipalRoles object inside the Tachyon connector instance.
The method will return a boolean value. |
Looking at the issue from the perspective of a Role, you can assign or unassign Principal(s) to a Role, or replace any Principals that Role has with a given set of Principals.
In the examples below we'll work with the Custom Role we've created above. It has the Id of 31 and first we'll assign 3 Principals to it:
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/ PrincipalRoles/Role/31
will yield following response:
| Use PrincipalRoles object inside the Tachyon connector instance.
"principals" object will contain the same data you can see in the JSON response on the left. |
Now we will replace the existing 3 Principals with 2, one of which, "SomeDomain\\Jane.Doe" was already assigned to the Role:
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a PUT request to https://my.tachyon.server/Consumer/ PrincipalRoles/Role/31
will yield following response:
| Use PrincipalRoles object inside the Tachyon connector instance.
"principals" object will contain the same data you can see in the JSON response on the left. |
And finally we'll remove all "SomeDomain\\John.Doe" from the Role, leaving just "SomeDomain\\Jane.Doe" assigned to the Role:
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a DELETE request to https://my.tachyon.server/Consumer/ PrincipalRoles/Role/31
will yield following response:
| Use PrincipalRoles object inside the Tachyon connector instance.
The method will return a boolean value. |
As we can see, the Principal and Role assignment, unassignment and replacement endpoints mirror each other covering the approach from either Principal or Role point of view.
Lastly, you can create or remove a link between a single Principal and a single Role.
In this example we'll create a link between Customer Role, which has the id of 31 and "SomeDomain\\John.Doe" Principal, which has the Id of 4.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/PrincipalRoles
will yield following response:
| Use PrincipalRoles object inside the Tachyon connector instance.
"principal" object will contain the same data you can see in the JSON response on the left. |
and now we'll remove the link we've just created:
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a DELETE request to https://my.tachyon.server/Consumer/Role/31/Principal/4 will not yield any response payload so you should check the HTTP return code to see if the operation was successful. | Use PrincipalRoles object inside the Tachyon connector instance.
The method will return a boolean value. |
Adding and removing Permissions to a Role Anchor ROLEPERM ROLEPERM
The main method of assigning Permissions is to send two collections, one with Permissions that need to be changed or updated and another one with permissions that should be removed.
Crafting the correct payload should be done carefully as omitting an entry can result in deletion of an existing Permission.
PermissionsToSaveOrUpdate collection should have permissions you either want to add or modify. You only need to provide Ids, names are ignored. It is important to understand when the system considers given operation an 'updated' and when a 'creation' as it will behave slightly differently.
Because a Permission is between a Securable Type and a Role, with possible addition of Securable Id, those three properties define it. Operations are considered a property of a Permission and they are always considered together - i.e. a single Permission can Allow or Deny a set of Operations, but it cannot mix and match.
When you request a Permission to be added or updated, Consumer API will look at the SecurableId, SecurableTypeId and RoleId properties provided and check for any permissions already existing for this combination of values. If none are found, a new permission is added with the operations specified in the payload. If an entry is found, then Operations are examined next. If the existing Permission has Operations that aren't present in the Permission sent to the API, they are removed. Any operations present in the Permission sent to the API that do not exist in the Permission that is already in the system are added.
As you might have noticed, PermissionsToSaveOrUpdate can be used to remove Permissions by omitting Operations you want to remove. Furthermore, if you provide a Permission without any Operations, the entire Permission is removed.
Lets look at an example that should help us better understand how this functionality works.
Let us assume that we have a Permission on Instruction Set "My set" assigned to Role "Custom Role" with just one Operation "View". "My Set" has the Id of 4, "Custom Role" has the Id of 31, "Instruction Set" Securable Type has the Id of 1 and "Viewer" has the Id of 1. This means that the existing Permission will look as follows:
Code Block | ||||
---|---|---|---|---|
| ||||
{ "Allowed": true, "SecurableTypeId": 1, "SecurableId": 4, "RoleId": 31, "Operations": [ { "OperationId": 1 } ] } |
Now let us assume that a request comes into the Consumer API that looks as follows:
Code Block | ||||
---|---|---|---|---|
| ||||
{ "PermissionsToSaveOrUpdate": [ { "Allowed": true, "SecurableTypeId": 1, "SecurableId": 4, "RoleId": 31, "Operations": [ { "OperationId": 1 }, { "OperationId": 3 } ] } ], "PermissionsToDelete": [] } |
This request matches a Permission we already have, because it has the same SecurableId, SecurableTypeId and RoleId, but the Operations are slightly different - Id of 3 has been added, which represents 'Questioner' Operation. Following the rules outlined above, the API will match this to the existing Permission and see that Operation with the Id of 1 already exists, so no action is needed but the Operation with the Id of 3 doesn't exist, so it needs to be added. Afterwards we will end up with a permission that looks like this:
Code Block | ||||
---|---|---|---|---|
| ||||
{ "Allowed": true, "SecurableTypeId": 1, "SecurableId": 4, "RoleId": 31, "Operations": [ { "OperationId": 1 }, { "OperationId": 3 } ] } |
If now we were to make another request with with following payload:
Code Block | ||||
---|---|---|---|---|
| ||||
{ "PermissionsToSaveOrUpdate": [ { "Allowed": true, "SecurableTypeId": 1, "SecurableId": 4, "RoleId": 31, "Operations": [ { "OperationId": 2 }, { "OperationId": 4 } ] } ], "PermissionsToDelete": [] } |
The Consumer API will again recognise that a Permission already exists that matches the one in the payload and will examine the Operations. Because neither operation 1 nor 3, which do exist in the Permission already in the system are present in the payload, they will be removed. Operations 2 and 4 (Actioner and Approve respectively) do not exist in the Permission so they will be added and changed made will result in a Permission that looks like this:
Code Block | ||||
---|---|---|---|---|
| ||||
{ "Allowed": true, "SecurableTypeId": 1, "SecurableId": 4, "RoleId": 31, "Operations": [ { "OperationId": 2 }, { "OperationId": 4 } ] } |
As a last example let's look at what will happen when we send this payload to the API:
Code Block | ||||
---|---|---|---|---|
| ||||
{ "PermissionsToSaveOrUpdate": [ { "Allowed": true, "SecurableTypeId": 1, "SecurableId": 4, "RoleId": 31, "Operations": [] } ], "PermissionsToDelete": [] } |
Again, the system will recognise this as an existing Permission and will remove Operations 2 and 4 because they do not exist in the request payload. But since there are no Operations to add, the entire Permission will be removed.
Lastly, let's look at how an example API call would look like:
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/Permissions with following payload:
will yield following response:
| Use Permissions object inside the Tachyon connector instance.
"permissions" object will contain the same data you can see in the JSON response on the left. |
Configuring Management Groups
Management Groups can only be assigned to a Role which has Permission to at least one Instruction Set. This prerequisite stems from internal implementation and it has to be taken into account when designing Permissions in your system.
The example below assumes that Role "Custom Role" with the Id of 31 has at least one Instruction Set Permission assigned to it.
You can assign or unassign either a single Management Group or a collection of Management Groups. To assign a single Management Group to a Role you'd issue a POST request to https://my.tachyon.server/Consumer/Roles/[role Id]/ManagementGroups /[management group id], so for instance to assign Management Group wit the Id of 7 to role with the Id of 31 you'd call https://my.tachyon.server/Consumer/Roles/31/ManagementGroups /7.
Making a DELETE request instead of POST will results in the Management Group being unassigned from the Role.
These requests do not require any payload because all information is already present in the URI. Consumer SDK equivalents are Roles.AddPermissionForManagementGroup(...) and Roles.RemovePermissionForManagementGroup(...) respectively, which simply take the Ids of the Role and the Management Group.
To assign or unassign Management Groups in bulk you have to use POST and DELETE respectively to https://my.tachyon.server/Consumer/ Roles/ManagementGroups, and below is an example of the payload that should be sent with the request.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
To assign multiple Management Groups to a Role in a single call, make a POST request to https://my.tachyon.server/Consumer/Roles/ManagementGroups with following payload:
which will yield following response:
| Use Roles object inside the Tachyon connector instance.
"role" object will contain the same data you can see in the JSON response on the left. |
Unassigning Management Groups from a role is a mirror operation using the DELETE verb on the same web address:
Direct Consumer API call | C# code using Consumer SDK library | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
To unassign multiple Management Groups from a Role in a single call, make a DELETE request to https://my.tachyon.server/Consumer/Roles/ManagementGroups with following payload:
This call will not return any data. | Use Roles object inside the Tachyon connector instance.
|
Configuring Securable Types and Applicable Operations
We have already seen how to retrieve Securable Types and now we'll look at how we can create and modify them.
All you need to create a Securable Type is a name, which must be unique.
In order to delete a Securable Type, you have to first delete all Permissions that use that Securable Types and all Applicable Operations linked to the Securable Type.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a POST request to https://my.tachyon.server/Consumer/SecurableTypes
will yield following response:
| Use SecurableTypes object inside the Tachyon connector instance.
"securableType" object will contain the same data you can see in the JSON response on the left. |
If you wish to update a securable type you'll have to provide its Id:
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Making a PUT request to https://my.tachyon.server/Consumer/SecurableTypes
will yield following response:
| Use SecurableTypes object inside the Tachyon connector instance.
"securableType" object will contain the same data you can see in the JSON response on the left. |
and to delete this Sedurable Type:
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Make a DELETE request to https://my.tachyon.server/Consumer/SecurableTypes/26 This call will not yield any response. | Use SecurableTypes object inside the Tachyon connector instance.
|
It is worth noting that Securable Types are created "empty" and that Applicable Operation have to be created separately.
Dealing with Operations
Applicable Operations exist only in the context of a Securable Type. While Applicable Operations must be unique within a single Securable Type, they do not have to be unique between Securable Types.
To create an Operation you have to provide either Id or Name (but not both) of Securable Type for which the Operation should be created. In the example below we'll use the Securable Type we've just created, which has the Id of 26.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Make a POST request to https://my.tachyon.server/Consumer/ ApplicableOperations to use Securable Type Id
or with this payload to use Securable Type Name:
Both will yield following response:
| Use ApplicableOperations object inside the Tachyon connector instance. To use Securable Type Id:
To use Securable Type Name:
"operation" object will contain the same data you can see in the JSON response on the left. |
To delete an Operation you just need its Id.
Direct Consumer API call | C# code using Consumer SDK library | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Make a DELETE request to https://my.tachyon.server/Consumer/ApplicableOperations/63 | Use ApplicableOperations object inside the Tachyon connector instance.
|