Skip to content

fix(apl): and / or should not propagate Unorderable past a definite operand #69

Description

@terylt

Description

eval_expression uses ? inside And and Or, so an unorderable operand aborts the
expression even when a sibling already settles it. With args.amount = "lots",
args.amount > 10000 | subject.role == "admin": deny denies the phase instead of taking
true from the second operand. The same happens on & when one operand is definitely
false.

The result is order dependent: a | b and b | a decide differently when one side is
unknown. Not a fail-open, it errs the other way, but a policy language should not depend
on operand order.

Depends on the Result<bool, Unorderable> plumbing that lands with #45.

Measured

On security/analysis-pass at 8855038, with args.amount = "lots" and
subject.role = "admin":

Rule Decision
args.amount > 10000 & subject.role == "guest": deny Deny, unorderable
subject.role == "guest" & args.amount > 10000: deny Allow
args.amount > 10000 | subject.role == "admin": deny Deny, unorderable
subject.role == "admin" | args.amount > 10000: deny Deny, rule fired

The first pair is the same policy with the operands swapped and it decides differently.
The second pair both deny, but only one names the rule, so the audit reason changes with
operand order too.

Acceptance criteria

  • | returns true if any operand is true, & returns false if any operand is false,
    regardless of an unorderable sibling.
  • Unorderable is returned only when no operand settles the expression.
  • Tests cover both orders of unknown | true and unknown & false.
  • CHANGELOG entry: some phases that denied on an unparseable value now evaluate normally.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions