# Policy Statement

The policy statement defines one or more resources that the application can work within the current context. In other words, the policy statement tells the application if certain components may or may not be executed depending on some predetermined conditions.

For example, the below statement restricts user registration if requests come from outside of the USA as well as over the weekends.

{
    "Effect": "deny",
    "Resource": "UserRegistration",
    "Condition": {
        "Operator": "OR",
        "NotEquals": {
            "${IDENTITY.location.country_code}": "USA"
        },
        "In": {
            "${DATETIME.D}": [
                "Sat",
                "Sun"
            ]
        }
    }
}

As you can see, it becomes relatively easy to define any conditional logic and make changes over time without a need to touch the existing codebase.

Below I'm going over each supported statement's attribute in more detail.

# Effect

  • Type: String
  • Required

The Effect attribute defines if resources or combination of resources and actions are "allowed" or "denied". I'm deliberately wrapping "allowed" and "denied" keywords into quotes to emphasize the fact that the effect can be as verbose as you wish.

For example, you may prefer to use keywords like "permit" and "restrict" instead or certain resources are defined to be "attached" or "detached".

By default, all the available libraries support allow and deny effects and developers have the ability to declare a custom collection of stems for more verbose implementation.

FYI! For more details about custom effects, please refer to the respective language library reference page.

The reserved Effect attribute as well as its value are both case-sensitive, so "Allow" is not equals to "allow". That is why please be extra cautious defining this attribute.

# Enforce

  • Type: Boolean
  • Optional

The Enforce attributes prioritize the applicable statement over other applicable statements that target the same resource or combinations of resource/action. It basically works exactly the same way as !important tag in CSS stylesheets.

Note! The "applicable" statement is the statement that either does not have any conditions or defined conditions evaluate to true.

If there are two or more enforced and applicable statements that target the same resource, then the last declared statement is used.

In the example below, there are two statements that target the same action trade for the resource Car, however, the user will be denied to trade the car because this action is enforced to be denied.

{
    "Statement": [
        {
            "Effect": "deny",
            "Enforce": true,
            "Resource": "Car",
            "Action": "trade"
        },
        {
            "Effect": "allow",
            "Resource": "Car",
            "Action": [
                "purchase",
                "trade"
            ]
        }
    ]
}

# Resource

  • Type: String|Array
  • Required

The Resource attribute contains either a single string value or an array of string that represents an application's resources.

The resource can be anything. It can be an object or even some very specific method of an object. It is up to you to define application resources and actions that can be performed upon them.

By default, the JSON policy framework converts an object into a string by taking the class name of the instance. However, if the passed resource is already a string, then it is taken as-is.

In the example below, I'm declaring two statements that target a completely different type of resources when the first one restrict access to tasks that belong to the protected category "Accounting" and the second statement completed restricts the ability to delete any tasks.

{
    "Statement": [
        {
            "Effect": "deny",
            "Resource": "Task",
            "Condition": {
                "In": {
                    "${Task.category}": [
                        "Accounting"
                    ]
                }
            }
        },
        {
            "Effect": "deny",
            "Resource": "delete-tasks"
        }
    ]
}

Resources can be declared dynamically by using markers. This is extremely useful when you do not have the ability to foresee every possible resource that your application may work with.

For example, let's say you want to allow a user to the category that has the exact name that the user's email address. In this case, the statement may look something like this:

{
    "Effect": "allow",
    "Resource": "Category:${USER.email_address}"
}

The Resource attribute may also contain the specially reserved => mapping operand. It basically allows you to build the list of resources dynamically from giving marker that contains an array of scalar values. These values are used to replace the %s and build the final name for each resource.

{
    "Effect": "restrict",
    "Resource": "Article:%s => ${CONTEXT.RestrictedArticles}"
}

The RestrictedArticles property contains the array of article names that are restricted.

# Action

  • Type: String|Array
  • Optional

The Action attribute is the optional attribute and may or may not exist based on the type of resources.

{
    "Effect": "allow",
    "Resource": "User",
    "Action": [
        "update",
        "create",
        "delete"
    ]
}

Note! The Action attribute does not allow markers inside to improve policy readability and an application security pasture.

# Condition

  • Type: { Equals: Object, NotEquals: Object, ... }: Object
  • Optional

The Condition attribute is also the optional attribute and contains a collection of conditions that if meat, classify the statement as applicable. This is very helpful when some restrictions or allowances have to be applied only when certain conditions are fulfilled.

Note! Conditions are discussed in greater details in the "Policy Condition" section.

For example, you may allow a user that has the administrator role to be able to manage other users with the statement like this:

{
    "Effect": "allow",
    "Resource": "User",
    "Action": [
        "view",
        "update",
        "create",
        "delete",
        "suspend"
    ],
    "Condition": {
        "In": {
            "administrator": "(*array)${USER.roles}"
        }
    }
}

FYI! The type casting (*array) is discussed in more detail in the "Type Casting" section