Cloudentity’s AuthZ service provides a Single Source of Truth for security policy management Users, Services and Things. The flexible API utilizes a pluggable validation architecture to support hybrid authorization models that span across roles based, attribute based, and risk based, micro-segmentation. Policies are applicable for both inbound and outbound transactions (ingress and egress) and provides context-based authorization including user, device, application, transaction, and location attributes.
Overview
The Authorization engine allows configuration and validation of access policies. An access policy can model authentication and authorization scenarios for resources protected by Cloudentity. Access policies are defined in terms of policy validators, which verify that the system, user, application or other object is in a required state.
Cloudentity provides a number of out-of-the-box policy validators you can use to implement attribute-, role- or risk-based access control, as well as user device, session or context data verification. But the AuthZ Service is also extensible. New policy validators can be implemented and used in access policy definitions. Moreover, you can add/remove policy validators to/from an AuthZ Service deployment with zero downtime.
Cloudentity AuthZ service can be utilized in collaboration with the MicroPerimeter™ Sidecar, MicroPerimeter™ Gateway, Web Access Gateway (traditional HTTP reverse proxy) or as a standalone service directly integrated with 3rd party applications via REST APIs.
Internally in the Cloudentity Platform the AuthZ Service is working in concert with MicroPerimeter™ Security Gateway to secure the all the Business APIs.
Example scenario
Need to secure an endpoint of a service by enforcing the following rules:
-
The user must be active
-
The user must have successful SMS code verification
In order to do so, create an access policy that is defined with two policy validators:
-
User Validator — to make sure the user is active
-
Session Validator — to make sure the SMS code was verified
When the user calls this secured endpoint — providing their own session token — the service needs to call the AuthZ Service to validate the access policy defined, forwarding the user’s session token in the request. If the AuthZ Service returns a positive response, the service can perform the requested action. However, if the AuthZ Service response is negative, the access policy is invalid for the user in question and the action should not be performed.
Defining Access Policy
An access policy definition requires a unique name and a list of policy validators to be evaluated upon a policy validation request.
The policy can be created using:
-
API call to the Authorization Service APIs
-
Using policy editor in the Cloudentity UI or through local Microservice Security Admin UI
-
In the datastore when KV like Consul is used - directly or from version control system like git
The policies can be global or associated with specific applications that are owned by an organization.
The screenshots below show how to configure a global access policy using the Cloudentity UI. The similar process can be followed for creation of a policy for an application in the applications tab.
-
Open Access Policies tab.
-
Click "Create Policy" button.
-
Provide a name for the access policy, and add configured validators.
-
Save Access Policy.
You can also use the AuthZ Service API to register an access policy.
Each validator description has three attributes:
-
name: The unique identifier of validator. For list of all validators, see Policy Validators.
-
conf: The actual configuration of validator. See the documentation of a specific validator for more details.
-
recovery: Optional. The recovery will be returned by the validator in the case of a negative authorization response. See below.
Adding recovery to a policy validator
When a policy validator returns a negative authorization response, it may provide an optional list of recovery items. The consumer of the policy validation endpoint should be able to react to any received recovery items, e.g. by providing additional authentication steps for the user. A recovery item might be defined programatically in the validator’s implementation (e.g. auth-event-sequence validator) or configured in the access policy definition.
The following screenshots show how to configure recovery items for a policy validator using the Cloudentity UI:
-
Click the gear icon to the right of the validator configuration.
-
Choose a custom recovery from the predefined list.
-
Update the access policy.
Responding to Recovery in an Authentication Policy
A system which enforces an AuthZ access policy must perform a feedback loop on the AuthZ policy validation API call until it succeeds; this enables a user to eventually achieve the status required to access the protected resource. The policy validation API is exposed at:
POST /authz/policy/{policyName}/validate
This endpoint requires a session token in a request header. This API allows the AuthZ Service to check if the session info satisfies a given policy.
In an Cloudentity deployment, an access policy called FULLY_AUTHENTICATED is provided by default to accommodate general authentication. Therefore, the following endpoint would be used to validate a session against the FULLY_AUTHENTICATED policy:
POST /authz/policy/FULLY_AUTHENTICATED/validate
The definition of an example FULLY_AUTHENTICATED policy is shown below:
{
"policyName": "FULLY_AUTHENTICATED",
"validators": [
{
"name": "conditional",
"conf": {
"branches": [
{
"if": [
{
"name": "auth-event-sequence",
"conf": {
"criteria": [
{
"eventId": "IdentifierPasswordAuthentication",
"eventType": "AuthN",
"success": true
}
]
}
},
{
"name": "user",
"conf": {
"fields": [
{
"field": "status",
"comparator": "equals",
"value": "active"
}
]
},
"recovery": [
{
"id": "User.Inactive",
"type": "StaticErrorMessage"
}
]
},
{
"name": "session",
"conf": {
"fields": [
{
"field": "defaultCustomerStatus",
"comparator": "equals",
"value": "active"
}
]
}
}
],
"then": [
{
"name": "conditional",
"conf": {
"branches": [
{
"if": [
{
"name": "user",
"conf": {
"fields": [
{
"field": "mfaMethod",
"comparator": "equals",
"value": "GOOGLE_AUTHENTICATION"
}
]
}
}
],
"then": [
{
"name": "user",
"conf": {
"fields": [
{
"field": "googleAuthSecretAccepted",
"comparator": "equals",
"value": "true"
},
{
"field": "eulaApproval",
"comparator": "equals",
"value": "true"
}
]
}
},
{
"name": "auth-event-sequence",
"conf": {
"criteria": [
{
"eventId": "TotpAuthentication",
"eventType": "MFA",
"success": "true"
}
]
}
}
]
},
{
"if": [
{
"name": "user",
"conf": {
"fields": [
{
"field": "mfaMethod",
"comparator": "equals",
"value": "NONE"
}
]
}
}
],
"then": [
{
"name": "user",
"conf": {
"fields": [
{
"field": "eulaApproval",
"comparator": "equals",
"value": "true"
}
]
}
}
]
}
]
}
}
]
}
]
}
}
],
"type": "authentication"
}
That’s a huge piece of JSON, so let’s break it down into small pieces. The single, most important thing here is that the entire policy is made of validator objects.
Validator Object
A validator object is a building block of a policy, which defines what each policy validator should do.
Taken from a validator object in the FULLY_AUTHENTICATED policy example:
{
"name": "user" // validator ID
"conf": { // configuration for this validator
"fields" : [
{
"field": "status" // an attribute to check
"comparator": "equals" // equals, lessThan, greaterThan, contains, etc.
"value": "active" // value to be matched against comparator
}
]
},
"recovery" : [ // optional
{
"id": "User.Inactive" // recovery object ID to be matched with recovery.json in Authentication app
"type" : "StaticErrorMessage" // type of view page
}
]
}
In this example, the user
validator checks if the user (who is attempting to log in) has an attribute named status
that is equal to "active". This can be modified to check if a user has a firstName
that equals to "John", or age
that is less than 18, and so on.
Recovery
When a validator fails, a recovery is returned. Recovery is an object attribute in a validator object, guiding the UI or other client application to the next action if a validation step fails. The id and type attributes can be used to match a specific action if a configuration is defined in the UI application. For example, the UI application could contain a recovery configuration file which contains the following:
{
"recovery": {
"User.Inactive": {
"view": "StaticMessageView",
"contentTitle": "Your account is not active",
"contentMessage": "Please check your email to activate"
},
"IdentifierPasswordAuthentication": {
"view": "IdentifierPasswordView"
},
"KnowledgeBasedAuthentication": {
"view": "KBAView"
}
}
}
When a recovery object is returned from the policy validation API, the UI application can match action items by corresponding ID to render the desired view, title, and message. In the above example, IdentifierPasswordView.html may show fixed content, while StaticMessageView.html may dynamically show desired title and message content using data binding. It is up to the UI developer to be flexible to meet any desired business needs.
Recovery for Common Scenarios
Here are some examples.
-
Action: Describes the background of the scenario
-
Request Payload: Request body sent to AuthZ’s policy validation API
-
Response: Response from the API
-
Recovery View & API: An example view rendered by UI app and an API endpoint to recover
Action | Request Payload | Response | Recovery View & API |
---|---|---|---|
1. On load of login page |
{} |
{ "code": "Authentication.Unauthenticated", "message": "Unauthenticated", "details": { "recovery": [ { "id": "IdentifierPasswordAuthentication", "type": "AuthN" }, { "id": "User.Inactive", "type": "StaticErrorMessage" } ] } } |
Recovery: IdentifierPasswordAuthentication There are two recovery objects returned. In this case, the UI application may choose which recovery action to trigger. A common use case is to choose the first in the list. Recovery APIs: /ui/sla/authn/identifierpassword (recovery event API) |
2. Inactive user |
{ "identifier": "foobar", "password": "p@ssw0rd!", "device": { device data } } |
{ "code":"Authentication.Unauthenticated", "message":"Unauthenticated", "details": { "recovery": [ { "id":"User.Inactive", "type":"StaticErrorMessage" } ] } } |
Recovery: StaticErrorMessage The UI application may define a dynamic view page to render a specific message see recovery view below |
3. Password recovery submission |
{} |
Status Code: 200 OK |
Register/Update/Delete Policies
An admin with the entitlement ADMIN_MANAGE_POLICY can create/modify/delete policies.
Access Policy Validation
To validate an access policy, call (with an optional session token):
POST /policy/{policyName}/application/{applicationId}/validate
for application specific policy validation
OR
POST /policy/{POLICY_NAME}/validate
for global policy validation.
When the policy validation endpoint is called, all of the policy validators defined in the access policy configuration are executed in parallel. If at least one validator returns a negative authorization response, the access policy validation response is negative. Otherwise, the policy validation response is positive.
The Authorization Service integrates stores and manages policies in Cassandra or LDAP through data access layer. Some contextual data can be delivered to the PDP in the request by the policy enforcement point. For other data, the Authorization Service interacts with other systems to provide it so the validators can be executed upon it. Validators use that data to drive their authorization decision. The AuthZ Service caches context data shared by different validators during a single access policy validation request.
The following table lists several policy validators and the corresponding systems that provide context data:
Policy validator | External system |
---|---|
User |
User service |
Session |
Session service |
Session presence/absence |
Session service |
Auth Events Sequence |
Hazelcast instance storing auth events |
Device |
Device Service |
Address |
Stats Service |
Occasionally, there’s a need to create policy that requires extrnal data that is by default not managed by Cloudentity. There are three basic strategies to address such cases:
-
Inject the data required by a policy in the request to the validation API or configure the PEP (e.g. API GW) to do it,
-
Let Cloudentity manage the data or store the copy of the data in Cloudentity (e.g. as part of user, customer, session),
-
Create a custom validator that makes a call to the external system managing the data. See the description of the custom validator in a separate section below.
Policy Validators
Policy validators are the building blocks of access policies. Each validator returns a decision regarding whether access should be granted to secured resource. The decision is based on validator-specific information, including user data, device data, and any attributes or authentication/authorization events present in the current session.
Some policy validators require configurations for each instance; such configurations are provided in the access policy definition to which the validator belongs. Example configurations include which attribute values should be set in the current session (for a Session Validator), or which auth events should have occurred (for an Auth Events Validator).
Below there’s a description of multiple policy validators that are performing specific checks (e.g. user attributes check) that contain specific features and corresponding editor for such specifc checks. Apart of developer and user experience driven specific validators Cloudentity offers the general ABAC validator called Cross-Context Validator that allows comparison of any attribute available in the context available to the PDP with any other attribute present in the context.
In addition, the policy can contain custom validator creation of which is described separately.
Address Validator
The Address validator checks if a user authenticated from a specific location. Currently we have 4 address matchers implemented:
-
country
-
region
-
city
-
postal-code
{
"name": "address",
"conf": {
"match": "city" # one of: country, region, city, postal-code
}
}
Example
Let’s create a policy which checks if a user is allowed to withdraw money from an ATM only from a specific city.
We can use Cloudentity UI for that:
or if you prefer, you can find the JSON representation below:
{
"policyName": "ATM_WITHDRAW",
"validators": [
{
"name": "address",
"conf": {
"match":"city"
}
}
]
}
Once the policy is created, we can make a Validate Policy call with the session token in a header and the following request body:
{
"address": {
"country": "United States",
"region": "VA",
"city": "Ashburn"
}
}
How it works
-
Whenever a user authenticates, we are storing his IP address in SLA audit logs:
Audit logs{ "timestamp":"2017-06-29T12:21:31,183Z", "external_id":"", "internal_id":"", "local_id":"", "event":{ "action":{ "action":"com.syntegritynet.overlay.james.logic.authn.IdentifierPasswordAuthentication" }, "request":{ "ip":"54.172.92.11, 10.50.200.221", "ref":"/authn/identifierpassword", "method":"POST", "status":"created", "timestamp":1498738891180 }, "user":{ "uid":"iiam@syntegrity.com", "cid":"syntegrity", "uuid":"de8dbe92-c0f5-4dd7-8d03-63abc04aa1cc", "authLevel":"0", "authenticationMethod":"com.syntegritynet.overlay.james.logic.authn.IdentifierPasswordAuthentication" }, "details":{}, "date":"Thu, 29 Jun 2017 12:21:31 +0000", "id":"7b829e6f-0e99-46f8-91ed-7b5d679c092f" } }
-
The MD Logs collector grabs the SLA audit logs and sends them to the MD Logs datastore (Elasticsearch). At this point Elasticsearch has information about the country, region, city and postal code — if can be determined from the IP address:
-
When validating the ATM_WITHDRAW policy, the Address validator is making a call to the Stats Service (which gets data from the MD Logs database). It then makes the decision based on whether the address given in the validation request matches the location of the user provided during the authentication process.
Auth Events Sequence Validator
The Auth Events Sequence Validator checks whether a sequence of auth events, matching given list of criteria, have occurred in current session.
The criteria in an Auth Events Sequence Validator have the following parameters:
Criteria | Configuration key | Data type | Description |
---|---|---|---|
type (required) |
eventType |
String |
Type of the auth event, e.g. "MFA", "AuthN" |
id |
eventId |
String |
Identifier of the auth event, e.g. "TotpAuthentication", "FederatedAuthentication", "IdentifierPasswordAuthentication" |
success (required, default true) |
success |
Boolean |
Defines whether the attempted auth action succeeded |
occurred in last X seconds (required, default infinity) |
in_last |
Integer |
Defines how old the auth event is allowed to be, e.g. the auth event should have happened within the last 180 seconds |
When specifying the matching criteria for an auth events sequence, the order matters. For example, if we specify criteria matching auth events [X, Y], but the actual events occurred in a different order [Y, X], then the validator returns a negative response. If the ordering of the auth events does not matter in the policy you are building, add multiple Auth Events Sequence Validators, each for single auth event.
It is, however, not required that there be no other auth events in the sequence. For example, if we specify criteria matching auth events [X, Y], but the actual events were [A, X, B, Y, C], then the validator returns a positive response.
In the example below, we are checking that there was an auth event AuthN/IdentifierPasswordAuthentication during the current session (no in_last criteria has been specified). Then we are checking for an auth event MFA/TotpAuthentication in the last 900 seconds.
{
"name": "auth-event-sequence",
"conf": {
"criteria": [
{
"eventType": "AuthN",
"eventId": "IdentifierPasswordAuthentication"
},
{
"eventType": "MFA",
"eventId": "TotpAuthentication",
"in_last": 900
}
]
}
}
Conditional Validator
The Conditional Validator allows the definition of complex authorization scenarios based on results from other policy validators. It handles the standard if-else statement flow.
Example
if (validator-A passes) then { check validator-B and validator-C }
else if (validator-D passes) then { check validator-E }
In this flow, the Conditional Validator first checks the validation response from validator-A
.
If the response is positive, it checks the responses from validator-B
and validator-C
.
If validator-B
and validator-C
both return positive responses, the Conditional Validator returns a positive response as well;
otherwise it returns a negative response. In either case, the Conditional Validator ends execution.
However, if validator-A
returns a negative response, then validator-D
is executed. If it passes, the response of validator-E
is returned as the response of the Conditional Validator.
If validator-D
returns a negative response and there is no more else-if statements, the Conditional Validator ends
execution and returns a negative authorization decision.
Configuration
{
"branches": [
{
"if": [
{
"name": "validator-A",
"conf": { "some-param": "some-value" }
}
],
"then": [
{
"name": "validator-B",
"conf": { "some-param": "some-value" }
},
{
"name": "validator-C"
"conf": { "some-param": "some-value" }
}
]
},
{
"if": [
{
"name": "validator-D",
"conf": { "some-param": "some-value" }
}
],
"then": [
{
"name": "validator-E",
"conf": { "some-param": "some-value" }
}
]
}
]
}
The definitions of policy validators within the if and then fields follow the same rules as any top-level definition of a policy validator.
Modeling the else clause
The validator configuration syntax does not support an else clause directly. However, we can use [True validator] to model it.
Suppose we want to have the following logic expression:
if (validator-A passes) then { check validator-B } else { check validator-C) }
To model it with a Conditional Validator, we need following configuration:
{
"branches": [
{
"if": [
{
"name": "validator-A",
"conf": { "some-param": "some-value" }
}
],
"then": [
{
"name": "validator-B",
"conf": { "some-param": "some-value" }
}
]
},
{
"if": [
{ "name": "true", "conf": {} }
],
"then": [
{
"name": "validator-C",
"conf": { "some-param": "some-value" }
}
]
}
]
}
Policy Reference Validator
The Policy Reference Validator can be used to embed an existing policy in your new policy without a need to duplicate policy logic.
In order to use this validator, you must provide name: embedded
, and provide the policy
name which you would like to use in the conf
section.
{
"name": "embedded",
"conf": {
"policy": "POLICY_NAME"
}
}
Example
Let’s create a policy called SELF_CHANGE_PASSWORD
which:
-
validates the
FULLY_AUTHENTICATES_POLICY
using the Policy Reference validator -
checks if the session attribute
entitlements
contains the entitlement 1SELF_CHANGE_PASSWORD` -
checks if the user performed the TOTP operation within the last 5 minutes:
You could use the Cloudentity Access Policy editor to model such a policy:
or if you prefer, the JSON representation is below:
{
"policyName":"SELF_CHANGE_PASSWORD",
"validators":[
{
"name":"embedded",
"conf":{
"policy":"FULLY_AUTHENTICATED"
}
},
{
"name":"session",
"conf":{
"fields":[
{
"field":"entitlements",
"comparator":"contains",
"value":[
"SELF_CHANGE_PASSWORD"
]
}
]
}
},
{
"name":"auth-event-sequence",
"conf":{
"criteria":[
{
"eventType":"MFA",
"eventId":"TotpAuthentication",
"success":true,
"in_last":300
}
]
}
}
]
}
Session, User and Device Validators
The Session, User and Device Validators can be used to check if the session / user / device attributes of an authenticated user meet the given conditions.
In order to use the Session / User / Device Validators you must provide name: "session" / "user" / "device", and provide at least one object in the "conf" section describing the session / user / device field to compare.
{
"name":"session",
"conf": {
"fields": [
...
]
}
}
Each field consists of:
-
field – the name of a session or user attribute: session attributes, user attributes, device attributes
-
comparator – one of: equals, contains, lessThan, greaterThan, present, absent, within**
-
value – the value of a field to compare using the comparator*
Note
|
when using the "contains" comparator you could set multiple values by providing an array, for example: "value": ["value1","value2"] when using the "within" comparator field must be a date in ISO8601 (yyyy-MM-dd’T’HH:mm:ss.SSSX for ex. 2017-09-15T15:53:00.000Z) and value must be duration in ISO8601 (for ex. P4M stands for 4 months; PT4M stands for 4 minutes) |
{
"name": "user",
"conf": {
"fields": [
{
"field": "pwdLastChanged",
"comparator": "within",
"value": "P150D"
}
]
}
}
In the example below we are checking if the session attribute defaultCustomerStatus is set to 'active'.
{
"name":"session",
"conf": {
"fields": [
{
"field": "defaultCustomerStatus",
"comparator": "equals",
"value": "active"
}
]
}
}
Using the User validator we could check if the user attribute status is set to 'active':
{
"name":"user",
"conf": {
"fields": [
{
"field": "status",
"comparator": "equals",
"value": "active"
}
]
}
}
Using the Device validator we could check if the device type equals 'browser':
{
"name":"device",
"conf": {
"fields": [
{
"field": "type",
"comparator": "equals",
"value": "browser"
}
]
}
}
Using the Device-relation validator we could check if user-device relation equals 'registered'
{
"name":"device-relation",
"conf": {
"fields": [
{
"field": "Authentication",
"comparator": "equals",
"value": "registered"
}
]
}
}
In addition to above, device and device-relation validators make calls to external Device Service in order to collect data to compare with configured validator field value.
This is the reason why in descriptor config of device validator we have given 'basePath' of Device Service API and connection parameters, e.g.
{
"main": "io.orchis.services.authz.policyvalidator.device.DeviceRelationValidator",
"options": {
"config": {
"deviceProvider": {
"ssl": false,
"hostname": "local.orchis.syntegrity.com",
"port": 8090,
"connectionTimeout": 3000,
"basePath": "/api",
"maxConnectionPoolSize": 5,
"keepAlive": true
}
}
}
}
List of session attributes
Below you can find a list of session attributes* with their data type and an example:
Attribute name | Data type | Example |
---|---|---|
firstName |
string |
John |
lastName |
string |
Doe |
uid |
string |
|
uuid |
string |
f0ff9aa2-3ef1-4374-a401-ca527705f822 |
customer |
string |
syntegrity |
defaultCustomerStatus |
string |
active |
defaultCustomer |
string |
syntegrity |
customerAlias |
string |
Syntegrity |
mfaMethod |
string |
NONE |
eulaApproval |
string |
true |
googleAuthSecretAccepted |
string |
false |
authLevel |
integer |
35 |
locale |
string |
en-US |
deviceUuid |
string |
66706aed-7000-4949-93b4-9718cc5dac9c |
entitlements |
array of string |
[ "SELF_ACCEPT_USER_EULA", "SELF_CONFIRM_AUTH_SECRET", "SELF_INVALIDATE_DEVICE_SESSIONS", "SELF_FORGET_DEVICE", "SELF_GET_AUTH_SECRET", "SELF_UPDATE_USER", "SELF_LIST_DEVICES", "SELF_LIST_USER_CUSTOMERS", "SELF_GET_USER", "SELF_GET_CUSTOMER", "SELF_CHANGE_PASSWORD", "SELF_RESET_AUTH_SECRET" ] |
entitlementGroups |
array of string |
[ "SAMPLE_GROUP" ] |
-
session attributes may very depending on LLA and SLA configurations
List of user attributes
Below you can find a list of user attributes with their data type and an example:
Attribute name | Data type | Example |
---|---|---|
firstName |
string |
John |
lastName |
string |
Doe |
uid |
string |
|
uuid |
string |
f0ff9aa2-3ef1-4374-a401-ca527705f822 |
customer |
string |
syntegrity |
customers |
array of string |
[ "syntegrity" ] |
mfaMethod |
string |
NONE |
eulaApproval |
string |
true |
eulaRevision |
string |
1.0 |
entitlements |
array of string |
[ "SELF_ACCEPT_USER_EULA", "SELF_CONFIRM_AUTH_SECRET", "SELF_INVALIDATE_DEVICE_SESSIONS", "SELF_FORGET_DEVICE", "SELF_GET_AUTH_SECRET", "SELF_UPDATE_USER", "SELF_LIST_DEVICES", "SELF_LIST_USER_CUSTOMERS", "SELF_GET_USER", "SELF_GET_CUSTOMER", "SELF_CHANGE_PASSWORD", "SELF_RESET_AUTH_SECRET" ] |
-
user attributes may very depending on LLA and SLA configurations
List of device attributes
Attribute name | Data type | Example |
---|---|---|
type |
string |
browser, android |
properties.platform.name |
string |
Chrome |
properties.platform.version |
string |
59 |
properties.build.board |
string |
?? |
properties.details.screenColorDepth |
string |
24 |
properties.details.screenHeight |
string |
1053 |
properties.details.screenWidth |
string |
2560 |
properties.details.installedPlugins |
array of string |
[ "Widevine Content Decryption Module::Enables Widevine licenses for playback of HTML audio/video content. (version: 1.4.8.984)::application/x-ppapi-widevine-cdm~", "Shockwave Flash::Shockwave Flash 26.0 r0::application/x-shockwave-flashswf,application/futuresplashspl", "Chrome PDF Viewer::::application/pdf~pdf", "Native Client::::application/x-nacl,application/x-pnacl", "Chrome PDF Viewer::Portable Document Format::application/x-google-chrome-pdf~pdf" ] |
properties.details.installedFonts |
array of |
[ "Andale Mono", "Arial", "Arial Black", "Arial Hebrew", "Arial Narrow" ] |
properties.details.timezone |
string |
-120 |
properties.details.userAgent |
string |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 |
properties.details.platform |
string |
MacIntel |
properties.details.os.name |
string |
Mac OS |
properties.details.os.version |
string |
10.11.3 |
properties.details.latitude |
string |
17.003857999999997 |
properties.details.longitude |
string |
51.1110401 |
-
device attributes may very depending on AuthN, SLA and Device Service configurations
List of device-relation attributes
Attribute name | Data type | Example |
---|---|---|
Authentication |
String |
not recognized |
Authentication |
String |
recognized |
Authentication |
String |
verified |
Those example device-relation attributes may have different names and values
Sample Policy
Let’s create a policy which uses the Session, User and Device validators to check the following conditions:
-
session attribute
defaultCustomerStatus
equals active -
session attribute
authLevel
is greater than 30 -
session attribute
entitlements
contains entitlement SELF_GET_USER and SELF_GET_CUSTOMER -
user attribute
status
equals active -
device attribute
type
equals browser, and device properties.platform.name equals Chrome, and properties.platform.version > 59
You could use the Cloudentity Access Policy editor to model such a policy:
or if you prefer, the JSON representation is below:
{
"policyName":"SAMPLE_POLICY",
"validators":[
{
"name":"session",
"conf":{
"fields":[
{
"field":"defaultCustomerStatus",
"comparator":"equals",
"value":"active"
},
{
"field":"authLevel",
"comparator":"equals",
"value":"30"
},
{
"field":"entitlements",
"comparator":"contains",
"value":[
"SELF_GET_USER",
"SELF_GET_CUSTOMER"
]
}
]
}
},
{
"name":"user",
"conf":{
"fields":[
{
"field":"status",
"comparator":"equals",
"value":"active"
}
]
}
},
{
"name":"device",
"conf":{
"fields":[
{
"field":"type",
"comparator":"equals",
"value":"browser"
},
{
"field":"properties.platform.name",
"comparator":"equals",
"value":"Chrome"
},
{
"field":"properties.platform.version",
"comparator":"greaterThan",
"value":59
}
]
}
}
]
}
Session Presence Validator
The Session Presence Validator checks if a session exists.
{
"name":"session-presence",
"conf": {}
}
Example
Let’s create a policy which checks if a session exists.
We can use the Cloudentity UI for that:
or if you prefer, you can find the JSON representation below:
{
"policyName": "SESSION_PRESENCE",
"validators": [
{
"name": "session-presence",
"conf": {}
}
]
}
Once the policy is created, we can make a Validate Policy call with the session token in a header (body is not required) to check if the session is present or not.
True and False Validators
The True and False Validators can be used to:
-
create a policy which always passes or always fails — such a policy can be used for testing purposes, and later could be enhanced with more advanced logic
-
to make a decision in a conditional validator branch (see Conditional example)
In order to use the True / False Validator, you need to provide the name: "true" / "false" and an empty config object:
{
"name": "true",
"conf": {}
}
{
"name": "false",
"conf": {}
}
Conditional example
In this example we will create a policy which checks if a user is using mfaMethod. In the first conditional validator, we are checking if mfaMethod equals 'NONE'; if it is true we are failing the policy using the False validator with custom recovery: 'mfa'. In second conditional, if mfaMethod equals 'GOOGLE_AUTHENTICATOR', we use the True validator to indicate that the user is using mfa (in which case the policy will succeed).
To model this policy we can use the Cloudentity UI:
or the JSON representation:
{
"policyName": "IS_MFA",
"validators": [
{
"name": "conditional",
"conf": {
"branches": [
{
"if": [
{
"name": "session",
"conf": {
"fields": [
{
"field": "mfaMethod",
"comparator": "equals",
"value": "NONE"
}
]
}
}
],
"then": [
{
"name": "false",
"conf": {},
"recovery": [
{
"type": "mfa"
}
]
}
]
},
{
"if": [
{
"name": "session",
"conf": {
"fields": [
{
"field": "mfaMethod",
"comparator": "equals",
"value": "GOOGLE_AUTHENTICATOR"
}
]
}
}
],
"then": [
{
"name": "true",
"conf": {}
}
]
}
]
}
}
]
}
User Existence Validators
Two User Existence Validators exist: User Presence Validator, and User Absence Validator.
The User Presence Validator checks if user exists based on given identifier.
{
"name":"user-presence",
"conf": {}
}
The User Absence Validator verifies that a user does not exist based on given identifier*.
{
"name":"user-absence",
"conf": {}
}
identifier - depends on SLA configuration, it could be for instance:
-
uid: iiam@syntegrity.com
-
uuid: 711f31b6-439a-4a34-afd2-51fe4c6903ac
-
email: iiam@syntegrity.com
-
mobile: 1-888-796-8341
An error will cause either validation to fail.
Warning
|
The two User Existence Validators are not strictly inverses — an error in either case will result in validation failure. To summarize:
|
Example
Let’s create a policy which checks if user exists.
We can use the Cloudentity UI for that:
or if you prefer, you can find the JSON representation below:
{
"policyName": "USER_PRESENCE",
"validators": [
{
"name": "user-presence",
"conf": {}
}
]
}
Once the policy is created, we can check existence of a user 'j.doe@syntegrity.com' by making a validate policy call with following request body:
{
"user-presence": {
"identifier": "iiam@syntegrity.com"
}
}
URL Validators
Two kinds of URL validators are available: * Whitelist Url Validator * Blacklist Url Validator
They operate in a similar way but the authorization decisions made by those validators differ.
Those can be useful to define checks on redirection URLs, validate user provided data against a list of known URLs etc.
API details and examples
Policy registration
When registering a policy with any of those validators, the expected object looks as follows:
{
"regexes": [".*\\.org", ".*\\.mydomain\\.com"]
}
Which represents URLs ending with .org or URLs ending with .mydomain.com
Regexes provided have to be valid Java regex patterns
In case some of the regexes are invalid an error message is returned with the following contents
{
"reason": "Invalid regexes",
"invalidRegexes": [".*("]
}
In case an empty list was provided, following error is returned
{
"reason": "Empty regexes"
}
Policy validation
When validating a policy with any of those validator, validation data looks as follows:
{
"url": "http://random.org"
}
Whitelist Url Validator
Validator name: whitelist-url
The idea behind a whitelist Url validator is to check if a provided URL matches at least one of the defined regular expressions.
Note
|
With the examples shown here, this validator responds with Authorization Success as 'http://random.org' matches '.*\\.org' |
Blacklist Url Validator
Validator name: blacklist-url
The idea behind a whitelist Url validator is to check if a provided URL doesn’t match any one of the defined regular expressions.
Note
|
With the examples shown here, this validator responds with Authorization Failure as 'http://random.org' matches '.*\\.org' |
Cross-Context Validator
The cross-context validator is a general ABAC validator that allows comparison of any attribute with any other attribute avaiable in the context.
The example below shows the structure of the cross-context validator configuration.
{
"name":"cross-context",
"conf": {
"fields":[
{
"field": "user.transferLimit",
"comparator": "lessThan",
"value": "$request.body.amount"
}
]
}
}
In the example above user attribute is compared with the request body attribute. The request body attribute may be passed by the Cloudentity API GW if the API GW is configured appropriately to send request context for a given endpoint call. The example below shows what other contextual attributes can be used when Authorization Service is used in conjunction with the Cloudentity API GW.
{
"request": {
"body": {
"from": "account-a",
"to": "account-b"
"amount": 100
},
"headers": ...,
"url": ...,
"method": ...,
"pathParams": ...,
"queryParams": ...,
"cookies": ...
}
}
Apart of the requests from the headers by default the following entities and its attributes can be used:
-
session
-
customer
-
request
-
authn
Version information
Version: 1.18