Yet another question about ZedTokens.
# spicedb
s
Yet another question about ZedTokens. Having hard times understanding how and where to store them. Details in thread, thanks in advance for any clarification
Copy code
definition user {}
definition folder {
    relation owner: user
}
definition file {
    relation folder: folder
    permission access = folder->owner
}
1) Create new folder. Perform a single WriteRelationships call with the following content: folder:docs#owner@user:alice I get zedToken1 in response. I assume it should be saved alongside folder entity somewhere (https://authzed.com/docs/reference/zedtokens-and-zookies#when-adding-or-removing-a-relationship-for-a-resource) 2) Add new file to the folder. A single WriteRelationships call: file:doc1#folder@folder:docs I get zedToken2 in response. According to https://authzed.com/docs/reference/zedtokens-and-zookies#when-adding-or-removing-a-resource I should save it alongside the folder as well. But since this is also a file creation, I should save this alongside a file too? 3) Now I want to check file:doc1#access@user:alice. Is that correct I should use zedToken saved alongside the file (zedToken2)? 4) Now I want to transfer ownership to Bob. First I call DeleteRelationships folder:docs#owner@user:alice. I receive zedToken3 and store it alongside the folder. Then I call WriteRelationships folder:docs#owner@user:bob. I receive zedToken4 and store it alongside the folder. 5) Now I want to check file:doc1#access@user:alice again. But file's zedToken is not updated, since file was not modified or moved. So alice still has access at zedToken2 and bob does not. What am I missing here? Should I use zed tokens differently here?
j
no, this is correct
the "issue" is #5: you're assuming you need read-after-write protection there
but you don't
really, you only need to store a zedtoken for the file itself when contents change IF you want to be protected from the new enemy problem
otherwise, if you're using this solely for read-after-write consistency, then the question becomes: when do you need that?
s
I assume, for user to see a file content that he has already seen some time ago is considered valid and is not a new enemy problem, right? I use file/folder notation here just as an example. You can think of it as something different. E.g
Copy code
definition user {}
definition playlist {
    relation owner: user
    relation viewer: user

    permission view_content = viewer + owner
}
definition video {
    relation playlist: playlist
    permission access = playlist->view_content
}
I want to group entities under a parent and manage per entity access via group permissions.
j
sure
but the question is: what problem are you trying to solve?
if it is new enemy, you store a zedtoken when the file or video contents change
and then use that
otherwise, the cache should be sufficient
s
I am trying to prevent user access entities after I modified group permission. So yes, read-after-write protection as you mentioned. > otherwise, the cache should be sufficient yes, but I may get stale results (depending on my quantization config). I understand that new enemy is about content change and zedTokens alongside file content would work. I simoly wonder is there a way to have similar behaviour for group permissions as in example above
> yes, but I may get stale results I understand that I can use fully_consistent, but that is unwanted due to performance considerations. Any other ideas maybe?
j
why is it important to prevent user access immediately after group permission change?
s
hi, sorry for the delay > why is it important to prevent user access immediately after group permission change? this is a part of our business logic, so I want to understand whether SpiceDB is suitable for such case
I understand that my case is solved if I make two checks: for group and then for file
A more realistic use case when finance is somehow involved
Copy code
definition user {}

definition company {
    relation accountant: user
    relation member: user

    permission view_money_stats = accountant
}

definition campaign {
    relation company: company
    relation webmaster: user

    permission setup_traffic = webmaster
    permission view_money_stats = setup_traffic + company->view_money_stats
}

definition offer {
    relation campaign: campaign
    permission view_money_stats = campaign->view_money_stats
}
1) write
company:myCoolAds#accountant@user:alice
. I store zedToken1 alongside myCoolAds 2) write
campaign:asiaCampaign#company@company:myCoolAds
. zedToken2 alongside myCoolAds (link to parent) and asiaCampaign (resource creation) 3) write
campaign:asiaCampaign#webmaster@user:bob
. zedToken3 alongside asiaCampaign 4) write
offer:spicedbMeetup#camplaign@campaign:asiaCampaign
. zedToken4 alongside spicedbMeetup and asiaCampaign 5) check
offer:spicedbMeetup#view_money_stats@user:bob
at zedToken4 from spicedbMeetup. has permissionship 6) write
campaign:asiaCampaign#webmaster@user:jack
. zedToken5 alongside asiaCampaign 7) delete
campaign:asiaCampaign#webmaster@user:bob
. zedToken6 alongside asiaCampaign 8) write
company:myCoolAds#accountant@user:kate
. zedToken7 alongside myCoolAds 9) now I want to check
offer:spicedbMeetup#view_money_stats@user:bob
again. But zedToken stored alongside spicedbMeetup has not changed, so I use zedToken4 and bob still has permissionship. When working with money related resources/permissions it is essential to perform checks such that they do not give false positives or negatives. One could argue, that fully_consistent is the key here, but in high-load system that would result in underlying storage overload. ZedTokens seem to be a viable solution for achieveing both performance and correctness, but they don't seem to work with nested schema as in the example above. I chose to store zedTokens according to https://authzed.com/docs/reference/zedtokens-and-zookies#how-do-i-use-them. So my question is: am I storing zedTokens in a wrong place? Or is SpiceDB not suitable for read-after-write protection?
j
You’re saying that bob should not have access but he did have access a few seconds ago
That’s why I asked: for a read operation, he already had access so having access for a few more seconds isn’t leaking anything
That’s why it’s called the New Enemy Problem: Bob only becomes a new enemy if the information accessed has changed
for a write operation you’d check using full consistency before allowing access
The key insight is that stale reads are okay if the content has not changed
that’s why the paper says to update the zedtoken if the underlying content is changing (like in a document)
If you want to use cache and still have read after write you can store a zedtoken at a higher level
But that’s working around the fact that the cache is safe for reads
s
> The key insight is that stale reads are okay if the content has not changed yeah, I think that's the issue with my use case. In the latter example I assume that stats may be updated invisibly to SpiceDB which means offer's zedToken is not changed. Technically I don't have any write action here, but I guess business should determine "critical" permissions that must be checked using full_consistency and "regular" permissionships that allow stale reads
j
Correct
Generally any action which makes changes should use a fully consistent check if such consistency is needed
If stats are changed, so long as they cannot reveal any “new” information within a few seconds, it’s still safe
s
got it thanks a lot for a thorough explanation!
j
Of course
Now, this all being said, we have some ideas on how to improve the read after write experience to make this all easier
but still a decision would need to be made on when a cache is safe
g
Hi, today around 11/12 am central European time I had strange problems. Write transactions failed that later on succeeded. Is it somehow possible that this could be related to new enemy or some other kind of outage/conflicts? Calls were made from separate computers, but both in Germany.
j
on... serverless? what was the failure?
also, better to ask in the main channel rather than a thread
g
Sorry for the wrong channel. I will analyze the problem further before reposting it (if still necessary).
4 Views