https://authzed.com logo
Question about zookies and consistency
e

ethanlew

03/13/2023, 5:20 PM
Question about zookies and consistency - what’s the practical risk of not using zookies at all? My understanding is that if no zookie is provided with a check request then cached relation data will be used if available - does that mean that, for an object that was just created, there’s a high likelihood that a check will fail? Consider this use case - I post to my feed and should be able to see it immediately on my feed. Do I need to use zookies to ensure this flow works?
v

vroldanbet

03/13/2023, 5:32 PM
there is the potential that could happen, yeah. I depends on various factors, hence if you are expecting read-your-own-writes consistency, use
AtLeastAsFresh
with ZedToken or check with
FullConsistency
e

ethanlew

03/13/2023, 5:56 PM
Have you seen any patterns for easily implementing this? Feels like storing a new type of data across our microservice architecture is a non starter and so using FullConsistency is the answer - but to minimize the calls using that we’d have to read the createdAt time stamp of the object first and only use it if createdAt is within the last few seconds or so
v

vroldanbet

03/13/2023, 6:16 PM
it's an integral part of Zanzibar's design. Zanzibar is fundamentally a very clever cache for authorization, but in exchange it asks for cooperation to achieve strong consistency and scalability. Authorizing fresh data is inherently going to be more expensive because the chances that data was already cached are low, so even if you used ZedToken, it does not mean database reads will be completely avoided. For this specific scenario, and depending on your client application and setup, the difference between using
FullyConsistent
and
AtLeastAsFresh
may not that significant, but it sounds like the cost of asking different service to store a ZedToken would definitely offset that. If I understand that what you want to do is that after a X amount of time (presumably the quantization window you've configured SpiceDB with), you'd call
MinimizeLatency
, correct? In theory that would work, but as you probably know clocks in distributed systems can be a bit picky 😜 @Joey @jzelinskie do you guys have perhaps other ideas?
j

Joey

03/13/2023, 6:17 PM
You could use a zedtoken store in something like redis
e

ethanlew

03/13/2023, 6:18 PM
Honestly I’m not following that last paragraph at all - regarding MinimizeLatency etc.
Hey @Joey - thanks for jumping in. I think this will be a good topic to work through as we partner during a trial. We’d obviously like our architecture and infrastructure to be as minimal as possible.
v

vroldanbet

03/13/2023, 6:23 PM
So the SpiceDB API allows you to define the consistency you want in your requests: - minimize latency gives you the answer based on whatever is cached, with potential stale results, but within a maximum window called the "quantization window" - fully consistent is "do not use the cache at all, always query DB" - at_least_as_fresh is "I'm ok with certain bounded staleness", the result should not use cached results that are older than the point in time represented by the token
what I proposed was to start use a different consistency that would leverage the caches once you know the object is "old enough", but unfortunately that does not guarantee you'll never get a stale result, because a change to any part of the graph could affect the result of your request, yet you are only making the decision around the requested consistency based on one single object in your database
e

ethanlew

03/13/2023, 6:35 PM
Ok I think I’m following you now. Thanks for the details. I think we’ll need to discuss this in greater depth on a call at some point. Given the many variables with caching, on top of the fact that a write is async - it’s not clear to me how we can guarantee that an owner can always view the thing they create, let alone friends of the owner etc.
I think it might come down to solving some edge cases outside of spicedb, or just being ok with some room for error
v

vroldanbet

03/13/2023, 6:45 PM
putting SpiceDB aside for a moment, how does your architecture propagate changes? Are you using something like Kafka and services mantainers would be listening to the relevant events?
e

ethanlew

03/13/2023, 9:12 PM
Exactly! Yes
I didn’t consider it before but I suppose we could write spicedb relations in a synchronous way - like include that write as part of a creation flow for cases where an async write might not work well.
So mix and match sync vs Kafka async depending the use case. We can likely depend on async for the majority though.
j

jzelinskie

03/13/2023, 9:21 PM
Correct! If you're already eventually consistent because of using Kafka, it's honestly a matter of just how much each application can tolerate. You've probably already architected your services to tolerate some amount of eventual consistency.
ZedTokens are not always required, but their existence is important. If SpiceDB wasn't designed at all to support them and you hit a scenario where you needed immediate consistency, you'd have no solution but to rearchitect everything. Because they're opt-in, you can choose to only apply them where necessary to get the best of both worlds.
j

Joey

03/13/2023, 9:42 PM
yeah, you'd do a write and store its zedtoken if you wanted to provide "immediate" access to the user that was just granted access
v

vroldanbet

03/14/2023, 8:51 AM
>putting SpiceDB aside for a moment, how does your architecture propagate changes? Are you using something like Kafka and services mantainers would be listening to the relevant events? In case you wanted to continue doing async, I could imagine a flow like this: - Service A writes object and emits event (watch out, this is a dual-write, ideally you do Event Sourcing, so first emit event, and then write object based on event) - A "PermissionUpdaterService A" listens to event from ☝️ and writes the corresponding relationship(s) to SpiceDB. After that it emits an event like "PermissionChanged" with the ZedToken - Any service that needs to check for permissions for that object will use
FullyConsistent
, until the event with the
ZedToken
arrives, and then they use it with
AtLeastAsFresh
>I didn’t consider it before but I suppose we could write spicedb relations in a synchronous way - like include that write as part of a creation flow for cases where an async write might not work well. Assuming you refer to doing the business object and SpiceDB relationships synchronously: you can, but please note this is also a distributed transaction, which comes with its own challenges. Do this is your application is ok with the possibility that one of the writes fails, but the other one is never rolledback. If that's completely unacceptable, then I'd suggest the Event Sourcing based approach described above, since you have Kafka in place already. Another alternative is using a workflow engine (https://github.com/meirwah/awesome-workflow-engines) like Temporal which solves the distributed transaction problem
e

ethanlew

03/14/2023, 3:18 PM
> but please note this is also a distributed transaction, which comes with its own challenges Technically, emitting a Kafka event from application code is also a distributed transaction, and unfortunately that's not typically solved for by application servers. But your warning is fair - we will weigh the risks!
v

vroldanbet

03/14/2023, 3:25 PM
you mean just emitting an event and not DB write + event?