This message was deleted.
# opal
s
This message was deleted.
o
Hi Doug, No, no equivalent in Cedar (nor in Cedar agent or AVP) to http.send We can look at maybe adding it in Cedar-agent; but In general i’d say it’s for the better - http.send seems harmless but it’s the fastest way to destabilize your authorization layer ( creating sensitive dependencies as part of the critical chain)
d
I agree with that statement. It's risky. The alternative seems to be to load OPA with the data prior to rule eval. In that case, how does Cedar access the pre-fetched data? For example, if there's a policy for a principal, action, and resource, and for the resource there's a
when
clause that filters on a list of identifiers that have been loaded into OPA. What's the syntax for referencing that list?
Copy code
permit(
    principal in Role::"sales",
    action in Action::"create",
    resource
)
when {
    (resource.name == "rate_codes" || 
     resource.name == "rate_models" || 
     resource.name == "campaign" || 
     resource.name == "mailer") 
};
I'd like to load that list of names into OPA, rather than hard-coding them in the rule.
o
In Vanilla Cedar or AVP the only option is to load data as part of the input query. In Cedar-agent, which manages a memcache for you (like OPA) , you can load data via the API or via OPAL
CC: @Asaf Cohen, @Omer Zuarets
d
Something like
Copy code
when {
    resource.name in [some_array_in_OPA]
};
o
I’d like to load that list of names into OPA, rather than hard-coding them in the rule.
Are we talking OPA or Cedar ? those are of course not the same
d
Good question, I'm still learning!
o
Maybe worth trying this article first then - to allow you to dive into the differences between the two : https://www.permit.io/blog/opa-vs-cedar
d
My proof of concept is using
permitio/opal-server:latest
and
permitio/opal-client-cedar:latest
and I can send requests to the
/v1/is_authorized
endpoint for decisions. And, I can send
context
to the endpoint, but I would like to move that fetch of context to Cedar. Does that make sense?
o
You can use OPAL data updates then
d
For example, I have this rule and it all works:
Copy code
{
  "principal": "Role::\"sales\"",
  "action": "Action::\"read\"",
  "resource": "Resource::\"rate_codes\"",
  "context": {
    "id": "abc123",
    "ids": [
      "abc123",
      "xyz456"
    ]
  }
}
But, I'd prefer to only send the
id
and have Cedar(?) have a cache of the
ids
.
If OPAL data updates is used, how does one reference the data in the policy language? I can't seem to find any documentation on how to do that in Cedar. I can see how to do that with Rego.
o
just by the path you assigned them as part of the update
d
Got it. I understand conceptually. But, I don't know how to craft a Cedar policy to reference the data.
Copy code
permit(
    principal in Role::"sales",
    action in [Action::"read", Action::"update", Action::"delete"],
    resource
)
when {
     context.ids.contains(context.id)
};
How would I write the policy to reference that data (array) in the above use case, instead of the list that's passed in via context?
BTW, I promise that I've read the docs!
o
The Cedar docs are new; so there are defiently gaps in them 😄
👍 1
d
OK, so it's not just me!
o
Take a look at this docker compose including a baseline data update (OPAL_DATA_CONFIG_SOURCES): https://github.com/permitio/opal/blob/master/docker/docker-compose-example-cedar.yml And this example data file : https://github.com/permitio/cedar-agent/blob/1838635f16ba6db60d16c2ca28cb257e970bdff0/examples/data.json
d
Thanks! That's actually what I used to build my PoC.
o
Cedar data is actually a list of entities, Each entity has a • type • id • attributes • parents In Cedar, you enforce the conditions on principal, action, resource and context. So for example if you declared the following entity in your data:
Copy code
{
  "uid": {
    "type": "User",
    "id": "alice"
  },
  "attrs": {
    "age": 25,
    "name": "alice",
    "userId": "897345789237492878"
  },
  "parents": []
}
and your authorization query is on
User::alice
, then the
principal
will have the attributes from the data and you’ll be able to perform
principal.age > 20
inside the when block ( same goes for action and resource ), context is a bit different, you provide the data inside the request and you can simply enforce conditions on it
To simplify, the attributes are taken from the data automatically using the entity type and id provided in the authorization query
d
Thanks, Omer! Let's say I have a banking app, and there's millions of customers who can have one or more accounts. How would I create an entity or entities that map the customer to their accounts in Cedar data? Perhaps Cedar isn't built for this fine-grained access control use case?
Or, maybe an attr of the user in the example above is a list of account numbers?
Copy code
{
  "uid": {
    "type": "User",
    "id": "alice"
  },
  "attrs": {
    "age": 25,
    "name": "alice",
    "userId": "897345789237492878",
    "account_numbers": [
      "abc",
      "def"
    ]
  },
  "parents": []
}
o
You have multiple ways to solve this: 1. using the attributes - having an attribute like you described with the list of accounts 2. using the parents - declaring that
User::"alice"
has the parents
Account::"abc"
and
Account::"def"
, and by doing this you can perform the condition
principal in Account::"abc"
d
Perfect. I'll try that now. At some point that list of account numbers needs to be built from a query to an external data source. That's currently a blindspot for me. And, I'm wondering if that's what the Cedar Agent is for?
o
Yep, Cedar Agent can be used with OPAL to store data from external data sources before you perform the authorization query, and then when you perform the authorization query the agent uses the stored data that you’ve already imported.
👍 1
d
@Omer Zuarets Trying what you suggested. This works, provided the
allowed
key only has a single value.
Copy code
{
    "attrs": {
      "allowed": "mailer"
    },
    "parents": [],
    "uid": {
      "id": "admin",
      "type": "Role"
    }
  },
Copy code
permit(
    principal in Role::"admin",
    action in [Action::"export"],
    resource
)
when {
    resource.name == principal.allowed
};
However, if I try to add a list of resources to the admin role this error gets raised:
Copy code
{
    "attrs": {
      "allowed": [
        "mailer",
        "rate_analysis"
      ]
    },
    "parents": [],
    "uid": {
      "id": "admin",
      "type": "Role"
    }
  },
Copy code
permit(
    principal in Role::"admin",
    action in [Action::"export"],
    resource
)
when {
    resource.name in principal.allowed
};
Copy code
{
  "decision": "Deny",
  "diagnostics": {
    "reason": [],
    "errors": [
      "while evaluating policy admin_0.cedar, encountered the following error: type error: expected (entity of type any_entity_type), got string"
    ]
  }
}
I'm loading data into OPA via a data.json file. And, I'm wondering what syntax mistake I'm making.
o
I will have to take a closer look at it, I’ll check it tomorrow morning. In the meanwhile you can check the parents approach
👍 1