Skip to content

Access Control Framework

Altair SLC Hub implements a role based access control system.

A Role is a named entity that has an associated set of permissions. Roles can be associated directly with users or can be associated with groups. The set of permissions a user has is the union of the permissions associated with any roles directly assigned to the user and the roles associated with any groups the user is a member of, directly or indirectly.

Note

The groups a user is a member of are captured when an authentication token is created or refreshed. Changing the group memberships of a user doesn't have an effect until the user's authentication token is refreshed, either due to expiry, or because the user logs out and logs back in. However, changing the association of roles to users or groups has immediate effect.

A Permission associated with a role consists of a string defining the object or objects that the permission applies to, and the name of an action that is being permitted. A permission can then specify an effect, either Allow or Deny.

A Role bound to a User or Group can apply to all namespaces or be bound to a single namespace (see Namespaces for a discussion of namespaces.) If a role is bound to a specific namespace, the permissions only have an effect for access control requests that explicitly reference that namespace, that is access control requests relating to entities in the namespace. If a role is bound to all namespaces, then the permissions have an effect for any access control request, regardless of the namespace it specifies. This includes access control requests that specify no namespace, for example access control requests for non-namespaced entities such as Users and Groups.

Access control evaluation requests

When a request is made to a service to perform some kind of action, the service will make a request to the access control service to establish whether the requester has permission to perform the action. This request consists of:

  • The action to perform (for example Create or Read).
  • The object on which the action is performed (for example /Groups/developers, /Users).
  • The namespace, or any, in which the object exists.
  • The user ID and any group IDs of the user making the request.

This information, along with the database of permissions associated with each role, is used to determine whether the request is permitted. An Allow or Deny decision is then returned to the requesting service reflecting whether the user has permission to perform the action.

Access control decision log

All decisions made by the access control service are logged in a searchable log. Each line in the log records the object, action, decision string, user ID, and the timestamp of when the decision was made. This decision log can then be used to understand why a particular action was permitted or denied.

Action Strings

An access control evaluation request contains a string giving the action that is being attempted. Action strings are conventionally single words. Each service defines its own set of action strings, but typical action strings are:

  • Create
  • Read
  • Update
  • Delete

Object Strings

An access control request contains a string identifying the object on which the action is being performed. These are path-like strings, for example, /Group/developers or /Pipeline/DailyJobs/ManagementReport.

Permission Rules

A role will typically have one or more permission rules associated with it. Each permission rule consists of an action string pattern and an object string pattern, and a resulting effect.

Action specification

Permissions can define the actions to which the permission applies either as an exact string, or as a wildcard (*) that matches any action.

Object specification

A permission can define the object or objects to which the permission applies using a variety of matchers:

  • Simple
  • Doublestar
  • Regular expression
  • Hierarchy

Simple matcher

The object string can be specified as an exact string or as a simple wildcard. This is the default.

Some examples of object patterns:

Pattern Description
/Groups/* Matches /Groups/developers, does not match /Groups
/Pipeline/* Matches /Pipeline/DailyJobs and /Pipeline/DailyJobs/ManagementReport but not /Pipeline

Doublestar matcher

The doublestar matcher recognises that access control object strings are "file path like", that is, they are made up of a sequence of elements separated by forward slashes.

In the doublestar matcher, the following patterns can be used:

Pattern Description
* Matches any sequence of characters, not including the path separator (/)
/**/ Matches zero or more complete "directory" path elements
? Matches a single character, not including the path separator (/)
[class] Matches a single character within the given character class, not including the path separator (/)

The doublestar should only appear surrounded by path separators (/). To match any object string at all, the pattern /**/* is required.

The following character classes can be used:

Class Description
[abc] Matches a single character within the set
[a-z] Matches a single character within the range
[!class] or [^class] Matches a single character not in the given class

Regular express matcher

The syntax of the regular expressions accepted by the regular expression matcher is the same general syntax used by Perl and Python. For a definition of the syntax accepted, see the RE2 syntax description

The regular expression matcher matches the complete object string against the provided regular expression. That is, the matcher adds beginning of string and end of string anchors to the provided regular expression.

Hierarchy matcher

The hierarchy matcher also recognises that access control object strings are "file path like", that is, they are made up of a sequence of elements separated by forward slashes.

The hierarchy matcher treats both the pattern string and the provided object string as path like strings, and will return a match if the object string is equal to, or a child path of the pattern string.

For example:

Pattern Object string Match
/Pipelines /Pipelines yes
/Pipelines /Pipelines/Pipeline1 yes
/Pipelines/Folder /Pipelines/Folder/Pipeline1 yes
/Pipelines/Folder /Pipelines/Folder1/Pipeline1 no

Access Control Request Evaluation

As described above, an access control evaluation request consists of:

  • The action being performed (for example Create or Read)
  • The object on which the action is being performed (for example /Groups/developers, /Users)
  • The namespace, or any, in which the object exists
  • The user ID and any group IDs of the user making the request

When an access control request is made, the access controller evaluates such a request as follows:

The list of all relevant roles is calculated. For a role to be relevant it must satisfy a number of requirements: * There must be a role binding from the role to one of the principals (that is the user, or one of the groups) provided in the access control request * The role binding must apply to either all namespaces or the namespace in the access control request.

Then for each relevant role, each permission rule is evaluated to see whether it matches the access control request. For a permission rule to match the evaluation request, both the action pattern and the object pattern have to match the evaluation request.

If any rules match the request and specify a deny result, then the result of the evaluation is a deny decision. Otherwise, if any rules match the request and specify an allow result, then the result of the evaluation is an allow decision.

If no permission rules match the request, the result is a deny decision.

In the case of access control requests that specify a namespace, there is then an additional access control check for the object /Namespace with the action Use in the same namespace. This ensures that the user making the request also has permission to use the given namespace. That is, in order for a user to make use of any entity within a namespace, they require permission to "use" that namespace, as defined by a successful access control check for the object /Namespace with the action Use. Note that this check is performed in the context of the specific namespace. That is, regardless of the namespace, the check is on the same object string /Namespace, but the check is a "namespaced" access control check, so it only considers role bindings that explicitly specify the relevant namespace, or specify "all namespaces". So although namespaces themselves aren't namespaced entities, this access control check is a namespaced access control check. This allows easy definition of a single Role called NamespaceUser that can be used to grant access to any namespace simply by creating a role binding for a user or group and associating the role binding with the relevant namespace.

General Principles

There are some general principles that apply to the access control checks that Hub performs.

Creation of entities

Creation of entities generally uses the action Create on an "entity" path. So for example, creating a Library Definition called Lib1 performs an access control check for the action Create on the path /LibraryDefinitions/Lib1.

Querying entities

In general, when performing a query, only entities that a user explicitly has read access to are returned. That is, there is no specific access control check for "can this user query entities of this type", instead the result set of the query is filtered by whether the user has read access to each entity.

Reading, writing and deleting entities

Reading, writing and deleting entities uses the actions Read, Update and Delete on an "entity" path. For example, returning the definition of a Library Definition called Lib1 performs an access control check for the action Read on the path /LibraryDefinition/Lib1. The access control request made will also include the namespace in which the Library Definition is contained, so there is then an additional implied access control request for the action Use on the object /Namespace in the given namespace. For entities that support folders, such as pipelines, returning the definition of a pipeline within a folder performs an access control check for the action Read on a path such as /Pipelines/Folder/Subfolder/Pipeline1.