Comments (7)
Thanks for the suggestion! There are a couple different pieces here, and I'd like to make sure I understand them all (and make separate issues, as appropriate).
- Allow
like
to match on entity id. Currently,like
requires a string-typed expression on the left and a literal string (e.g.,"*.pdf"
) on the right. We do not support an expression likeresource like "*.pdf
, which could return true when the resource was something likeSome::Document::"foo.pdf"
. - Allow
like
expressions in the policy scope. Currently only expressions likeprincipal == ?principal
oraction in [Action::"Read", Action::"Write", Action::"Comment"]
are allowed in the policy scope. Assuming that change (1) was made, your example proposes that we allowlike
expressions in the scope as well. - Add support for a placeholder on the right side of a
like
operator. The only template placeholders we currently allow are?principal
and?resource
, which are both entities, whereaslike
expects a string on the right side (per (1) above). Independently of changes (1) and (2), it may be useful to support placeholders of other types (e.g., string) so that users could write expressions likeresource.some_string like ?pattern
, and instantiate with different strings like*.pdf
and*.txt
.
Is that a correct summary of your suggestion?
For your current example, here are some ideas for workarounds for each of the points above:
- Add a "filename" field to each resource, and use
like
to match on that. - Put the
like
expression in the policy condition instead of the scope. - Make a distinct policy for each type of filename you want to match on, or use
||
.
So, for example, a valid policy for your example in the current version of Cedar might look something like the following:
@id("Editor")
permit(
principal == ?principal,
action in [Action::"Read", Action::"Write", Action::"Comment"],
resource
) when {
resource.filename like "*.pdf"
};
from cedar.
Seems like the RFC process is a better way to deal with this: https://github.com/cedar-policy/rfcs
from cedar.
Thanks for your comments @khieta!
Let me give a little more context that may make this make more sense. Sorry for not providing it earlier, it's just so ingrained in how I think about permissions that I don't always think to mention it.
We have a system that is similar to GCP IAM Roles. The idea is that a "Role" is a predefined set of permissions. At the time you grant the role, you specify the principal you're granting the role to and the resource(s) you're granting the role on. Template linking seems purpose-built for this. A "Role" becomes a policy template, and granting the role is creating a template link.
The wrinkle here is that we allow our users to grant roles on patterns of resources, not just one resource at a time. For example, maybe the user wants to grant access to all Kafka Topics that start with us-finance-
to their new accountant. The like
operator seems purpose-built for this kind of thing.
We want to combine these two Cedar features.
Addressing the pieces questions:
- That's right. Being able to write things like
resource like Document::"*.pdf"
orresource like Kafka::Topic::"us-finance-*"
would allow granting the "Role" on a user-specified set of resources. - Thanks for pointing out that
like
isn't supported in the scope. I wasn't aware of that. At the end of the day, I'd be just as happy to do that test in the condition, but see: #81 - Yes, that's right. We'd like to specify the pattern at grant time.
And thanks for the suggestions. Comments on those...
like
matching on an attribute would work, but in the current version of Cedar, that would mean giving up on using policy templates and doing substitutions ourselves. I guess we could create a policy template template like:
permit(
principal == ?principal,
action in [Action::"Read", Action::"Write", Action::"Comment"],
resource
) when {
resource.filename like "{{ escaped_pattern }}"
};
And substitute the {{ escaped_pattern }}
and then create a template link to fill in ?principal
, but if we're going to do that, it seems more straightforward to just do all of the substitutions and avoid template linking altogether:
permit(
principal == {{ principal }},
action in [Action::"Read", Action::"Write", Action::"Comment"],
resource
) when {
resource.filename like "{{ escaped_pattern }}"
};
Then every grant is a new policy.
2. We'd be happy to do the check in the condition instead of the scope, but we still want it to be against a placeholder.
3. We were hoping to avoid creating lots of new policies.
Maybe the outcome here will be "Template linking isn't for that. Just create more policies." But the system seems very close to being able to do this.
Thanks again for your consideration!
from cedar.
A "Role" becomes a policy template, and granting the role is creating a template link.
Yes, I think this is a natural way to think about things. Another way to do this is to use the entity hierarchy to help express roles. For example, you could say that every user in UserGroup::"roleA"
is allowed to read/write all files with a name like *.doc
using the following policy:
permit(
principal in UserGroup::"roleA",
action in [Action::"Read", Action::"Write"],
resource
) when {
resource.filename like "*.doc"
};
Then when you want to give a user User::"alice"
this "role", you can add UserGroup::"alice"
to be a member of UserGroup::"roleA"
in your entity hierarchy.
You could also do something similar to group files together. For example, you could create an entity FileGroup::"doc"
that will be the parent of all files with an entity ids like *.doc
, and then use a template like
permit(
principal in ?principal,
action in [Action::"Read", Action::"Write"],
resource in ?resource
);
where you instantiate ?principal
to be UserGroup::"foo"
(for example) and ?resource
to be FileGroup::"doc"
.
But getting back to your original question: If you're ok with the "filename" solution, then I think you'll want to file a new issue that requests allowing templates to be instantiated with non-entity type values (String
s in this case). If the "filename" solution won't work for you, then you could consider the group-based approach above, or narrow the scope of the current issue to ask for allowing like
operations on entity ids.
from cedar.
One more comment: in your example, I think there is still value in using template-linking in the first case:
permit(
principal == ?principal,
action in [Action::"Read", Action::"Write", Action::"Comment"],
resource
) when {
resource.filename like "{{ escaped_pattern }}"
};
Although it is inconvenient to have to manually create different templates for different filename patterns, you still get the benefit of have a single template definition for multiple ?principal
s, which allows you to update multiple policies from a single location.
from cedar.
Thanks for the further responses.
My feature request is that I be able to use template linking to grant permissions on patterns of resources.
The filename solution does not accomplish that, because I can't use template linking to supply the pattern for several reasons:
- placeholders are not supported in conditions (see #81)
- the existing placeholders can only be filled in with entities, not strings
like
RHS must be a literal
I've made a more focused feature request here: #119. And there's a related one about type comparison here: #94.
But there are a bunch of potential solutions to my feature request:
like
on entity patterns (# 119) +like
RHS can be a placeholder +like
allowed in scopelike
on entity patterns (# 119) +like
RHS can be a placeholder + placeholders allowed in conditions (# 81)- placeholders can take strings + type comparison (# 94) +
like
RHS can be a placeholder +like
allowed in scope - placeholders can take strings + type comparison (# 94) +
like
RHS can be a placeholder + placeholders allowed in conditions (# 81)
There are probably other solutions that I haven't considered.
If you would like, I can file more feature requests to accomplish the parts, but that feels like I'm requesting a particular implementation, rather than a feature. I'd rather leave the team free to choose whatever solution they think makes the most sense.
from cedar.
Closing this issue in favor of rfc#3 (formerly issue #81) and #119.
from cedar.
Related Issues (20)
- Key-only policy annotation HOT 2
- JSON-to-human schema translator should only insert `__cedar` on primitive/extension types if necessary
- (De-)serialization of PatternElem under the Arbitrary feature HOT 1
- Better error message when forgetting `appliesTo` in the human schema format
- Better error message when incorrectly using `;` after a namespace declaration in human schema format HOT 1
- Translate serde-json error line and column into miette source spans HOT 1
- Change `Policy::parse` to take a `PolicyId`
- Attempt CST to AST conversion even when parsing fails for some policies
- EST parser and Cedar parser return different ASTs on policies with functions named "unknown"
- Converting a JSON-syntax schema to human syntax and back can change the target of an entity type reference HOT 1
- Allow common types in entity parent-types lists and action `appliesTo`
- Convert a JSON object to an Entities type HOT 5
- Support named constants, or imports? HOT 1
- Validator should error on JSON schema containing unused, undeclared common type of type `Entity`
- Reserve `Set`, `Record`, `Entity`, `Extension` in schemas
- Additional APIs for manipulating schemas HOT 1
- Carry source info through schema structures HOT 1
- Generate schema warnings later in the process
- Allow reopening a namespace in human-syntax schemas
- Improve parse errors on parenthized "special" expressions
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cedar.