Policy Record
An application can have multiple versions of policies, but only
one version is deployed and active at any given time.
An application's policy typically consists of multiple policy
records, each containing seven parts

- Type
Permit or Deny.
Clear Entitlement evaluates "Deny" policies first; if a decision can
be reached, it won't process "Permit" policies.
- Resource
The target of the policy, e.g., domesticPayment—think of this as the
resource in a RESTful API.
For convenience, multiple resources can be added to a single record;
each line represents a different resource.
Clear Entitlement supports two types of resources: path pattern
match and exact match. When a resource string starts with "/", it is
a path pattern:
? matches one character
* matches zero or more characters within a path segment
** matches zero or more path segments until the end of the path
{spring} matches a path segment and captures it as a variable named "spring"
{spring:[a-z]+} matches the regexp [a-z]+ against a path segment and captures it a path variable named "spring"
{*spring} matches zero or more path segments until the end of the path and captures it as a variable named "spring"
For example, "/user/{uid}" matches any string starting with
"/user/", and the remaining part is matched to {uid}. To reference
the value in the condition, use "resource.uid" in this case. For
more details, please check the
Spring document
When the resource string doesn't start with "/", it is an exact
match.
Also, for exact match resources, they form trees, with the delimiter
being "/". For example, if we define two resources as
"payment/domesticPayment" and "payment/internationalPayment", the
resource tree is structured as follows:
payment -> domesticPayment
|
-> internationalPayment
The policies defined for ancestor nodes in the tree apply to all
descendant nodes. In the above example, the policies with
resource="payment" will be evaluated if the request is for
"payment/domesticPayment" or "payment/internationalPayment"
- Action
The action on the resource, such as create, read, update, delete,
etc., akin to the method in REST.
For convenience, multiple actions can be added to a single record,
with each line representing a different action.
- Subject
Can consist of users, groups, or roles, or a combination of them.
For convenience, multiple subjects can be added to a single record,
with each line representing a different subject.
For users, use the subject format user/{username}, for example,
user/johnf, or user/jonhf@clearentitlement.com if email is used as
the username.
For groups, use the subject format group/{group name}, for example,
group/sales.
For application roles, use the subject format appRole/{role name},
for example, appRole/paymentChecker.
or global roles, use the subject format role/{role name}, for
example, role/admin.
There are three special subjects: everyUser, everyGroup, and
everyRole.
"everyUser" can be used if the policy applies to every user.
"everyGroup" matches only if the current user belongs to at least
one group. Additionally, if there are group attributes in the
condition, those attributes are specific to the current group being
evaluated. If no decision can be reached based on the current group,
the evaluation continues with the next group.
"everyRole" matches only if the current user has at least one role.
Similarly, if there are role or role membership attributes in the
condition, those attributes pertain to the current role being
evaluated. If no decision can be reached based on the current role,
the evaluation continues with the next role.
- Condition
Specifies the condition for the access APIs, providing the complete
criteria for granting access. Refer to the grammar section for
details on how to write the condition.
- Functional Condition
Refers to the condition for functional access, distinct from the
full access check. For instance, when verifying permission for
making a payment, the full condition may entail checking account
details, amounts, etc. However, to decide whether to display a
"payment" menu item, only the role may need to be verified.
- Obligation:
This is the instruction/data returned from the API for the client to
act on. Clear Entitlement uses this for data redaction/filtering.
Obligations are in the format of name=value, and multiple
obligations can be set up in one policy record, one line each.
The value of the obligation can be any format agreed upon between
the client and policy, such as string, JSON, XML, etc. To reference
attributes (the same attribute in the condition), use
${attribute.name}$, for example:
accounts=$roleAtts.accountAndLimit.account$
restrictions=$roleAtts.accountAndLimit$
Note: roleAtts is a built-in attribute that refers to the membership
attribute for the current role.
Sample response:
{
"granted": true,
"filterObject": {
"restrictions": [
[
{
"account": "8744336085399580",
"maxAmount": 1200
},
{
"account": "70048841700216300",
"maxAmount": 2000
},
{
"account": "12494980148173100",
"maxAmount": 1000
},
{
"account": "3690859741294280",
"maxAmount": 1500
}
]
],
"accounts": [
[
"3690859741294280",
"12494980148173100",
"8744336085399580",
"70048841700216300"
]
]
}
}
Attribute Based Access Control (ABAC)
Clear Entitlement offers ABAC support for various data entities,
and each has a built-in attribute retriever to fetch (and cache)
the values.
User attribute: To reference user attributes, use
user.{attributeName} Group attribute: group.{attributeName}
Role attribute: role.{attributeName}
Entitlement attribute: entitlement.{attributeName}
User-role membership attribute: roleAtts.{attributeName}
Group-role membership attribute: roleAtts.{attributeName}
Sample conditions:
"user.department in ('sales', 'IT')"
"ifAny(roleAtts.accountAndLimit, 'payload.account=.amount and
payload.amount<=.amount')"
Note: "ifAny" is a built-in function to iterate through
multi-value attributes, in this case, roleAtts.accountAndLimit,
and see if any value can satisfy the condition.
Other built-in attributes:
username: the username.
resource: the resource in the request.
action: the action in the request.
resource.{attributeName}: the resource section when the resource
is in path pattern resource.
context.{attributeName}: the object passed from the request's
context.
userId: the user ID of the subject. Note, not the username.
orgId: the org ID, for multi-tenant deployments.
roleId: the role ID of the current subject if the subject is a
role.
groupId: the group ID of the current subject if the subject is a
group.
Customers can build their attribute retriever to fetch any value
from an external data source. For details, check the developer's
guide.
Functions
Clear Entitlement provides built-in functions that can be used in
conditions:
now(): Returns the current date and time.
countMatchedValue(attributes, regex): Returns the number of items
in attributes (a multi-value string list) that match the regex.
ifAny(attributes, condition): Checks if any item in attributes (a
multi-value object list) evaluates to true based on the condition.
Use .{attributeName} to reference the attributes of the current
item in the iteration.
ifAll(attributes, condition): Checks if all items in attributes (a
multi-value object list) evaluate to true based on the condition.
Use .{attributeName} to reference the attributes of the current
item in the iteration.
toJson(string): Converts a string to a JSON object.
Customers can build their own functions; for details, check the
developer's guide.
Condition Grammar
Clear Entitlement's condition grammar is straightforward, making
it easy for anyone familiar with programming to write
conditions.
In essence, the condition consists of one or more condition units
connected by "and", "or", or "not" operators.
Operator precedence follows the order: not > and > or. To alter
precedence, use parentheses ().
Each condition unit takes the form "operand" or "operand1 operator
operand2", where the operand can be a literal, attribute, or
function.
If the condition unit is a single "operand", its result must be a
boolean type.
- Operators
=: equal.
!=: not equal.
≪: less than.
<=: less than or equal.
>: greater than.
>=: greater than or equal.
in: checks if a single value is in a list of values.
not_in: checks if a value is not in a list of values.
start_with: checks if a string starts with another string.
not_start_with: checks if a string doesn't start with another
string.
contain: checks if a string contains another string.
not_contain: checks if a string doesn't contain another string.
match: checks if a string matches a regular expression.
not_match: checks if a string doesn't match a regular
expression.
- Literal
Number: Can be an integer or decimal, such as 100 or 9.5.
String: Enclosed in either single or double quotes, for example,
"abc", 'abc', "John's account", or '"some quoted value"'.
Boolean: Represented as true or false, without quotes.
NULL: Indicates a non-existent value, represented as null, without
quotes.
ANY: Indicates any value, represented as any, without quotes.
Date: Represented in the format mm/dd/yyyy or mm/dd/yyyy hh:mm:ss,
such as 03/20/2024 or 03/20/2024 05:03:20.
Time: Represented in the format hh:mm:ss, for example,
05:03:20.
- Attribute
Attribute names can include letters, numbers, "_", "$", ".", and
"[]". They cannot start with a number.
"." is used as a delimiter to indicate a child attribute when the
attribute name is a constant. If the attribute name is a variable,
use [].
Examples:
userId
user.department
.account
org[orgId].primaryContactEmail
Policy Management Workflow
Clear Entitlement's policy management workflow comprises three
states: policy creation, policy approval, and policy
deployment.
The lifecycle of a policy version includes "DRAFT", "PENDING
APPROVAL", "APPROVED"/"REJECTED", and "DEPLOYED"/"UNDEPLOYED".

To create a policy, navigate to "Application" -> "Manage Access
Policy" and select the application if it hasn't been chosen
previously.
Once the application is selected, users with policy creation
permission will see the "New Version" and "Upload Policy"
buttons.
After the policies are created, the policy modeler can either save
them as drafts or submit them for approval.

The policy reviewer can either approve or reject the policies.

Once the policy is approved, the policy deployer can deploy the
policy.
When a new version of the policy is deployed, the previous version
changes to "UNDEPLOYED".

Policy Management Permissions
The resource for policy is "/Applications/{appId}/Policies"
The actions are: "read", "create", "update", "delete", "approve",
and "deploy".
Out of the box, Clear Entitlement provides three application roles
to support the workflow: PolicyMaker, PolicyChecker, and
PolicyDeployer. (no SoD by default)
These roles also support fine-grained entitlements by specifying
which applications are authorized to manage policy when assign the
user to the role.

To retrieve the application ID, navigate to "Application" ->
"Manage Applications" -> view an application. The application ID
can be found in the address bar, for example:
.../application/b472f8b3-7696-4975-8136-46720ccbabd4