-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding quip as a cedar use case #201
Open
anagella-dev
wants to merge
1
commit into
cedar-policy:main
Choose a base branch
from
anagella-dev:release/4.2.x
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Quip Policies | ||
Quip is a service thatcombines documents, spreadsheets, chat, into a powerful collaboration platform that integrates with Salesforce. Run `.\run.sh` in order to see the example authz requests for Quip. | ||
|
||
## Basic Model | ||
|
||
Quip has one principal type, which is a `User`. Users have a unique `id`, a `name`, a boolean value for if they are `disabled` or not, as well as an optional `shared_folder_ids` attribute that contains a set of all folders shared with them. | ||
|
||
Quip has two resources, `Threads` and `Folders`. | ||
|
||
A `Thread` has a unique `id`, an `author_id` of `User` type, and a `title`. They also have an optional set of Users under `user_ids` that are the individuals a document is shared with directly and not rhouh a folder. Threads have an optional `shared_folder_ids`, for all folders that exist in the shared list. To see the expanded list of users that are members of these shared folders, we have an optional `expanded_user_ids` attribute. The most important attribute here is the `access_levels` attribute, which is a set of `member_ids` as `User` types and their `level_of_access`. Finally, there is an optional parent_folder attribute, that contains the parent `Folder` entity (if there is one) of a thread. | ||
|
||
A `Folder` has a unique `id`, a `title`, a `creator_id` of `User` type, and a `member_ids` attribute which contains a set of all `User`s who are members of a folder. | ||
|
||
|
||
There are four levels of access a principal can have for a `Thread`. Those include `FullAccess`, `Edit`, `View`, and `Comment`. For a `Folder` a `User` can only have `FullAccess` or no access. Specific actions are further defined in the cedar schema. | ||
|
||
|
||
|
||
## Examples | ||
There are a few policies defined in `quip.cedar`, as well as sample entities defined in `entity.json`. The `run.sh` script runs multiple queries to confirm expected behavior for this data. To summarize the information in `entity.json`: | ||
|
||
### Entities | ||
There are three `Users` (principals): | ||
|
||
* Alice Smith | ||
* Bob Johnson | ||
* Charlie Brown | ||
|
||
|
||
As well as two documents (`Threads`) and a `Folder` they are in. | ||
|
||
* [Document] Budget Report | ||
* [Document] Meeting Minutes | ||
* [Folder] Administration | ||
|
||
|
||
And then another document that is not in any folder | ||
|
||
* [Document] Charlie’s Personal Notes | ||
|
||
### Assumptions | ||
|
||
* Alice Smith is an administrator, so she has access to the entire Administration folder as a member. | ||
|
||
* Bob Johnson is a part of the finance department, so he has individual comment access to the Budget Report, but no other documents in the folder. | ||
|
||
* Charlie Brown is an intern with no access to the Administration folder or documents in it. But he created the a Personal Notes document. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
[ | ||
{ | ||
"uid": { | ||
"type": "User", | ||
"id": "alice" | ||
}, | ||
"attrs": { | ||
"id": "alice", | ||
"name": "Alice Smith", | ||
"disabled": false, | ||
"shared_folder_ids": [{ "type": "Folder", "id": "administration" }] | ||
}, | ||
"parents": [] | ||
}, | ||
{ | ||
"uid": { | ||
"type": "User", | ||
"id": "bob" | ||
}, | ||
"attrs": { | ||
"id": "bob", | ||
"name": "Bob Johnson", | ||
"disabled": false | ||
}, | ||
"parents": [] | ||
}, | ||
{ | ||
"uid": { | ||
"type": "User", | ||
"id": "charlie" | ||
}, | ||
"attrs": { | ||
"id": "charlie", | ||
"name": "Charlie Brown", | ||
"disabled": false | ||
}, | ||
"parents": [] | ||
}, | ||
{ | ||
"uid": { | ||
"type": "Thread", | ||
"id": "budget_report" | ||
}, | ||
"attrs": { | ||
"id": "budget_report", | ||
"author_id": {"type": "User", "id": "some_user"}, | ||
"title": "Budget Report", | ||
"user_ids": [{"type": "User", "id": "bob"}], | ||
"shared_folder_ids": [{ "type": "Folder", "id": "administration" }], | ||
"expanded_user_ids": [{"type": "User", "id": "alice"}], | ||
"access_levels": [ | ||
{ | ||
"member_id": {"type": "User", "id": "alice"}, | ||
"level_of_access": "FullAccess" | ||
}, | ||
{ | ||
"member_id": {"type": "User", "id": "bob"}, | ||
"level_of_access": "Comment" | ||
} | ||
], | ||
"parent_folder":{ "type": "Folder", "id": "administration" } | ||
}, | ||
"parents": [] | ||
}, | ||
{ | ||
"uid": { | ||
"type": "Thread", | ||
"id": "meeting_minutes" | ||
}, | ||
"attrs": { | ||
"id": "meeting_minutes", | ||
"author_id": {"type": "User", "id": "some_user"}, | ||
"title": "Meeting Minutes", | ||
"shared_folder_ids": [{ "type": "Folder", "id": "administration" }], | ||
"expanded_user_ids": [{"type": "User", "id": "alice"}], | ||
"access_levels": [ | ||
{ | ||
"member_id": {"type": "User", "id": "alice"}, | ||
"level_of_access": "FullAccess" | ||
} | ||
], | ||
"parent_folder":{ "type": "Folder", "id": "administration" } | ||
}, | ||
"parents": [] | ||
}, | ||
{ | ||
"uid": { | ||
"type": "Thread", | ||
"id": "charlies_personal_notes" | ||
}, | ||
"attrs": { | ||
"id": "charlies_personal_notes", | ||
"author_id": {"type": "User", "id": "charlie"}, | ||
"title": "Charlie's Personal Notes" | ||
}, | ||
"parents": [] | ||
}, | ||
{ | ||
"uid": { | ||
"type": "Folder", | ||
"id": "administration" | ||
}, | ||
"attrs": { | ||
"id": "administration", | ||
"title": "Administration", | ||
"creator_id": { "type": "User", "id": "some_user" }, | ||
"member_ids": [{ "type": "User", "id": "some_user" }, { "type": "User", "id": "alice" }] }, | ||
"parents": [] | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
@id("thread_author_full_access") | ||
permit( | ||
principal, | ||
action in [Action::"ThreadFullAccessActions"], | ||
resource | ||
) | ||
when { | ||
principal == resource.author_id | ||
}; | ||
|
||
@id("folder_member_full_access") | ||
permit( | ||
principal, | ||
action in [Action::"FolderFullAccessActions"], | ||
resource | ||
) | ||
when { | ||
resource.member_ids.contains(principal) | ||
}; | ||
|
||
@id("thread_comment_access_if_user_access_level_comment") | ||
permit( | ||
principal, | ||
action in [Action::"ThreadCommentActions"], | ||
resource | ||
) | ||
when { | ||
resource has access_levels && | ||
resource.access_levels.contains( | ||
{ | ||
"member_id": principal, | ||
"level_of_access": "Comment" | ||
} | ||
)}; | ||
|
||
|
||
@id("thread_full_access_if_user_access_level_full") | ||
permit( | ||
principal, | ||
action in [Action::"ThreadFullAccessActions"], | ||
resource | ||
) | ||
when { | ||
resource has access_levels && | ||
|
||
resource.access_levels.contains( | ||
{ | ||
"member_id": principal, | ||
"level_of_access": "FullAccess" | ||
} | ||
)}; | ||
|
||
@id("thread_edit_access_if_user_access_level_edit") | ||
permit( | ||
principal, | ||
action in [Action::"ThreadEditActions"], | ||
resource | ||
) | ||
when { | ||
resource has access_levels && | ||
|
||
resource.access_levels.contains( | ||
{ | ||
"member_id": principal, | ||
"level_of_access": "Edit" | ||
} | ||
)}; | ||
|
||
|
||
@id("thread_view_access_if_user_access_level_view") | ||
permit( | ||
principal, | ||
action in [Action::"ThreadViewActions"], | ||
resource | ||
) | ||
when { | ||
resource has access_levels && | ||
|
||
resource.access_levels.contains( | ||
{ | ||
"member_id": principal, | ||
"level_of_access": "View" | ||
} | ||
)}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Entities | ||
// All enums are modeled as just String here | ||
|
||
entity User { | ||
id: String, | ||
name: String, | ||
disabled: Bool, | ||
shared_folder_ids?: Set<Folder>, // folders that are explicitly shared with the user | ||
}; | ||
|
||
entity Folder { | ||
id: String, | ||
title: String, | ||
creator_id: User, | ||
member_ids: Set<User>, | ||
}; | ||
|
||
entity Thread { | ||
id: String, | ||
author_id: User, | ||
title: String, | ||
user_ids?: Set<User>, // the individuals a document is shared with (not through a folder) | ||
shared_folder_ids?: Set<Folder>, // the folders added to a document (including the folder the document is in) | ||
expanded_user_ids?: Set<User>, // all the users in the folders | ||
access_levels?: | ||
Set<{ | ||
member_id: User, | ||
level_of_access: String | ||
}>, | ||
// access_levels will have all the necessary information about who has access to what (consolidates the user_ids, shared_folder_ids,expanded_user_ids in one place) | ||
// it does not however include author, so there has to be another policy for that | ||
parent_folder?: Folder | ||
}; | ||
|
||
//Actions | ||
action ThreadFullAccessActions; | ||
action ThreadEditActions; | ||
action ThreadCommentActions; | ||
action ThreadViewActions; | ||
action FolderFullAccessActions; | ||
|
||
action viewThread | ||
in [ThreadFullAccessActions, ThreadEditActions, | ||
ThreadCommentActions, ThreadViewActions] | ||
appliesTo { | ||
principal: User, | ||
resource: Thread, | ||
}; | ||
|
||
//Theres only full access or no access for folders | ||
action viewFolder, editFolder, shareFolder | ||
in [FolderFullAccessActions] | ||
appliesTo { | ||
principal: User, | ||
resource: Folder, | ||
}; | ||
|
||
action editThread | ||
in [ThreadFullAccessActions, ThreadEditActions] | ||
appliesTo { | ||
principal: User, | ||
resource: Thread, | ||
}; | ||
|
||
action shareThread | ||
in [ThreadFullAccessActions] | ||
appliesTo { | ||
principal: User, | ||
resource: Thread, | ||
}; | ||
|
||
action commentThread | ||
in [ThreadFullAccessActions, ThreadEditActions, | ||
ThreadCommentActions] | ||
appliesTo { | ||
principal: User, | ||
resource: Thread, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
echo "Testing that Alice can do all actions on the Administration Folder as a member" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"viewFolder\"" --resource "Folder::\"administration\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"editFolder\"" --resource "Folder::\"administration\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"shareFolder\"" --resource "Folder::\"administration\"" | ||
|
||
|
||
echo "Testing that Alice can do all actions on all Documents in the Administration Folder" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"viewThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"editThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"commentThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"shareThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"viewThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"editThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"commentThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"shareThread\"" --resource "Thread::\"budget_report\"" | ||
|
||
|
||
echo "Testing that Bob and Charlie can not do any actions on the folder" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"viewFolder\"" --resource "Folder::\"administration\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"editFolder\"" --resource "Folder::\"administration\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"shareFolder\"" --resource "Folder::\"administration\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"viewFolder\"" --resource "Folder::\"administration\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"editFolder\"" --resource "Folder::\"administration\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"shareFolder\"" --resource "Folder::\"administration\"" | ||
|
||
echo "Testing that Bob can access Budget Report with Comment actions" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"viewThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"editThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"commentThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"shareThread\"" --resource "Thread::\"budget_report\"" | ||
|
||
echo "Testing that Bob can not access Meeting Minutes" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"viewThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"editThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"commentThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"shareThread\"" --resource "Thread::\"meeting_minutes\"" | ||
|
||
echo "Testing that Charlie can not access Budget Report or Meeting Minutes" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"viewThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"editThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"commentThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"shareThread\"" --resource "Thread::\"budget_report\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"viewThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"editThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"commentThread\"" --resource "Thread::\"meeting_minutes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"shareThread\"" --resource "Thread::\"meeting_minutes\"" | ||
|
||
echo "Testing that Charlie has full access to Charlie's Personal Notes as the author" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"viewThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"editThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"commentThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"charlie\"" --action "Action::\"shareThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
|
||
echo "Testing that Alice and Bob do not have access to Charlie's Personal Notes" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"viewThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"editThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"commentThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"alice\"" --action "Action::\"shareThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"viewThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"editThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"commentThread\"" --resource "Thread::\"charlies_personal_notes\"" | ||
cedar authorize --policies quip.cedar --schema quip.cedarschema --schema-format cedar --entities entity.json --principal "User::\"bob\"" --action "Action::\"shareThread\"" --resource "Thread::\"charlies_personal_notes\"" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious: why is this field (and other Set-typed fields below) optional? If there are no folders shared with a user, this can be modeled as a required Set attribute, where the Set is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick conjectured answer (but curious about the correct answer): Maybe since it is possible to test that
shared_folder_ids
is present, but not (at the moment) possible to set whether a set is empty?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good point; that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thats a good point! I cant remember if I had tried the empty set but had remembered seeing the
has
keyword for policies with optional fields so went that route. Im still fairly novice with cedar syntax, but like Mike said I'm unsure if theres a way to test whether a set is empty.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A quick update. We've recently added the
.isEmpty
operator on sets, so if that was the main reason for avoiding empty sets, we now have a nice solution for it :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(The new operator is coming in version 4.3.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed this PR was still open and wanted to let you know that version 4.3, which includes the
.isEmpty()
function, is available now. The function is also documented here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Apologies, did not follow up on this. Will update this PR using isEmpty().