Skip to main content

Statement

Vasyl MartyniukAbout 3 min

Syntax

{
    "Effect": "string",
    "Enforce": "boolean",
    "Resource": "string|array",
    "Action": "string|array",
    "Condition": "object"
}

Definition

The Statement property contains one or more policy statements that define access to resources and actions. If you need to declare more than one statement, then the Statement property can be defined as array of objects. For example, the following policy has only one statement declared:

{
    "Statement": {
        "Effect": "deny",
        "Resource": "URI:/membership/*"
    }
}

However, in the following policy we declare more than one statements within a single policy:

{
    "Statement": [
        {
            "Effect": "deny",
            "Resource": "PostType:page:posts",
            "Action": [
                "List",
                "Read"
            ]
        },
        {
            "Effect": "allow",
            "Resource": "Post:page:home",
            "Action": [
                "List",
                "Read"
            ]
        }
    ]
}

Statements can be conditional and are applicable only when declared conditions are met. For example, the following statement denies commenting on all posts if a user is not from the US.

{
    "Statement": {
        "Effect": "deny",
        "Resource": "PostType:post:posts",
        "Action": "Comment",
        "Condition": {
            "NotEquals": {
                "${IPSTACK.country_code}": "US"
            }
        }
    }
}

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 we are going over each supported attribute in greater detail.

Effect

  • Type: String
  • Required

The Effect attribute defines if resources or combination of resources and actions are "allowed" or "denied". We are deliberately wrapping "allowed" and "denied" words 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".

{
    "Statement": {
        "Resource": "PostType:page:posts",
        "Effect": "deny",
        "Action": "Read"
    }
}

AAM plugin support allow and deny effects and developers have the ability to declare a custom collection of stems for more verbose implementation with the aam_access_policy_effects_filter hook. It is also worth noting that the Effect attribute may hold different values depending on the resource. For example, the Hook resource expects the Effect to have values like apply or merge.

FYI!

To learn more on how to declare custom effects and use them in your custom implementation, refere to the How to define a custom statement effect? article.

The reserved Effect attribute as well as its value are both case-insensitive, so "Allow" equals to "allow".

Enforce

  • Type: Boolean
  • Optional

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

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 "read" for the "Hello World" post, however, the user will be denied to read the post because this action is enforced to be denied.

{
    "Statement": [
        {
            "Effect": "deny",
            "Enforce": true,
            "Resource": "Post:post:hello-world",
            "Action": "read"
        },
        {
            "Effect": "allow",
            "Resource": "Post:post:hello-world",
            "Action": [
                "list",
                "read"
            ]
        }
    ]
}

Resource

  • Type: String|Array
  • Required

The Resource attribute holds either a single string value or an array of strings, representing an application's resources.

These resources can encompass anything supported by AAM or your customized implementation. You are responsible for defining application resources and the actions permissible on them. For a comprehensive list of AAM-supported resources and actions, consult the "Resources & Actions" section below.

In the following example, two statements are declared, targeting vastly different resource types. The initial statement grants the "Editor" role to a user, whereas the subsequent statement denies access to all RESTful API endpoints:

{
    "Statement": [
        {
            "Effect": "allow",
            "Resource": "Role:editor"
        },
        {
            "Effect": "deny",
            "Resource": "Route:*:*"
        }
    ]
}

Resources can be dynamically declared using markers, which proves invaluable when anticipating every conceivable resource that an application might encounter.

For instance, suppose you wish to permit a user access to a category named identically to their username. In such a scenario, the statement might resemble the following:

{
    "Effect": "allow",
    "Resource": "Term:category:${USER.username}"
}

Additionally, the Resource attribute may incorporate the specially reserved => mapping operand. This functionality enables the dynamic construction of resource lists from markers containing an array of scalar values. These values replace the %s placeholder, thereby generating the final name for each resource.

{
    "Effect": "allow",
    "Resource": "Term:category:%s => ${USER_META.allowed-categories}"
}

If the allowed-categories user meta contains a list of strings (e.g. "[science,news,travel]"), they will be leveraged to dynamically generate a policy with a list of resources:

{
    "Effect": "allow",
    "Resource": [
        "Term:category:science",
        "Term:category:news",
        "Term:category:travel"
    ]
}

Action

  • Type: String|Array
  • Optional

The presence of the Action attribute is contingent upon the resource type, and it may be absent in certain cases.

{
    "Effect": "deny",
    "Resource": "Plugin:advanced-access-manager",
    "Action": [
        "deactivate",
        "delete"
    ]
}

To enhance policy readability and maintain application security, the Action attribute prohibits the inclusion of markers within it.

Condition

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

The Condition attribute, while optional, holds a set of conditions. If met, these conditions categorize the statement as applicable. This feature proves invaluable when specific restrictions or permissions need to be enforced only under certain circumstances.

FYI!

For a deeper dive into conditions, refer to the Condition article.

For instance, consider granting additional capabilities to users with the Contributor role, as illustrated below:

{
    "Effect": "allow",
    "Resource": "Capability:some-additional-cap",
    "Condition": {
        "In": {
            "contributor": "(*array)${USER.roles}"
        }
    }
}

The method of type casting (*array) is elaborated further in the "Type Casting" article.