authzen icon indicating copy to clipboard operation
authzen copied to clipboard

`deny_on_first_deny` and `permit_on_first_permit` examples are cumbersome

Open identitymonk opened this issue 11 months ago • 1 comments

In section 7.1.2.1.1 https://openid.github.io/authzen/#name-example-evaluate-read-actio, if one wants to use deny_on_first_deny or permit_on_first_permit, it means that there are some relations in between the requests: here the subject is the same.

Therefore, one would expect only global decision (true or false) coming from one of the following use case:

  • Request is deny_on_first_deny and one evaluation leads to "decision": false then a global decision should be false
  • Request is permit_on_first_permit and no evaluation leads to "decision": true then a global decision should be false
  • Request is permit_on_first_permit and one evaluation leads to "decision": true then a global decision should be true

Therefore I propose that PEP would be better served with the following proposal that aligns more with the single Access Evaluation part of the specification:

  • In the case of a request is deny_on_first_deny and one evaluation leads to "decision": false
{
    "decision": false,
    "context": {
      "evaluations": [
        {
          "decision": true
        },
        {
          "decision": false,
          "reason": "deny_on_first_deny"
        }
      ]
    }
}
  • In the case of a request is permit_on_first_permit and no evaluation leading to "decision": true
{
    "decision": false,
    "context": {
      "evaluations": [
        {
          "decision": false
        },
        {
          "decision": false
        },
        {
          "decision": false
        }
      ]
    }
}
  • In case of a request is permit_on_first_permit and one evaluation leading to "decision": true as:
{
    "decision": true,
    "context": {
      "evaluations": [
        {
          "decision": false
        },
        {
          "decision": true,
          "reason": "permit_on_first_permit"
        }
      ]
    }
}

identitymonk avatar Mar 10 '25 21:03 identitymonk

After chatting with @baboulebou and @identitymonk we agreed that when using a boxcarred request with an evaluation semantic should always lead to a single decision.

  • permit_on_first_permit should always lead to either true (when shortcircuited) or false (when all decisions have been checked and all are false)
  • deny_on_first_deny should always lead to either false (when shortcircuited) or true (when all decisions have been checked and all are true)

We could use the context object to:

  • convey the # of requests that were actually processed
  • convey collected obligations/advice/context

davidjbrossard avatar Mar 21 '25 16:03 davidjbrossard

On the 6/20 call @ggebel @identitymonk and @davidjbrossard agreed that:

  1. We need a top-level decision: why would the PEP have to parse N elements of an array only to find out that the nth entry is a short circuit?
  2. We need the response format to be symmetric with the evaluation response for consistency
  3. We need to agree on a way to convey the reason and the other responses, if any. Do they go in as top-level elements or do we want to leverage the context object?

Note that this is a breaking change although we never covered evaluation semantics in the interops thus far.

davidjbrossard avatar Jun 20 '25 21:06 davidjbrossard

On the 8/21 call, we agreed participants should add their feedback here to decide on the way forward. Some points that were brought up were:

  1. the spec as it stands is consistent for all evaluations requests regardless of the evaluations semantic chosen. The decision(s) always come(s) back in an array making the PEP easier to implement
  2. changes this late in the process will delay 1.0

davidjbrossard avatar Aug 21 '25 19:08 davidjbrossard

I like the current behavior. I think it's consistent. Also, I think getting back the list of decisions already evaluated is helpful (e.g. in the case that they were not evaluated in the input order, it's potentially useful to know which decisions were evaluated as "allow" before the first deny, or which decisions evaluated to "deny" before the first allow.

ogazitt avatar Aug 23 '25 00:08 ogazitt

Can we also just allow results to be null when evaluations aren't actually evaluated. Optionally the returned array could also be shortened if the last N evaluations were all null.

Then we can leave the actual semantics up to the specific PEP/PDP.

If we do that we could also omit the options field (or add options to the main evaluation) for consistency between evaluation and evaluations.

mtrimpe avatar Sep 08 '25 13:09 mtrimpe