Security Definitions
Overview
Security definitions are used throughout the application to limit access to elements like Spaces, Kapps, forms, and submissions. This guide describes the submission definition creation process, how precedence is determined, and how to coordinate security policies with submission search patterns.
Creating a Security Definition
The creation process is the same for all security definition types, but the page from which you access the security definitions list will determine which types are available for selection.
Created From | Types Available |
---|---|
Space level | Space, File Resource, Team, User |
Kapp level | Kapp, Form, Submission |
In both cases, you can access the Security Definitions page by clicking Security under the Definitions heading.
From there, follow these steps to create a new security definition:
- Click New Definition.
- Enter a unique name for the security definition in the Name field. This description is displayed when selecting a security definition to assign to a security policy.
- Select the functionality you want the security definition to affect from the Type drop-down list. Types also have bindings that determine which types of data the Platform can access. The Bindings section below discusses types and bindings in more detail.
- In the Message field, enter a message to display to the customer if the rule evaluates to False.
- Enter a single JavaScript expression that must evaluate to True or False in the Rule field. See the Rule Examples section below for more information.
- Click Create Security Definition.
Additional Security Definition Details
Rule Examples
Rules determine the exact parameters of the security definition. A basic example is a rule limited to a single username, such as identity('username') === "han.solo"
.
JavaScript provides a mechanism for wrapping scope that's also helpful for wrapping multiple statements and expressions into a single expression.
(function () {
//insert multiple functions and expressions
})();
Adding something like this makes the definition much more flexible but can make the definition more complex. We use this model for many of the security definitions we create in kinops, as shown below:
(function() {
__// Helper method__
var hasIntersection = function(obj1, obj2) {
// Ensure the objects are not empty
obj1 = (obj1 === null || obj1 === undefined) ? [] : obj1;
obj2 = (obj2 === null || obj2 === undefined) ? [] : obj2;
// If the parameters are not lists, wrap them in lists
var list1 = (obj1 instanceof Array) ? obj1 : [obj1];
var list2 = (obj2 instanceof Array) ? obj2 : [obj2];
// Find the intersection
var intersection = list1.filter(function(n) {
return list2.indexOf(n) != -1;
});
// Return whether any intersecting values were found
return list1.find(function(value) {return hasValue(list2, value)}) !== undefined;
};
__// Helper method__
var hasValue = function(list, value) {
return (list instanceof Array) && list.indexOf(value) != -1
};
__// Employee Check - unique portion of the Rule__
return hasIntersection(identity('teams'), ['Role::Employee']);
})()
This rule contains three pieces that are marked by comments.
The Helper methods are included in all the predefined kinops security definitions like this one. The top two sections are there to make sure that the first object in the hasIntersection
function is present in the second object. In the above example, the identity of the person's team is part of the "Employee" role. To put it another way, the definition asks, "Is the person requesting access an employee?".
As a slightly more complex example, the definition below checks whether the person is a member of the assigned team or is the assigned individual for a submission. This would replace the employee check section of the JavaScript expression above.
return (
// Assigned Team
hasIntersection(values('Assigned Team'), identity('teams'))
// Assigned Individual
|| hasIntersection(values('Assigned Individual'), identity('username'))
// Last updater (this is necessary so that a user can see that they successfully
// re-assigned a submission)
|| submission('updatedBy') == identity('username')
);
This definition asks whether the person is a member of the assigned team, whether they are the assigned individual, and if they are the last person to update the submission. The other JavaScipt functions are the same.
Note: Recall that Space Admins are automatically granted permission to everything, and as such are not affected by these rules.
Bindings
Along with using a type to indicate where a security definition can be used, you can assign bindings to the definition. Bindings are similar to the variables you use when creating an element on a form. For example, identity(username)
lets you access the authenticated User ID.
Technically, there is no definitive list of bindings because they can change with the types of security and other external factors.
The available types and some examples of available bindings for Spaces include:
Type | Endpoints Using this Type | Available Bindings |
---|---|---|
Space | Space Display, User Access, User Creation, User Modification, Team Membership Modification, Teams Access, Teams Creation, Team Modification, Submission Access, Submission Modification, WebApi Execution | identity(...), space(...) |
Team | Team Membership Modification, Team Modification | identity(...), space(...), team(...) |
User | User Modification | identity(...), space(...), user(...) |
The available types and some examples of available bindings for Kapps include:
Type | Endpoints Using this Type | Available Bindings |
---|---|---|
Kapp | Kapp Display, Kapp Modification, Form Creation, Submission Support, WebApi Execution, Default Submission Access, Default Submission Modification, Default Form Display, Default Form Modification | identity(...), space(...), kapp(...) |
Form | Form Display, Form Modification, Submission Access, Submission Modification | identity(...), space(...), kapp(...), form(...) |
Submission | Submission Access, Submission Modification | identity(...), space(...), kapp(...), form(...), submission(...) |
Each binding function accepts a second optional argument which is returned if the binding evaluates to undefined as displayed in this example: identity(‘attribute:Manager, [“mary.manager”])
Submission Searching Considerations
Security definitions can affect submission search patterns and thus must be coordinated. Keep the following in mind when developing new security definitions or submission searches:
- If more than 25 submissions are encountered in a search that the Submission Access policy denies, the entire query fails.
- Security Policies must be evaluated AFTER querying the database.
- The Platform limits failures to avoid "table scans" and any resulting performance degradation.
- The following table provides an example of a submission search query and an instance of a "good" and "bad" submission access policy:
Search Example | All submissions where the Assigned Team is “Facilities.” |
Submission Access Policy: Good Example | The current user is on the Facilities team. |
Submission Access Policy: Bad Example | The current user has the attribute “Manager” set to True. |
Updated 9 months ago