Assuming I have the following resource policy and ...
# help
j
Assuming I have the following resource policy and derived role defined:
Copy code
---
apiVersion: "api.cerbos.dev/v1"
description: "Dynamic role to determine if this is a HM employee."
derivedRoles:
  name: hm_employee
  definitions:
    - name: internal_user
      parentRoles: ["valid_user"]
      condition: 
        match:
			expr: request.aux_data.jwt.is_hm_employee == "TRUE"
---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "1"
  importDerivedRoles:
    - hm_employee
  resource: "businessassets"
  rules:
    - actions: ['read']
      effect: EFFECT_ALLOW
      derivedRoles:
        - internal_user
Copy code
And then my code calls /api/check with the following JSON

{
  "requestId":  "xxxxxxx", 
  "actions":  ["read"], 
  "resource":  {
    "policyVersion": "1",
    "kind":  "businessassets", 
  },
  "principal":  {
    "id":  "user01", 
    "policyVersion": "1", 
    "roles":  ["valid_user"], 
  },
  "includeMeta": true, 
  "auxData": { 
    "jwt": {
        "token": "xxx.yyy.zzz", 
    }
  }
}
am I going to get a response of EFFECT_ALLOW?
i'm just trying to understand if I have coded the policies properly or missed some good practices - before i start coding them en-masse.
d
Yes, all looks good to me
j
ok, for the resource policy, do i absolutely need "importDerivedRoles" ?
d
Yes, you do
j
if i do not have a derived role defined, then can i drop that?
d
Correct
You need it, if you want to import a derived role
j
and assuming in the json payload above, i have a "roles":["valid_user"], then what would the resourcePolicy look like?
apiVersion: api.cerbos.dev/v1 resourcePolicy: version: "1" resource: "businessassets" rules: - actions: ['read'] effect: EFFECT_ALLOW roles: - valid_user
something like the above?
Copy code
{
  "requestId":  "xxxxxxx", 
  "actions":  ["read"], 
  "resource":  {
    "policyVersion": "1",
    "kind":  "businessassets", 
  },
  "principal":  {
    "id":  "user01", 
    "policyVersion": "1", 
    "roles":  ["valid_user"], 
  },
  "includeMeta": true, 
  "auxData": { 
    "jwt": {
        "token": "xxx.yyy.zzz", 
    }
  }
}
with the json policy above, would i get EFFECT_ALLOW response if i have this resource policy:
Copy code
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "1"
  resource: "businessassets"
  rules:
    - actions: ['read']
      effect: EFFECT_ALLOW
      roles:
        - valid_user
d
Copy code
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "1"
  importDerivedRoles:
    - hm_employee
  resource: "businessassets"
  rules:
    - actions: ['read']
      effect: EFFECT_ALLOW
      derivedRoles:
        - internal_user
This is your resource policy, right?
j
no. it is this. assume i no longer want to use derivedRoles
Copy code
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "1"
  resource: "businessassets"
  rules:
    - actions: ['read']
      effect: EFFECT_ALLOW
      roles:
        - valid_user
i'm not even sure if the format of the resourcepolicy yaml above is correct for "resourcePolicy.rules.roles"
d
the format seems correct
If you don’t want to use derivedRoles you need to repeat use this expression in the resource policy rule:
expr: request.aux_data.jwt.is_hm_employee == "TRUE"
j
well assume i drop that expr
no longer checking the JWT
d
kk
j
and in my code, when i call /api/check, i add the user's role into the json payload....
(assume i can derive the role from some other source / algorithm)
then this resourcepolicy would give me an EFFECT_ALLOW response from /api/check, is that correct?
Copy code
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "1"
  resource: "businessassets"
  rules:
    - actions: ['read']
      effect: EFFECT_ALLOW
      roles:
        - valid_user
assuming my json payload has "valid_user" as the role of course
d
looks good. Let me double check
j
also is it a good practice to combine resourcepolicies and roles into a single yaml file (assuming the roles are those that will access those resources)? or would it be better to split roles into roles yamls...and resourcepolicies into resourcepolicies yamls.... ?
d
Yes, correct
j
i guess that's more an operational question, which i understand. but i'm just thinking from a cerbos perspective, is there any difference?
like performance - because cerbos has to load slightly more YAMLs during start up
d
“Roles yamls” - you mean derived roles yamls, right?
j
yeah derived roles
d
There’s no difference from a performance perspective.
Derived roles were introduced to help with organising policies.
j
okay thank you sir
👍 1
gonna start transitioning some of my APIs to Cerbos ABAC today 🙂
🎉 2
d
I should have framed my answer more carefully about no impact on performance 🙂 hundreds of small derived role yaml files will impact performance
j
ok so i did a quick curl test
Copy code
curl -POST -H "Content-type: application/json" -d '{
  "requestId":  "1", 
  "actions":  ["read"], 
  "resource":  {
    "policyVersion": "1",
    "kind":  "businessassets", 
  },
  "principal":  {
    "id":  "user01", 
    "policyVersion": "1", 
    "roles":  ["valid_user"], 
  },
  "includeMeta": true, 
  "auxData": { 
    "jwt": {
        "token": "xxx.yyy.zzz", 
    }
  }
}' '<https://mycerbosurl/api/check>'
that gives me an error...i'm assuming because with token, i literally put those values in "xxx.yyy.zzz"
Copy code
{
  "code": 3,
  "message": "invalid character '}' looking for beginning of object key string",
  "details": []
}
so when i put in the proper JWT token string (base64 encoded) into the auxData.jwt.token key, i still get the same error message from cerbos
d
Can you please omit
auxData
from the request and try again?
j
ok
d
You’re not using it ,right?
j
well i just want to test this first
i will be using it in production eventually
d
I mean just to start with a more simple request.
j
curl -POST -H "Content-type: application/json" -d '{ "requestId": "1", "actions": ["read"], "resource": { "policyVersion": "1", "kind": "businessassets", }, "principal": { "id": "user01", "policyVersion": "1", "roles": ["valid_user"], }, "includeMeta": true }' 'https://mycerbosurl/api/check'
stil lgetting same error
going to take a look at the pod logs...gimme a min
d
Incorrect json. Please try this:
Copy code
{
  "requestId": "1",
  "actions": [
    "read"
  ],
  "resource": {
    "policyVersion": "1",
    "kind": "businessassets"
  },
  "principal": {
    "id": "user01",
    "policyVersion": "1",
    "roles": [
      "valid_user"
    ]
  },
  "includeMeta": true
}
I removed a couple of commas
j
{"log.level":"error","@timestamp":"2021-12-15T030951.656Z","log.logger":"cerbos.blob","message":"Failed to check for updates","bucket":"gs://abac-policies","workDir":"/root/tmp/cerbos/work","error":"failed to convert data to JSON: yaml: line 10: found character that cannot start any token"}
does that look like there's a problem with the policies / derivedroles yaml?
d
Please try with a JSON I provided above.
j
ok
Copy code
{
  "code": 3,
  "message": "invalid CheckResourceSetRequest.Resource: embedded message failed validation | caused by: invalid ResourceSet.Instances: value must contain between 1 and 20 pairs, inclusive",
  "details": []
}
what does that mean?
ok i see what u did with the JSON...some extra commas i had in there
d
The request
resource
field should have a dictionary of resource instances that we are checking access to. Please refer to https://docs.cerbos.dev/cerbos/latest/api/index.html#_checkresourceset_apicheck (callout 6)
j
ok let me take a look
d
Let’s make it up for now:
Copy code
{
  "requestId": "1",
  "actions": [
    "read"
  ],
  "resource": {
    "policyVersion": "1",
    "kind": "businessassets",
    "instances": {
      "id001": {}
    }
  },
  "principal": {
    "id": "user01",
    "policyVersion": "1",
    "roles": [
      "valid_user"
    ]
  },
  "includeMeta": true
}
j
ok let me try that
actually u can curl it directly to my instance of cerbos
curl -POST -H "Content-type: application/json" -d '{ { "requestId": "1", "actions": ["read"], "resource": { "policyVersion": "1", "kind": "businessassets", "instances": { "id001": {} } }, "principal": { "id": "user01", "policyVersion": "1", "roles": ["valid_user"] }, "includeMeta": true }' '<https://pdp.controlshift.io/api/check%7C&lt;&gt;redacted>'
that's the URL
👍 1
i'm still getting the same error{"code":3,"message":"invalid character '{' looking for beginning of object key string","details":[]}
d
I think you have an extra
{
j
oh
oh yeah
Copy code
{
  "requestId": "1",
  "resourceInstances": {
    "businessassets": {
      "actions": {
        "read": "EFFECT_DENY"
      }
    }
  },
  "meta": {
    "resourceInstances": {
      "businessassets": {
        "actions": {
          "read": {
            "matchedPolicy": "NO_MATCH"
          }
        },
        "effectiveDerivedRoles": []
      }
    }
  }
}
voila!
so i have a follow up question
message has been deleted
does line 53 above
gets checked against line 18 below
i guess my question is "kind" and "instances" - how are these cross referenced to resource policies?
it looks like only "kind" is used to find the correct resource policy, yes?
👍 1
so in my case, instances is useless. i can put meaningless data inside it.
d
In the resource policy the field
resource
means resource kind.
j
what about line 55?
is that checked against resource policies too?
from the cerbos docs, it doesn't look like it. it looks more like a way for my custom code to keep track of request for access against resource vs the response from cerbos?
d
Line 53 should refer to the resource kind, i.e. “businessassets”. Line 55 can contain some key
j
ok so in my use case i only want to protect REST APIs....each REST API retrieves one kind of data.....so i guess line 55 is useless. my smallest denominator for access permission is the API. in one example my API endpoint is called "businessassets". so i guess the resourcepolicy will be defined for "businessassets" kind, and line 55 is of no use to me
but because line 55 is needed for the json payload, i just have to put some meaningless data in it. yes?
👍 1
d
Correct
j
ok!!!!!
A big thank you @Dennis (Cerbos)!!!!
d
You are welcome, Jesum!
j
if I ever go to NZ / Auckland, I'll be sure to look you up to say thank you!
d
Great idea. I’d love to catch up
but because line 55 is needed for the json payload, i just have to put some meaningless data in it.
an extra comment about this. The response is given per a key in this
instances
object.