Access policies
Conditional item access
The Permissions app lets admins specify which user groups have read or write access to all items of a particular design/interface. For more granular per-item access control, you can extend your permissions configuration with access policies.
An access policy lets you control which items of a design/interface are accessible to users, based on each item's attribute values.
Each rule in the policy targets a set of user groups and has one or more expressions. Each expression defines a condition that items of the targeted design/interface must fulfil to be accessible to those user groups. A rule may require all or any of its expressions to be fulfilled before access is granted.
For example, imagine an access policy that targets the Street Cleaning Jobs design. It has a rule stating that Group A users can only see items whose Geometry attribute is located within a specific area.
Access policies are enforced throughout CausewayOne Asset Management, whenever item data is fetched. If any access policies exist for a given design/interface, the items shown to users will be filtered, according to the groups a user is assigned to (either directly or via a role).
Interface access policies
If you create an access policy for an interface, it will apply to all designs/interfaces that implement it.
For example, imagine an access policy that targets the Jobs interface. It has a rule stating that Group B users can only see items of designs that implement the interface, whose Team attribute equals "Street Cleaning Team B".
However, be aware that those designs/interfaces may have their own access policies, which could affect the overall item results.
Multiple access policies
In situations where multiple access policies apply, group users will see items that fulfil any of them (logical OR).
For example, imagine a user that belongs to Group A and Group B in the examples above. If they search the Street Cleaning Jobs design, they will only see items located within the specific area, or assigned to "Street Cleaning Team B", or both!
Access policies don't work on their own! If a group doesn't have the Read permission enabled for a design/interface, the group can't access any of those items, regardless of any access policies.
Live API documentation
Access policies can only be managed by admin users. The AccessPolicy endpoint details are available on Swagger.
Create an access policy
No rules are defined when creating an access policy.
{
"name": "MyExampleAP",
"description": "This access policy demonstrates the types of rule that can be added",
"enabled": false, // only set this to true when ready to use
"targetDodiCode": "designs_myExampleDesign" // the Guc code of the design/interface this will apply to
}
Response
{
"code": "accessPolicies_myExampleAP_64d92cac1669d55c91815627",
"name": "MyExampleAP",
"description": "This access policy demonstrates the types of rule that can be added",
"enabled": false,
"targetDodiCode": "designs_myExampleDesign",
"rules": [],
"metadata": {
"createdDate": "2023-08-10T1:19:09.035Z",
"createdUserUsername": "tobylerone",
"signature": "64d92cad1669d55s91815269"
}
}
Add a rule
You can add one or more rules to an access policy. Each rule can apply to one or more user groups. All rules must be fulfilled for read access to be granted (logical AND).
The rule's expression property accepts one expression of any type (logical, relational, conditional). The expression model can contain other expressions models, enabling you to construct a complex rule definition.
{
"userGroups": ["userGroups_MyExampleGroup"],
"expression": {
// a single expression model of any type
},
"signature": "64d92cad1669d55s91815269" // to get the current signature, use GET /api/accessPolicy/{code}
}
Expression types
Logical expressions
A logical expression lets you enforce conditional logic. Its conditions property accepts one or more expressions (relational or conditional).
Depending on the supplied discriminator:
-
AccessPolicyAndExpressionWebModel- all conditions must be met for the expression to be fulfilled. -
AccessPolicyOrExpressionWebModel- at least one condition must be met for the expression to be fulfilled.
{
"conditions": [
// one or more relational/conditional expression models
],
"discriminator": "AccessPolicyOrExpressionWebModel" // one of the two described above
}
Relational expressions
Relational expressions let you evaluate items related to the current item.
Parent relation
This relational expression performs a single hop to any parent items that reference the current item via the specified Link attribute.
Its RelationCondition property accepts one conditional expression, which is evaluated against the parent items. The relational expression is fulfilled if any parent items fulfil the condition (logical OR).
{
"attributeCode": "attributes_exampleParentDesignLinkAttribute_62ffa11f29e504015a04d7b0",
"condition": "All", // no other values are currently accepted
"relationCondition": {
// one conditional expression model
},
"discriminator": "AccessPolicyParentRelationExpressionWebModel"
}
Child relation
This relational expression performs a single hop to any child items stored in the specified Link attribute of the current item.
Its RelationCondition property accepts one conditional expression, which is evaluated against the child items. The relational expression is fulfilled if any parent items fulfil the condition (logical OR).
{
"attributeCode": "attributes_myExampleDesignLinkAttribute_63a30437742b9503a172395d",
"condition": "All", // no other values are currently accepted
"relationCondition": {
// one conditional expression model
},
"discriminator": "AccessPolicyChildRelationExpressionWebModel"
}
HasAccess relation
Link attribute contents
This relational expression is fulfilled if the current user has read access to any of the items stored in the specified Link attribute on the current item.
To ensure safe performance and reliability, the Link attribute must never contain more than 100 item IDs.
{
"attributeCode": "attributes_myExampleDesignLinkAttribute_6527107c464545d591710338",
"discriminator": "AccessPolicyHasAccessExpressionWebModel"
}
String attribute reference
Alternatively, this relational expression is fulfilled if the current user has read access to the object (basemap, card, design, interface, layer or workflow) referenced by the specified string attribute on the current item. For the best user experience, ensure the attribute is tagged with the FeatureCode tag.
In the following example, if a user has access to the layers_myBollardsLayer_63593b8a5d6f2603953cb9f7 layer, they will also have access to items of the Bollards design with a Layer Code attribute value matching that string.
{
"attributeCode": "attributes_bollardsLayerCode_63592f1344596f0392ffc966",
"discriminator": "AccessPolicyHasAccessExpressionWebModel"
}
Conditional expressions
Conditional expressions let you compare values against an attribute/property of the current item (or its related parent/child items if used within a relational expression).
String condition
This conditional expression compares one or more supplied strings against an attribute/property of the item. At least one match is required for the condition to be met (logical OR).
{
"valueString": ["Green", "Purple", "Blue"],
"condition": "Equals", // no other values are currently accepted
"itemValue": {
"attributeCode": "attributes_myExampleDesignStringAttribute_643e8b79f68507036f9b1533",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
},
"discriminator": "AccessPolicyStringConditionExpressionWebModel"
}
Link condition
This conditional expression compares one or more supplied item IDs against the contents of a Link attribute on the item, or the item's own ID property (shown below). At least one match is required for the condition to be met (logical OR).
{
"valueLink": ["643e9f7df68507036fa169cc", "643e9ec2f68507036fa0ff6a"], // one or more item IDs
"condition": "Intersects", // no other values are currently accepted
"itemValue": {
"property": "itemID",
"discriminator": "AccessPolicyItemValuePropertyWebModel"
},
"discriminator": "AccessPolicyLinkConditionExpressionWebModel"
}
Geometry condition
This conditional expression compares a Geometry attribute on the item against the supplied geometry value.
Its condition property accepts one of two values:
-
Intersects- does the attribute's geometry overlap the supplied geometry? -
Within- does the attribute's geometry fall completely within the supplied geometry?
{
"itemValue": {
"attributeCode": "attributes_itemsGeometry",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
},
"condition": "Within", // one of the two described above
"valueGeometry": {
"type": "Point",
"coordinates": [-1.516923, 52.288392]
},
"discriminator": "AccessPolicyGeometryConditionExpressionWebModel"
}
Boolean condition
This conditional expression compares a boolean attribute on the item against the supplied boolean value.
{
"itemValue": {
"attributeCode": "attributes_myBooleanAttribute_65e89f72e16307df9c69a065",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
},
"valueBoolean": "true", // or "false"
"condition": "Equals", // no other values are currently accepted
"discriminator": "AccessPolicyBooleanConditionExpressionWebModel"
}
User condition
This conditional expression checks the contents of a Link attribute on the item, which stores items of the Users design. It compares any stored item IDs against the item ID of the Users item that represents the current user.
In other words, is the current user referenced by the specified Link attribute on the item?
Its condition property accepts one of two values:
-
Equals- is the current user stored in the Link attribute? -
NotEquals- is the current user absent from the Link attribute?
{
"itemValue": {
"attributeCode": "attributes_myUsersLinkAttribute_65e8a88ee16307df9c6cb18b",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
},
"userItemValue": {
"property": "ItemId",
"discriminator": "AccessPolicyItemValuePropertyWebModel"
},
"condition": "Equals",
"discriminator": "AccessPolicyUserConditionExpressionWebModel"
}
User group condition
This conditional expression checks if the current user belongs to the group referenced by the specified string attribute on the current item.
It provides a way to perform a tiered user group check: does the current user belong to the access policy's group AND the group referenced by the item?
In the following example, if a user belongs to the userGroups_myLovelyGroup group, they will also have access to items of the Trees design with a User Group Code attribute value matching that string.
{
"itemValue": {
"attributeCode": "attributes_treesUserGroupCode",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
},
"condition": "Equals", // no other values are currently accepted
"discriminator": "AccessPolicyExpressionUserGroup"
}
Enable an access policy
We recommend setting an access policy's enabled property to false while it's being configured. When it's ready to use, you can edit the access policy accordingly.
{
"name": "MyExampleAP",
"enabled": true,
"signature": "64d92cad1669d55s91815269" // to get the current signature, use GET /api/accessPolicy/{code}
}
Item logs
To maintain security, access policies also affect item logs. When a user views an item's details, the audit log won't show events involving items they don't have access to.
For example, imagine an item with a Link attribute. It stores some items that you don't have access to. You won't see them when you examine the Link attribute. You also won't see them in the corresponding create/edit event in the audit log!
Full examples
Here are some full examples for reference and inspiration!
Example 1 - Link attribute check (Logical AND)
Imagine adding this rule to an access policy for the Jobs interface. It will affect all items of designs that implement the Jobs interface (unless those designs have permissions or other access policies set).
The rule allows read access to items whose Priority attribute is High/Critical and the Team attribute is Street Cleaning Team.
{
"userGroups": ["userGroups_StreetCleaners"],
"expression": {
"conditions": [
{
"valueLink": ["643e9f7df68507036fa169cc", "643e9ec2f68507036fa0ff6a"], // items of the Task Priorities design
"condition": "Intersects",
"itemValue": {
"attributeCode": "attributes_tasksPriority", // inherited from the Tasks interface
"discriminator": "AccessPolicyItemValuePropertyWebModel"
},
"discriminator": "AccessPolicyLinkConditionExpressionWebModel"
},
{
"valueLink": ["5e8b237cca31500c941bd16e"], // an item of the Teams design
"condition": "Intersects",
"itemValue": {
"attributeCode": "attributes_tasksTeam", // inherited from the Tasks interface
"discriminator": "AccessPolicyItemValuePropertyWebModel"
},
"discriminator": "AccessPolicyLinkConditionExpressionWebModel"
}
],
"discriminator": "AccessPolicyAndExpressionWebModel"
},
"signature": "62c3105bfab20501542e7134" // to get the current signature, use GET /api/accessPolicy/{code}
}
Example 2 - Geometry attribute check (Logical OR)
Imagine adding this rule to an access policy for a Benches design.
The rule allows read access to items whose Geometry attribute intersects a specific area, or whose Zone Tag attribute equals BUVCYKZY, or both.
{
"userGroups": ["userGroups_BenchViewers"],
"expression": {
"conditions": [
{
"itemValue": {
"attributeCode": "attributes_itemsGeometry", // inherited from the Items interface
"discriminator": "AccessPolicyItemValueAttributeWebModel"
},
"condition": "Intersects",
"valueGeometry": {
"type": "Polygon",
"coordinates": [
[
[-0.710355, 52.634739],
[-0.600632, 52.634739],
[-0.600632, 52.677035],
[-0.710355, 52.677035],
[-0.710355, 52.634739]
]
]
},
"discriminator": "AccessPolicyGeometryConditionExpressionWebModel"
},
{
"valueString": ["BUVCYKZY"],
"condition": "Equals",
"itemValue": {
"attributeCode": "attributes_BenchesZoneTag_643e8b79f68507036f9b1533",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
}
}
],
"discriminator": "AccessPolicyOrExpressionWebModel"
},
"signature": "6315c78cb7a8fc016dc79eec" // to get the current signature, use GET /api/accessPolicy/{code}
}
Example 3 - String attribute check (Parent relation)
Imagine adding this rule to an access policy for a Playground Defects design.
The rule allows read access to items with a parent asset, whose Owner attribute equals Causeway Technologies. The parent relation happens via the Defects Link attribute on the parent item (which is inherited from the Defects Assignable interface).
{
"userGroups": ["userGroups_PlaygroundDefectViewers"],
"expression": {
"attributeCode": "attributes_defectsAssignableDefects",
"condition": "All",
"relationCondition": {
"valueString": ["Causeway Technologies"],
"condition": "Equals",
"itemValue": {
"attributeCode": "attributes_playgroundsOwner_6336ef3fe6c5cf0394bd0f25",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
}
"discriminator": "AccessPolicyStringConditionExpressionWebModel"
},
"discriminator": "AccessPolicyParentRelationExpressionWebModel"
},
"signature": "6321e19d1890d60158d30e01" // to get the current signature, use GET /api/accessPolicy/{code}
}
Example 4 - User group check (Child relation)
Imagine adding this rule to an access policy for a Car Parks design.
The rule allows read access to specific child items stored in the Tasks Link attribute of the current item, where the current user belongs to the group referenced by the User Group Code attribute on each task.
To have access, a user must belong to the access policy's user group AND the group referenced on each child item!
In this imaginary scenario, car park tasks are performed by internal workers and third party contractors. Therefore, when users view a Car Parks item, this rule ensures they only see the linked task items meant for their group.
{
"userGroups": ["userGroups_CarParkViewers"],
"expression": {
"attributeCode": "attributes_tasksAssignableTasks", // inherited from the Tasks Assignable interface
"condition": "All",
"relationCondition": {
"itemValue": {
"attributeCode": "attributes_carParkTasksUserGroupCode",
"discriminator": "AccessPolicyItemValueAttributeWebModel"
},
"condition": "Equals",
"discriminator": "AccessPolicyExpressionUserGroup"
},
"discriminator": "AccessPolicyChildRelationExpressionWebModel"
},
"signature": "653f80d90b04ec8fb2cbc754" // to get the current signature, use GET /api/accessPolicy/{code}
}