Skip to main content

Entitlements System Data Model

Entitlements Systems have pre-defined policy snippets that work over an opinionated data model. To use snippets, import your data to conform to the Entitlements data model. To help get your data into Styra DAS in the Entitlements data model, Styra provides pre-built transformation policies for many data sources, including LDAP, AD, SCIM, OpenAPI v2, and OpenAPI v3.

The Styra DAS Entitlements data model is designed to be flexible. RBAC and ABAC are supported simultaneously, and almost any structured data can be used as additional context for authorization decisions.

The object package, which can be imported through the path data.object should contain data structured according to the Entitlements data model. The pre-configured snippets provided with the Entitlements System type to rely on the data in the object package having this structure and will not work correctly if this data is malformed.

note

All fields in the Entitlements object model are case-sensitive, including subject IDs, attribute names, and role names. If you are retrieving data from a case-insensitive system, transform your data to normalize the case of any identifiers to use within your Entitlements System. You can also use the lower or upper builtin functions in Rego.

Subjects

Subjects are optional and represent users, groups of users, or service accounts. All subjects must have a unique id and subjects may optionally have attributes.

Users may optionally be defined in a virtual document data.object.users. This document is not required to be defined; however, some snippets depend on it and will not work correctly without users being defined.

For example, the following package defines three users, two of which have attributes.

package object

users := {
"alice@styra.com": {
"location": "Wonderland",
"name": "Alice Liddell"
},
"bob@styra.com": {
"contractor": true,
"location": "US",
"name": "Bob"
},
"diya@styra.com": {
}
}

Groups are defined in the data.object.groups virtual document. Groups may specify inclusion by user id or by specifying membership-attributes, which dynamically selects users for membership in the group. If both users and membership-attributes are specified, the union of users matching either of those selectors is included in the group.

package object

groups := {
"contractors": {
"users": ["diya@styra.com"],
"membership-attributes": {
"contractor": true
}
},
"managers": {
"users": ["alice@styra.com"]
},
"admins": {
"users": ["cecily@styra.com"]
},
}

In the previous example, the contractors group contains diya@styra.com and bob@styra.com. The user diya@styra.com is included in the group by explicit inclusion and bob@styra.com is included because that user has the attribute contractor: true, which is specified in the membership-attributes of the contractors group.

The final subject type is intended for automation accounts and is defined in the virtual document data.object.service_accounts. Service accounts must have a unique id and may optionally include attributes. Groups may contain service accounts as well as users.

The following Rego document defines two service accounts, once of which has an attribute.

package object

users := {
"github-integration": {
"external-system": true
},
"das-publisher": {}
}

Service accounts are optional, and if specified will be included in snippets that use subjects.

Resources

A Resource is an unique object that can be accessed. Resources are optionally specified as an object in the virtual document data.object.resources. Resources may optionally have attributes, which may be used in ABAC policy snippets.

For example, the following Rego package defines two resources with ids /cars and /trains, and /cars has a single attribute.

package object

resources := {
"/cars": {
"public": false
},
"/trains": {}
}

Often all resources are not known ahead of time, as they may contain variables such as UUIDs or usernames. In such cases, globs may be used to specify a set of resources. For example, an HTTP resource may be of the form /api/{id} and all possible ids are not known because they come from user input. This is specified by using resource id /api/*.

Additionally, it is possible to provide the name of resource variables, which can then later be used in policy snippets. This is done with a special attribute _variables, which maps variable positions to names. In the previous example, this attribute would be the map {2: "id"}, which means that the variable in the second segment of the resource is named id.

The following is an example of resources:

package object

resources := {
"/cars": {
"public": false
},
"/cars/*": {
"_variables": {2: "id"},
},
"/cars/*/status/*": {},
"/trains": {},
"/trains/*": {},
"/trains": {}
}