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.

example

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.

  1. Open Access Policies tab.

    open access policies
  2. Click "Create Policy" button.

    create policy button
  3. Provide a name for the access policy, and add configured validators.

    configure validators
  4. Save Access Policy.

    save 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:

  1. Click the gear icon to the right of the validator configuration.

    gear
  2. Choose a custom recovery from the predefined list.

    custom recovery
  3. Update the access policy.

    update

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

status inactive recovery
Figure 1. recovery view

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

validators

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

Address validator syntax
{
  "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:

address

or if you prefer, you can find the JSON representation below:

policy with address validator
{
  "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

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

    address md logs
  3. 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.

Auth events sequence syntax
{
  "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

Validator configuration JSON
{
  "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:

Validator configuration JSON
{
  "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.

Policy reference syntax
{
  "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:

reference

or if you prefer, the JSON representation is below:

Sample policy with session validator
{
  "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.

Session validator syntax
{
  "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)

Within comparator example
{
  "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'.

Session validator syntax
{
  "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':

Session validator syntax
{
  "name":"user",
  "conf": {
    "fields": [
      {
        "field": "status",
        "comparator": "equals",
        "value": "active"
      }
    ]
  }
}

Using the Device validator we could check if the device type equals 'browser':

device validator syntax
{
  "name":"device",
  "conf": {
    "fields": [
      {
        "field": "type",
        "comparator": "equals",
        "value": "browser"
      }
    ]
  }
}

Using the Device-relation validator we could check if user-device relation equals 'registered'

device-relation validator syntax
{
  "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.

device-relation descriptor
{
  "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

jdoe@syntegrity.com

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

jdoe@syntegrity.com

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:

sample policy

or if you prefer, the JSON representation is below:

Sample policy with session validator
{
  "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.

Session validator syntax
{
  "name":"session-presence",
  "conf": {}
}

Example

Let’s create a policy which checks if a session exists.

We can use the Cloudentity UI for that:

session presence

or if you prefer, you can find the JSON representation below:

Session presence policy
{
  "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:

True validator syntax
{
  "name": "true",
  "conf": {}
}
False validator syntax
{
  "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:

conditional

or the JSON representation:

Conditional example
{
  "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.

User presence validator syntax
{
  "name":"user-presence",
  "conf": {}
}

The User Absence Validator verifies that a user does not exist based on given identifier*.

User presence validator syntax
{
  "name":"user-absence",
  "conf": {}
}

identifier - depends on SLA configuration, it could be for instance:

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:

  • The User Presence Validator succeeds only if the user is found. It fails if it is not found or an error occurs.

  • The User Absence Validator succeeds only if the user is not found. It fails if it is found or an error occurs.

Example

Let’s create a policy which checks if user exists.

We can use the Cloudentity UI for that:

user presence

or if you prefer, you can find the JSON representation below:

User presence policy
{
  "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:

Sample validate policy request
{
  "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:

Url Configuration Example
{
    "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

Url Configuration Error
{
    "reason": "Invalid regexes",
    "invalidRegexes": [".*("]
}

In case an empty list was provided, following error is returned

Url Configuration Error - Empty List
{
    "reason": "Empty regexes"
}
Policy validation

When validating a policy with any of those validator, validation data looks as follows:

Url Validation Example
{
    "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.

Cross-Context Validator Syntax (comparison of the wire transfer limit from the request body against the limit storted as a user attribute)
{
  "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.

Default structure of attributes that can be sent by the Cloudentity API GW to the Authorization Service including sample values in the body
{
  "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