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.
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": {}
}