davidjbrossard / alfa-authorization-language

A repository for the IETF RFC proposal for ALFA 2.0
Other
0 stars 0 forks source link

Shared conditions #1

Open andrewclymer opened 3 months ago

andrewclymer commented 3 months ago

Repeating the same boolean logic throughout a policy is not only tedious but, from a maintenance perspective, does not scale.

From a runtime perspective, it would be great not to repeat the execution of the same condition across policy decisions.

Consider the following ALFA

policy doorAccess {
        target clause ResourceType == "door" and Action == "open"
        apply denyUnlessPermit

        // Employees can open the door during office hours only
        rule mainDoor {
            target clause Resource == "mainDoor"
            permit
            condition Subject.Role == 'employee' and
                      CurrentTime >= "08:00:00":time and
                      CurrentTime < "18:00:00":time
        }
    }

The use of office opening hours could be part of a shared condition.


condition IsOfficeOpen  CurrentTime >= "08:00:00":time &&   CurrentTime < "18:00:00":time

policy doorAccess {
        target clause ResourceType == "door" && Action == "open"
        apply denyUnlessPermit

        // Employees can open the door during office hours only
        rule mainDoor {
            target clause Resource == "mainDoor"
            permit
            condition Subject.Role == 'employee' and IsOfficeOpen
        }
    }

Using shared conditions allows the runtime to cache the result of a shared condition. Reducing the execution overhead.

Some ALFA conditions can look complex, especially when multiple functions are called. The use of shared conditions increases the readability of ALFA and allows a clean separation between developers and policy builders. Developers can create shared conditions, and policy builders can create high-order conditions by combining shared conditions with boolean operators (and, or, not). This results in a form of ALFA that is

There is an argument to make conditions general-purpose expressions so they can return any result type, not just boolean. Keeping the contract to just boolean expressions creates a level of policy building that does not require deep technical knowledge. If policy conditions were built using shared expressions (return any type), a developer's refactor of the shared expression could break various policies, resulting in an error in the consumer of the shared expression, not in the author of the shared condition. A strong boolean contract prevents this from happening. This is not dissimilar to shared rules, which can only produce a permit or deny.