Quick start
This section introduces you to the core concepts of the ALFA language. It serves as a quick guide, equipping you with the fundamental knowledge required to author access control policies within your organization.
ALFA syntax
ALFA uses keywords and symbols to define the structure and logic of a policy. The basic elements are:
Namespaces Namespaces are containers for policies, rules, and attributes, helping to prevent naming conflicts and improve code readability. They are declared with the keyword
namespacefollowed by an identifier. A namespace can import other namespaces with the keywordimport.Policy sets
Policy sets are containers for policies and other policy sets. They are primarily used to group related policies together and define how conflicts between those policies are resolved
Policies Policies are collections of rules that define the conditions for permitting or denying access to a resource. They are declared with the keyword
policyfollowed by an identifier and an optional target. A target is an expression that specifies the scope of the policy, such as the resource, action, or subject involved in the request.Rules A rule is a statement that evaluates to a decision of Permit, Deny, NotApplicable, or Indeterminate. It is declared with the keyword
rulefollowed by an identifier and an optional target. A rule also has a condition that is a boolean expression that must be "true" for the rule to apply. A rule can also have an obligation or advice that is an action to be performed by the Policy Decision Point (PDP) or the Policy Enforcement Point (PEP) when the rule is evaluated.Attributes An attribute is a piece of information that can be used in a target or a condition. It is declared with the keyword attribute followed by an identifier, a type, and an optional category. An attribute can also have a value that is a constant or a variable. An attribute can be referenced by using the
@symbol followed by its name.
Namespaces
To ensure proper scoping and identification of elements within the policy structure, ALFA mandates that all policies, policy sets, and other declarations must be enclosed within a namespace. Namespaces establish a hierarchical structure within the policy framework, enabling organized categorization, and enhanced code readability and maintainability, while making it easier to navigate and understand the policy structure.
Learn more details in the Namespaces section.
Policies
Rules reside within policies, which can also include a target clause and/or a condition along with obligations and advice. The PDP only considers the rules within a policy if its target clause is missing or if one or more target clauses evaluate to "true".
When authoring policies with multiple rules, potential complications arise. If two rules produce conflicting outcomes, the PDP must determine which outcome to promote as the policy's decision. To address this, policies employ a combining algorithm specified by the apply clause. This algorithm dictates how the PDP should resolve conflicting outcomes, ensuring a consistent policy decision.
Policy Sets
Creating a single policy for an entire organization would quickly become unmanageable. Defining policies for specific areas, and then aggregating them into a single overall policy would enable sharing of policies and simpler maintenance and management of policies.
This is the role of a policy set. Similar to policies, policy sets may contain a target and/or a condition. Moreover, a policy set can
- contain any number of other policy sets or policies
- have references to policy sets or policies
- be empty
Read the Policy sets section for more in-depth details.
Rules
The foundation of policy decisions lies in rules, which can result in one of four outcomes:
- Permit: Granting access to a resource
- Deny: Blocking access to a resource
- Indeterminate: Ambiguous outcome due to missing information or incomplete evaluation
- NotApplicable: Rule is irrelevant to the current request
When evaluating a rule, the Policy Decision Point (PDP) starts by examining the target clause to assess its relevance to the specific request. If the target clause evaluates to "false", the rule's outcome is immediately determined as NotApplicable.
A target is a conditional expression that determines when a policy or a rule applies. It specifies the conditions that must be met for the policy to be considered for a particular access request.
If the target clause passes the evaluation and evaluates to "true", the PDP then proceeds to assess the rule's condition. If the condition evaluates to "false", the rule's outcome remains NotApplicable. However, if the condition evaluates to "true", the PDP declares the rule's defined outcome, either Permit or Deny.
In the event where either the condition or the target clause fails to evaluate, perhaps due to missing attributes or incomplete information, the outcome of the rule is declared as Indeterminate.
Sample rules
rule {
permit
condition Attributes.userClearance >= Attributes.resourceClassification
}
rule {
deny
condition Attributes.documentStatus == "draft"
&& not(Attributes.documentAuthor == Attributes.subjectId)
}
The snippet above contains two rules. One of the rules permits access and the other one denies access, depending on how the rules match the request. The policy applies a deny override algorithm to decide which gets priority in the event that both rules match. In such a case, the deny decision will receive priority.
The two rules do not contain any target but they use a condition, which is another way to define how a rule or a policy matches. A condition is not limited to a special structure, unlike a target, which is why it is used in this instance.
The first rule will permit access to the target, in this case the "document", if the user's clearance is at least as high as the document's classification. The second rule will override this if the document's status is "draft" and the user attempting to access it is not the author of the document.
Targets and conditions
Targets
A Target is a way to specify which policy applies to which authorization request. A target consists of one or more attribute comparisons, such as role=="manager", that check if the request matches the policy. You can use logical operators like and and or to combine multiple comparisons. For example:
role=="manager" and action=="view" and object=="financial record"
A target can only use functions that compare attributes to values, such as string equality, numeric equality, or set membership.
Conditions
A Condition is a way to add more complex logic to your policy. A condition can use any of the functions available in ALFA, such as arithmetic, string manipulation, or custom functions. You can also nest functions inside other functions to create more elaborate expressions. Conditions are especially useful for implementing relationships between attributes. For example, you can use a condition to allow access to a record only if the user and the record share some attribute, or if the user has a higher attribute value than the record. Here are some examples of conditions:
user.clearance>record.classification: This condition allows access if the user’s clearance level is higher than the record’s classification level.user.department==record.department: This condition allows access if the user and the record belong to the same department.
When to use targets or conditions?
Use Target when you want to define a simple and clear scope for your policy. Think of the target as a filter that selects the requests that are relevant for your policy. Try to express your authorization problem in terms of simple statements that you can use in your target.
Use Condition when you need more flexibility and power in your policy. Think of the condition as a function that evaluates the request and returns a decision. Use conditions when you need to manipulate attributes, use custom functions, or implement ReBAC (relationship-based access control).
Attributes
Attributes supply the information necessary to drive the evaluation of policies and rules. This information can be about the subject accessing a resource, the resource to be addressed, and the environment. Each attribute consists of a key-value pair such as "Role=Manager", “Resource=Blueprint”, or “Action=Edit”.
The attributes themselves are defined in a separate file. For example:
namespace Attributes {
import System.*
attribute resourceType {
id = "http://example.com/xacml/attr/resource/type"
type = string
category =resourceCat
}
For each attribute there is:
- a short name, which is used when writing ALFA policies
- the full XACML attribute identifier
- the data type of the attribute
- the category it belongs to (subject, resource, action, environment, etc.)
Combining algorithms
Combining algorithms are used to combine the evaluation results of multiple rules or policies to determine the final authorization decision. They are declared with the keyword apply followed by the name of the combining algorithm.
Using combining algorithms is optional but generally recommended. For further details, refer to the Combining algorithms section.
Operators
Operators are used to compare and manipulate attribute values in conditions. ALFA supports a wide range of operators, including arithmetic, comparison, logical, and set operators.
Operators such as == and >= can be applied to bags in the condition. If the values are not bags, then the operator is applied between the two atomic values. However, if either operand is a bag, the operator is applied through the "any-of-any" function. This means that the operator returns "true" if at least one combination of values causes the operator to evaluate to true. For example, if there are three authors of the document "Alice", "Bob" and "Carol", and the subject is "Alice", then the expression Attributes.documentAuthor == Attributes.subjectId would evaluate to "true".
Certain operators such as + are not compatible with bags and using them will result in syntax errors.
For more details on this feature, see the Operator declarations section.
Obligation and advice
Obligation and advice are optional elements that can be attached to a policy set, a policy, or a rule to specify some actions that should be performed by the PDP or the PEP when the policy set, the policy, or the rule is evaluated.
policyset topLevel {
apply permitOverrides
policy medicalPolicy
rule {
deny
condition booleanOneAndOnly(Attributes.recordIsBlocked)
on deny {
advice ObligationAdvice.reasonForDeny {
Attributes.message = "The record is blocked"
}
}
}
These actions are declared with the keywords obligation and advice followed by an identifier and a set of attributes. An obligation is a mandatory action that must be successfully executed in order for the outcome of the PDP to remain valid. An advice, on the other hand, is optional and does not affect the overall outcome of the policy or rule.
In the example above, we use an advice to return a reason for the denial, informing the doctor why they are not being granted access to the medical record. This advice helps to provide transparency and accountability for policy decisions.