if i have a derivedrole policy that looks like thi...
# help
j
if i have a derivedrole policy that looks like this. ....will the user end up getting an array of roles with 2 entries in it for "explore" ?
furthermore, if the claim is missing from the jwt, then will line 26 evaluate correctly to 0?
Copy code
{
  "requestId": "1",
  "resourceInstances": {
    "prod": {
      "actions": {
        "read": "EFFECT_ALLOW"
      }
    }
  },
  "meta": {
    "resourceInstances": {
      "prod": {
        "actions": {
          "read": {
            "matchedPolicy": "resource.businessassets.v1"
          }
        },
        "effectiveDerivedRoles": []
      }
    }
  }
}
i see that the effectiveDerivedRoles is blank.... ?
so this is supposed to be populated with the correct role if it matched a derivedrole policy?
d
derived role names should be unique.
j
ok so is there a way i can group those 2 pairs of exprs?
in an OR condition
👍 1
d
match all is ‘AND’ condition
j
condition: match: expr: |- ((request.aux_data.jwt.hm_account_status == "Explore") && (expr: request.aux_data.jwt.is_hm_employee != "TRUE")) || ((expr: size(request.aux_data.jwt.hm_account_status) == 0) && (expr: request.aux_data.jwt.is_hm_employee != "TRUE"))
👍 1
i assume the above would work 🙂
d
it is easier to replace
all
with
any
in your latest screenshot
ouch. not that simple
j
let me try with the above first
but now i know derivedroles must be unique
d
The policy above is incorrect
Try this:
Copy code
- name: explore
      condition:
        match:
          any:
            of:
              - expr: (request.aux_data.jwt.hm_account_status == "Explore" && request.aux_data.jwt.is_hm_employee != "TRUE")
              - expr: (equest.aux_data.jwt.hm_account_status != "" && request.aux_data.jwt.is_hm_employee != "TRUE")
j
ok
Copy code
{
  "requestId": "1",
  "resourceInstances": {
    "prod": {
      "actions": {
        "read": "EFFECT_DENY"
      }
    }
  },
  "meta": {
    "resourceInstances": {
      "prod": {
        "actions": {
          "read": {
            "matchedPolicy": "resource.businessassets.v1"
          }
        },
        "effectiveDerivedRoles": []
      }
    }
  }
}
i'm getting that
d
What’s the intent of this
size(request.<http://aux_data.jwt.hm|aux_data.jwt.hm>_account_status) == 0
?
j
which is odd....effectiveDerivedRoles is blank
well that claim might be blank
i.e. uninitialized
d
But does it exist in the claim at all?
j
no it does not
d
then you need something else. give me a minute
j
oh ok
d
Copy code
- name: explore
      condition:
        match:
          any:
            of:
              - expr: (request.aux_data.jwt.hm_account_status == "Explore" && request.aux_data.jwt.is_hm_employee != "TRUE")
              - expr: (!has(request.aux_data.jwt.hm_account_status) && request.aux_data.jwt.is_hm_employee != "TRUE")
j
oh!!!!
so i did this
and i have a resource policy like this
in my json payload, i specify the user is a type "naked_user" but i'm getting an effectr deny
and the effectivederivedroles is blank
Copy code
{
  "requestId": "1",
  "resourceInstances": {
    "prod": {
      "actions": {
        "read": "EFFECT_DENY"
      }
    }
  },
  "meta": {
    "resourceInstances": {
      "prod": {
        "actions": {
          "read": {
            "matchedPolicy": "resource.businessassets.v1"
          }
        },
        "effectiveDerivedRoles": []
      }
    }
  }
}
what's odd is effectiveDerivedROles is blank
i would expect it to have 'explore'
the jwt i submitted does not have hm_account_status AND does not have is_hm_employee claims
d
Can you please submit your HTTP request
without the token of course
j
it's ok token has expired - u can't use it
d
kk
What if you remove
hm_employee
derived role from the resource policy?
j
ok let me try
Copy code
{
  "requestId": "1",
  "resourceInstances": {
    "prod": {
      "actions": {
        "read": "EFFECT_DENY"
      }
    }
  },
  "meta": {
    "resourceInstances": {
      "prod": {
        "actions": {
          "read": {
            "matchedPolicy": "resource.businessassets.v1"
          }
        },
        "effectiveDerivedRoles": []
      }
    }
  }
}
Copy code
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "1"
  importDerivedRoles:
    - platform_roles
  resource: "businessassets"
  rules:
    - name: allow_readbusinessassets_test
      actions: ['read']
      effect: EFFECT_ALLOW
      derivedRoles:
        - explore
that's my resource policy
Copy code
apiVersion: "api.cerbos.dev/v1"
description: "Dynamic roles."
derivedRoles:
  name: platform_roles
  definitions:
    - name: explore
      parentRoles: ["naked_user"]
      condition:
        match:
          any:
            of:
              - expr: (request.aux_data.jwt.hm_account_status == "Explore" && request.aux_data.jwt.is_hm_employee != "TRUE")
              - expr: (request.aux_data.jwt.hm_account_status == "" && request.aux_data.jwt.is_hm_employee != "TRUE")
              - expr: (request.aux_data.jwt.hm_account_status == "" && request.aux_data.jwt.is_hm_employee == "")
              - expr: (!has(request.aux_data.jwt.hm_account_status))
              - expr: (!has(request.aux_data.jwt.is_hm_employee))
    - name: expand
      parentRoles: ["naked_user"]
      condition:
        match:
          all:
            of:
              - expr: request.aux_data.jwt.hm_account_status == "Expand"
              - expr: request.aux_data.jwt.is_hm_employee != "TRUE"
    - name: experience
      parentRoles: ["naked_user"]
      condition:
        match:
          all:
            of:
              - expr: request.aux_data.jwt.hm_account_status == "Experience"
              - expr: request.aux_data.jwt.is_hm_employee != "TRUE"
that's derived role policy
d
Great. Thanks. I’ll try locally
j
did you manage to reproduce the issue?
d
Yes, and I found what caused the problem.
- expr: (request.<http://aux_data.jwt.hm|aux_data.jwt.hm>_account_status == "" && request.aux_data.jwt.is_hm_employee == "")
this fails the entire condition if there’s no
hm_account_status
field in the JWT struct
This works:
Copy code
- name: explore
      parentRoles: ["naked_user"]
      condition:
        match:
          any:
            of:
              - expr: (!has(request.aux_data.jwt.hm_account_status) || request.aux_data.jwt.hm_account_status == "")
              - expr: (!has(request.aux_data.jwt.is_hm_employee) || request.aux_data.jwt.is_hm_employee == "")
j
Ooooh. So the condition fails when the claim doesn't exist. I see. I learn something new
Ok!!
very nice. it works as expected.
👍 1
gosh....so is this a CEL specific behaviour?
d
CEL does not give a default value for a field missing in the struct.
j
roger that. i understand now. i think i'll go read up more about CEL.
i now get this:
{"requestId":"1","resourceInstances":{"prod":{"actions":{"read":"EFFECT_ALLOW"},"validationErrors":[]}},"meta":{"resourceInstances":{"prod":{"actions":{"read":{"matchedPolicy":"resource.businessassets.v1"}},"effectiveDerivedRoles":["explore"]}}}}
which i exactly what i am expecting
d