Hi, We've been exploring Cerbos for some internal ...
# help
c
Hi, We've been exploring Cerbos for some internal use cases and have been particularly looking at one case where we would like to apply a series of label's to a user. I've created the following use case in the playground just for trial purposes but continue to get an empty output for computed_labels:[] Feel a bit stupid at the moment and cant work out the issue so would anyone be able to provide some quick hints on where we’re going wrong here? Thanks very much in advanced
business_roles.yaml
Copy code
apiVersion: api.cerbos.dev/v1
derivedRoles:
  name: business_roles
  definitions:
    - name: ROLE_Financial_Controlling
      parentRoles:
        - user
      condition:
        match:
          expr: P.attr.department in ["LIVX2", "FIN01", "FIN07"]
          
    - name: ROLE_Legal_Counsel
      parentRoles:
        - user
      condition:
        match:
          expr: P.attr.department in ["LEG01", "LEG02", "COMPLIANCE_A"]

    - name: ROLE_Export_Control
      parentRoles:
        - user
      condition:
        match:
          expr: P.attr.department in ["EXP01", "TRADE_C"]
data_labels.yaml
Copy code
apiVersion: api.cerbos.dev/v1
derivedRoles:
  name: data_labels
  definitions:
    - name: LABEL_Financial_Controlling
      parentRoles: ["ROLE_Financial_Controlling"]

    - name: LABEL_Business_Controlling
      parentRoles: ["ROLE_Business_Controlling"]

    - name: LABEL_GDPR
      parentRoles: ["ROLE_Legal_Counsel", "ROLE_HR_Operations"]

    - name: LABEL_Export_Control
      parentRoles: ["ROLE_Export_Control", "ROLE_Logistics_Operations"]

    - name: LABEL_Legal
      parentRoles: ["ROLE_Legal_Counsel"]

    - name: LABEL_Sensitive
      parentRoles: ["ROLE_Financial_Controlling", "ROLE_Legal_Counsel"]
geo_labels.yaml
Copy code
apiVersion: api.cerbos.dev/v1
derivedRoles:
  name: geo_labels
  definitions:
    - name: LABEL_US
      parentRoles:
        - user
      condition:
        match:
          expr: P.attr.geography == "US"

    - name: LABEL_EMEA
      parentRoles:
        - user
      condition:
        match:
          expr: P.attr.geography == "EMEA"

    - name: LABEL_Asia
      parentRoles:
        - user
      condition:
        match:
          expr: P.attr.geography == "Asia"

    - name: LABEL_China
      parentRoles:
        - user
      condition:
        match:
          expr: P.attr.geography == "China"
label_aggregator.yaml
Copy code
apiVersion: api.cerbos.dev/v1
resourcePolicy:
  version: "default"
  resource: "label_aggregator"
  
  importDerivedRoles:
    - geo_labels
    - business_roles
    - data_labels

  rules:
    - actions:
        - get_labels
      effect: EFFECT_ALLOW
      roles:
        - user
        
      output:
        expr: |
          {
            "computed_labels": P.roles
                                .filter(r, r.startsWith("LABEL_"))
                                .map(r, r.replace("LABEL_", "")),
            "user_id": P.id,
            "geography": P.attr.geography,
            "legal_entity": P.attr.legal_entity,
            "department": P.attr.department
          }
priciple_1
Copy code
{
  "id": "smith_john",
  "roles": [
    "user"
  ],
  "attr": {
    "geography": "US",
    "legal_entity": "LG101757",
    "department": "LIVX2"
  }
}
o
Hi @Clint, There are two things to address here: 1.
P.roles
doesn't include the effective derived roles for the principal because we do not mutate the incoming request. Instead we add the information to the
runtime
object. In this case you could use
runtime.effectiveDerivedRoles
. 2. The resource policy rule should have
derivedRoles
instead of `roles`:
Copy code
...
    - actions:
        - get_labels
      effect: EFFECT_ALLOW

      derivedRoles:
        - LABEL_US
        - LABEL_EMEA
        - LABEL_Asia
        - LABEL_China
      ...
c
Thanks for this - finally getting an output into the list... Would this mean though that if hypothetically I had say 4 derived role configs with say upto 10 or more roles in each than all 40 of those would need to be listed under the derivedRoles in the resource policies / aggregation config?
c
Hey. Am I correct to summarise what you're trying to do as "compute a set of labels for a given user"? Cerbos doesn't really work that way. It can make allow/deny decisions based on the policy rules and optionally output the set of data points that it used to make those decisions. It can't act like a general purpose function that takes some input and produces some output. You can write a policy that says "only users from EMEA who are either members of financial control departments FIN01 of FIN07 or legal counsel department LEG01 can read an invoice tagged sensitive". Then you can use the Cerbos
Check
request to make sure that those conditions are satisfied for a given user and an invoice.
c
Your right - We have some downstream applications that will require a payload list and not on the fly - the test case was really to see if we could consolidate both use cases into one tool with one set of roles etc - I knew this use case was the tricker / hackier so wanted to test it first....
c
I understand. This kind of "user belongs to department X and geography Y" attributes are probably best stored at the identity provider (IDP) level because those pieces of information are tied to each user. They can then be retrieved at the time of authentication and attached to a JWT or something like that. Alternatively, you could have a simple proxy service that takes a Cerbos request, does attribute lookups for the given principal from your data sources (IDP, databases etc.) and forwards the enriched the request through to Cerbos for making access decisions.