Statement
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.