Overview of Object Model
Entitlement systems have predefined policy snippets that work over an opinionated object model. To use these snippets, you must import your data in a way that conforms to the Entitlements model.
To help get your data into DAS in the Entitlements object model, Styra provides pre-built transformation policies for many data sources, such as LDAP, AD, SCIM, OpenAPI v2, and OpenAPI v3.
The Styra DAS Entitlements object model is designed to be flexible: both RBAC and ABAC are supported simultaneously, and almost any structured data can be used as additional context for authorization decisions. It is not required for you to populate the object model in its entirety, but it is required to populate the portion of it required by the pre-built rules that you intend to use.
In implementation, you can populate that object model by writing Rego code that lives in the folder object
(and has the Rego package object
and therefore referenced as data.object
). You must assign the following variables to the correct values based on the data sources you have configured.
users: The person (or program) which is attempting to perform the action.
service accounts: The machines that take actions.
actions: The changes that users and service accounts can make.
resources: The resources that users and service accounts can act on.
roles: The assignment of users and service accounts to roles.
role bindings: The assignment of roles to the permissions they are granted.
groups: The assignment of users and service accounts to group names.
group bindings: The assignment of groups to the permissions they are granted.
Object Schema
The schema for these variables is represented in the following object_schema.json
file.
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"title": "Entitlements data.object model",
"description": "Opinionated data model for the Styra DAS entitlement system type.",
"default": {},
"required": [],
"properties": {
"groups": {
"$id": "#/properties/groups",
"type": "object",
"title": "groups",
"description": "Groups of users, selected by user id or by attributes of users. This field is optional, and is used by RBAC snippets to grant groups of users permissions. Group ids are specified as keys in the object.",
"default": {},
"examples": [
{
"admin-team": {
"membership-attributes": {
"global_admin": true
},
"users": [
"bob",
"diya"
]
},
"platform-team": {
"users": [
"cheng",
"eric"
]
}
}
],
"required": [],
"patternProperties": {
"^.+$": {
"type": "object",
"description": "Groups may select members by user attributes and explicitly by id. If both membership-attributes and groups are specified, the union of users matching either selector are contained within the group.",
"properties": {
"membership-attributes": {
"$ref": "#/$defs/membership-attributes"
},
"users": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"additionalProperties": false
},
"resources": {
"$id": "#/properties/resources",
"type": "object",
"title": "resources",
"description": "Resource ids, optionally with attributes. Resource ids are specified as keys in the object.",
"default": {},
"examples": [
{
"System.Authz": {},
"System.Configuration": {},
"System.Datasources": {},
"System.Eval": {},
"System.LogReplay": {},
"System.Policies": {},
"System.Suggestions": {},
"System.Validate": {},
"Workspace.Authz": {
"restricted": "true"
},
"Workspace.Configuration": {},
"Workspace.Documentation": {
"public": "true"
}
}
],
"patternProperties": {
"^.+$": {
"description": "Attributes of the resource",
"$ref": "#/$defs/attributes"
}
},
"additionalProperties": false
},
"role_bindings": {
"$id": "#/properties/role_bindings",
"type": "object",
"title": "The role_bindings schema",
"description": "Role bindings attach a role to subjects and are used in RBAC snippets. Association can be done explicitly or through attributes or both.",
"default": {},
"examples": [
{
"DenySystemConfigModification": {
"subjects": {
"ids": [
"bob"
]
}
},
"SystemPolicyEditor": {
"subjects": {
"ids": [
"alice",
"bob",
"platform-team"
],
"membership-attributes": {
"is_admin": true
}
}
},
"WorkspaceAdmin": {
"subjects": {
"ids": [
"admin-team"
]
}
}
}
],
"required": [],
"patternProperties": {
"^.+$": {
"type": "object",
"properties": {
"subjects": {
"description": "Subjects to be bound to the role id; if ids and membership-attributes are both specified, the users selected are the union of those with an id in the ids array and those with all the attributes in membership-attributes",
"type": "object",
"properties": {
"ids": {
"type": "array",
"description": "IDs of subjects to be included in the role binding. IDs can be of any type of subject (user, group, and service account).",
"items": {
"type": "string"
}
},
"membership-attributes": {
"$ref": "#/$defs/membership-attributes",
"description": "Subjects with all of these attributes will be bound to the role id."
}
}
}
}
}
},
"additionalProperties": false
},
"roles": {
"$id": "#/properties/roles",
"type": "object",
"title": "role definitions",
"description": "Roles are used in RBAC models to describe permissions, and a role is defined in terms of actions and resources that are allowed or denied.",
"default": {},
"examples": [
{
"DenySystemConfigModification": {
"deny": {
"include": [
{
"actions": [
"update",
"delete"
],
"resources": [
"System.Configuration"
]
}
]
}
},
"SystemPolicyEditor": {
"allow": {
"include": [
{
"actions": [
"*"
],
"resources": [
"System.Policies"
]
},
{
"actions": [
"read"
],
"resources": [
"System.Authz",
"System.Configuration",
"System.Datasources",
"System.Eval",
"System.LogReplay",
"System.Suggestions",
"System.Validate"
]
}
]
}
},
"WorkspaceAdmin": {
"allow": {
"include": [
{
"actions": [
"*"
],
"resources": [
"**"
]
}
]
}
}
}
],
"required": [],
"patternProperties": {
"^.+$": {
"type": "object",
"allow": {
"$ref": "#/$defs/include-exclude-selector",
"description": "Selects request action and resource combinations to be allowed by this role"
},
"deny": {
"$ref": "#/$defs/include-exclude-selector",
"description": "Selects request action and resource combinations to be denied by this role"
}
}
},
"additionalProperties": false
},
"service_accounts": {
"type": "object",
"title": "service_accounts",
"description": "Defines the service accounts allowed access to the system; service_accounts may optionally include attributes.",
"default": {},
"examples": [],
"required": [],
"patternProperties": {
"^.+$": {
"$ref": "#/$defs/attribute",
"description": "Attributes for the service account"
}
},
"additionalProperties": false
},
"users": {
"$id": "#/properties/users",
"type": "object",
"title": "users",
"description": "User ids are keys in the map and users may optionally have attributes",
"default": {},
"examples": [
{
"alice": {
"location": "Mars",
"name": "Alice",
"organization": "Styra"
},
"bob": {
"name": "Bob",
"organization": "Styra"
},
"cheng": {
"name": "cheng"
},
"diya": {
"name": "Diya"
},
"eric": {
"contractor": "true",
"name": "Eric"
}
}
],
"required": [],
"patternProperties": {
"^.+$": {
"$ref": "#/$defs/attributes",
"description": "Attributes for the user"
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"$defs": {
"attributes": {
"patternProperties": {
"^.+$": {
"$ref": "#/$defs/attribute"
}
}
},
"attribute": {
"oneOf": [
{"type": "string"},
{"type": "number"},
{"type": "boolean"}
]
},
"membership-attributes": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/$defs/attribute"
}
}
},
"include-exclude-selector": {
"type": "object",
"include": {
"$ref": "#/$defs/action-resource-selector",
"description": "Requests to include in this selector"
},
"exclude": {
"$ref": "#/$defs/action-resource-selector",
"description": "Requests to exclude from the set selected by the include field"
}
},
"action-resource-selector": {
"actions": {
"type": "array",
"items": {
"patternProperties": {
"^.+$": {
"type": "string"
}
}
}
},
"resources": {
"type": "array",
"items": {
"patternProperties": {
"^.+$": {
"type": "string"
}
}
}
}
}
}
}
For example, if you had two data sources that each provided different user attributes, you can populate the users
part of the object model as the union of those two user objects. The following code assumes the two user objects have disjoint usernames. If that is not the case, you can prepend a classification to each user name.
package object
users := object.union(
data.datasources.contractors.users,
data.datasources.employees.users )
Whenever you write a policy, you can reference object.users
to get the entire collection. In other words, you can think of the object
folder as yet another data transformation that allows you to combine different data sources (each of which may have been transformed themselves) into one cogent object model.
Once that is done, the pre-built policy snippets will make decisions based both on the input or request provided by the application and the external data that has been infused into the DAS Entitlements’ opinionated object model.