About this video
What You'll Learn
- Model permissions with relations and permissions instead of hand-rolled ad hoc checks
- Use the zed CLI and Playground to test schema behavior before shipping
- Apply caveats and expiring relationships for contextual access and time-bound authorization
Jimmy Zelinskie, AuthZed cofounder, walks through SpiceDB from the ground up: why Google's Zanzibar paper reframes authorization, how to model schemas with relations and permissions, caveats, and using the zed CLI and Playground to test real applications.
Full transcript
Generated from the English captions. Timestamps jump the player to that moment.
Read the full transcript
0:01 David Flanagan here. Let's take a dive. Tonight the spotlight's not on the host you see. It's on a piece of tech meets Spice DB. Fine grained permissions done the modern way. Gonna unpack it all starting today. Oh, Spice He'll share the insights, show us how it's done. The power of Spice DB second to none. Raw code live with Alright. Hello, everyone, and welcome back to Rawkode Live at the Rawkode Academy. I'm your host, Rawkode, sometimes known as David Flanagan. And today on Rawkode Live, we are taking a look at another exciting open source project called SpiceDB.
2:08 And I'm really excited for this. I wanted to do an episode on this for a while because this is something that I have personally implemented badly at nearly every job I have ever had, and that is authorization. So today, we're gonna see how to do this right. And to guide us on our journey today, I am joined there we go. From Jimmy, cofounder and CPO at Offset and maintainer of SpaceDB. Hey. How's it going, man? Good. Good. Thanks for having me. Absolute pleasure. I like I said, I'm really excited for this episode. It's a great piece
2:41 of tech, and I'm looking forward to showing people how to get started and hope to be successful. And I can only imagine the amount of times I've seen permissions and authorization done badly in my life that you must have seen a whole lot more. But before we get into that, could you just take a moment, say hello, and introduce yourself to the audience? Sure. Hey, everyone. I'm Jimmy Zelinsky. I'm one of the cofounders of a company called OpZed. I'm sure we're gonna get way deeper into that in this this call, but I guess my background is just both in
3:13 product and engineering as a software engineer for many years, mostly working in kind of like background kind of cloud native ecosystem, just kind of as it all emerged And, I kinda transitioned as I had more opinions on how things should be architected into more product leading role. But, yeah, I have worked on a bunch of, like, main projects in the CNCF space and then also, I'm an OCI maintainer. So that's the standards for containers. Awesome. Thank you so much for sharing all that. Alright. Let's talk about SpaceDB then and give people a bit more, of a background of
3:51 understanding than what they're gonna see today. Right? So I said SpaceDB is their authorization. Right? And then I'm assuming this is something that, you know, maybe not all projects, but I'd say a large percentage of projects need to handle permissions of some sort in their application. And, yeah, I wasn't lying. I've built this wrong so many times in my career, or at least I've taken a rather naive approach to permissions. And SpaceDB, especially when you start to play with it, it reveals so much about why I've been wrong in my entire career. And I'll share
4:25 more of it as as we go, but maybe you could give us a bit of the background. Right? How did you end up in this space? Why is the Zanzibar paper inspiring in this open source project? And how can we do permissions? Like, what is the landscape of permissions that you've seen in your past and where we are today? And that's a lot. Sorry. I just threw that right at you, but, you know, good luck. Yeah. No. That's a great great kind of intro context laying. Kind of as you were saying, I personally have also
4:52 seen every rendition of kind of authorization or permissions implemented across a bunch of different applications I worked on in my career. And the reality for this is there's been years and years of research in the authorization space, but there's not really a strong cohesive narrative in the space or best practices that are well described in a way that most developers are educated. So when it comes time to build this part of the functionality for your application, a lot of folks just don't really know what to do. They hear their end customers throughout terms like RBAC,
5:32 and they kind of have used other applications, something like GitHub probably where they they know there's like organizations and teams and roles, and they could probably model something just similar enough to that. But I guess, just taking a step back, my background and, like, the the main project that kind of, like, inspired most of our work transitioning to work on SpiceDB and founding Offset was actually Quay, which is the first private Docker registry. So, my cofounders and myself worked on that back in the day and this was before kind of Docker even had any, enterprise or way
6:13 to store images in a registry privately. There is only the public index of images that people could share. And when you think about it, the core differentiating feature, like the main feature between Quay at the time and kind of like the open Docker index was authorization. That that was it. The ability for you to make images private. That was the core functionality. Everything else was just kind of layering on kind of nice to have, but where, where rubber meets the road and where people what they were paying for ultimately was the authorization scheme built on top of the standard
6:49 container registry. During that journey, we realized there were some features that the juice just wasn't worth the squeeze to implement the proper security primitives in our authorization model to even ship those features. And even to this day, a bunch of those features have never shipped in Quay simply because it would take too long to really go through with a fine tooth comb, the custom code we had built and, kind of cohesively create a new model, test it, build our confidence in it, get security auditors in there so they can look over it before it ever gets deployed to, an enterprise environment.
7:28 Right? And, it just takes really senior engineers to kind of go through that. There's very painstaking progress or a process, and there's time to be spent better elsewhere on the project, building out some other more important feature. So sometimes you just get into this little rut. They're like a local maximum. The features you can actually build just based on your authorization system. And we just kinda looked at ourselves, and we're like, there's gotta be another way. Right? There's always a better way to do it. And that was largely when Google published the Zanzibar paper, and that paper kind of models the system
8:03 that Google designed internally. This was originally actually to drive kind of the functionality in Google plus if you're familiar with that. And the the really interesting thing about Google's paper and the reason why I think it's, like, more novel than a lot of the other kind of authorization authorization research that came out, mostly because it talks about a cohesive system. If you go and read papers on authorization or even blog posts, you'll hear about RBAK and ABAC, and they'll talk about this concept, these ideas for how you can organize stuff, but they won't tell you, like, this is what a
8:42 comprehensive deployed real world system looks like built with these ideas. And the Zanzibar paper is that. It's actually kind of a retrospective paper looking back on the system they built, how it scaled, how how they ran it in production for a while, the things they have learned, and it gives you the holistic perspective to kind of understand, what goes into a robust authorization system and the framework that drives it. So I hope I did a good job answering your question. Yeah. Definitely. For sure. And then I think it leads us in nicely as we kinda
9:19 explore SpaceDB in more detail. But I'm also gonna come back to my my failures throughout my career because I feel like there's a certain pivot point where you realize just how important correct offset permissions are in your application because they're not something that are easy to fix retroactively. And I'm I'm sure if that resonates with anyone that been in in my position, hopefully, maybe your position at some point too. Right? But let's assume you start off with a simple application and you start off with a simple RBAC model. Right? A user has some sort of role and that role has permissions
9:52 across everything in the system. That's typically how I used to do it. Right? You say a user is an editor. They can edit articles. Job done. Right? You never really take it any finer grained than that. And then at some point in my application, we decided, okay. Well, actually, people are gonna have multiple roles because we can have editors, but you could also be an admin and you could also be this. And this is where we go from this flat one to one mapping of roles to users. If you were silly enough to build it
10:16 that way, which, of course, I have many times. And then you you start getting fancy. And, again, I'll lean on my own experience where, like, why don't we just store an integer and where they, like, shift some bets for every role and then if that bets active, you'd and then it sounds fancy and it sounds cool and then you realize you're in a world of heart later on. That doesn't scale either. But then you're so ingrained in this model that whenever you want to do anything that is truly sophisticated and goes beyond the simple RBAK premise, it fails substantially.
10:44 And this is I don't know if there's a certain point where or a type of system maybe this is a a good question. Right? Like, at what point do you need a SpaceDB verity just flipping a column in a database? And the example I had in my head is, like, fine. If you've got a flat system with user rules and content, fine. I think it be again, the quick example is perfect. Right? You've got user generated content, and their permissions are not gonna be something that is easily baked into the system as a whole. I don't even know if I'm explaining this
11:16 correctly, but there's definitely a point where SpiceDB and this model and the Zanzibar implementation, all of this comes together, and it's like a eureka moment. And I wish I had it sooner, but I didn't. And yeah. Maybe you can kind of get this, like but I'm gonna keep just talking at you, then you can just keep nodding at me. But let's try and find our actionable question here. Where do you see think I know your question. Your question is, like, when do you introduce something like a SpiceDB in in a project. Right? Well, I was actually gonna make it simpler
11:48 to start and lean into that. Right? Should every system use SpiceDB? Let's start with that. I think the answer to that is no. Right? If you're if you're just building an MVP of your app, like, you you're a startup founder and you're trying to test to see if an idea has product market fit and you're really early into the process, I do not think outside of a couple niche kind of domains, so say you're, trying to build a healthcare startup or something like that, where you're gonna have more sensitive authorization logic, things where you're like managing
12:21 when doctors are assigned to particular offices in these particular hours. They're allowed access to this customer information, like or this patient information. If you know there's something like that, you probably wanna invest in SpiceDB really early on. Otherwise, if you're kind of building a standard SaaS app, the very beginning of your project when you're kind of, like, trying to find your initial customers, things like that, it's just not the right time for something like this. Like, you're gonna be writing a lot of code you're gonna end up throwing away later. And I think the the point
12:53 is you should be focusing on kind of, like, figuring out if your product is gonna succeed. But there comes this kind of phase of when you're developing your product where the customers are gonna start coming to you, probably enterprises depending on what software you're building, and they're gonna start asking for things like, hey. We're trying to model our, like, structure of our business so that we can have multiple teams inside your application. And I feel like once you get to that point where, the customer feedback is flowing that you need better kind of organization around your resources
13:30 and the permissions that are maybe trying to sink in even, that's when you need to start evaluating something like SpiceDB or other authorization tooling because now you're kind of it's it's not just like, okay, we've proven out our idea. Now it's looking at it as like an investment into the future of the product and giving yourself a foundation that you can change and maintain the velocity with which you're developing your application. Because if you end up building something yourself, it'll probably work for a little bit, but also you're not giving yourself kinda like that foundational piece that you can mold
14:06 in different ways. So you're gonna build something really brittle, and then you're gonna throw it away and have to rebuild it. And then you'll build the new thing also brittle for the new requirements, and then you're gonna throw that away eventually when you get even more requirements. Right? And it's just rinse and repeat. And folks don't as they're building their application, they're not thinking about how to make, the most robust authorization foundation that's future proof for them, that's gonna be easy for them to maintain over time. That's something that only people working full time on authorization systems think about.
14:39 So really, I think it's at that phase where, like, the customers are coming to you asking for these things that you need to consider, like, okay, I need real tooling for this that's that I'm going to invest in and invest in my product over time. And and that's that's really when I would say start looking at something like SpiceDB or plenty of the other tooling that exists for an authorization. Just don't build the stuff yourself because I think that's where people fall into the trap of hurting themselves over and over and over again. Alright. Awesome. Thank you.
15:10 So you mentioned, you know, SpaceDB is inspired by the Zanzibar paper. You've kinda touched on that a little bit. Maybe we could go into a bit more detail, you know, for the people watching. What is different from, you know, the naive implementations I talked about versus what SpaceDB is doing. Like, how do people make that cognitive shift from, okay, I know this to, okay, I need to start doing this. Yeah. I think to some degree, the most naive take people have when they build authorization themselves is they probably store some data in their database. Like, say they're
15:45 building a Rails app, they're gonna do what they do with everything when they're building a Rails app. They're probably gonna use their the active record ORM to model some some tables that they're gonna store inside their database and they're probably gonna pull that data down when a request comes in and then they're gonna execute some Ruby code that has custom logic in it to interpret that data to say like, alright, is this person allowed to perform this action? And kind of the major problem there is, like, the the data that gets stored in the database,
16:18 I never told you anything about structure or shape. Right? And then the logic written in Ruby, never told you what any of that logic actually is. And those are both gonna change a lot over time. And it's gonna be a lot of complexity management around that. The other question that you have in this this kind of system is that it works when it's a monolith, but like you start introducing microservices and now that data lives inside of the monolith database. But say you have another service and it needs to check some of those permissions. What you end up doing is, like, you
16:53 build this ad hoc permissions API into your monolith. And now that's, like, not great because the whole point of microservices is to get the monolith out of the critical path. Right? And, like, kind of break down pieces into orthogonal components. But now everything has to check preflight things to the monolith before it can do work. So you kind of get into this place where, it's definitely not gonna last you forever. Right? And so the Zanzibar paper says, alright. You you could abstract the code that you've written in your monolith and pull that out, and use it as a library, but still
17:31 doesn't solve that problem, that data living inside the monolith database until you have a centralized kind of authorization service at your business. So the same way you would make a microservice of other domains, why don't you have a microservice that's dedicated to checking permissions? And what's really cool about that idea is that can be shared across your entire product portfolio. It's not just used for one particular app. So that means you can implement these really interesting experiences. So say you're Google, and this is a real example. If you're Google and you, if you open up Gmail and you paste in a
18:12 Google Doc link and then try to email it to someone, Gmail will actually preflight a request to Zansbar that says, can the email recipient actually see, like, do they have access to read this Google Doc? And Google Docs has no idea. It doesn't share any code with Google Drive. There's there's no kind of shared logic there. All it's doing is is sending a request to Zanzibar saying like, hey, does this email have access to this URL? And you get to build these deep experiences. That's a really powerful experience. Actually, if if you say like if it finds that the person
18:51 doesn't have access, can actually remediate it then and there in in Gmail as well. So you can give people access without the back ends having any shared code, which is kind of crazy. But you can build these super deep integrated experiences once you have all the permissions kind of living in a centralized place. Another example would be like, if you are an engineer at Atlassian building confluence, you could write rules like if a Jira ticket is embedded in this confluence page, if someone has access to this confluence page, they should inherit access to the Jira tickets that
19:27 also live inside of that page. So now you get kind of like this really, nice kind of cross product unified view of kind of permissions across your product suite. I just don't think there is many other solutions in the space that give you that kind of experience and give you that kind of central central way to manage and model and understand the permissions across your products. So Alright. Yeah. Fantastic answer. So I think with that, we've hopefully given everyone watching enough context to understand the old, the new, and now we can guide them through some steps. I'll also just
20:05 show there's some content on the Offset YouTube channel, which was invaluable to me when I was learning the SpaceDB, which is the session where you built think it was the GitHub permissions model video. That is a if this video doesn't help you, which I hope it does, go check that one out later. So I am going to share my screen, and we will kick this off. Alright. No computer signal. It'll pop up that it was, like, requesting me to share my screen. I'm not sure that was right. Well, I changed it over. So it it should just be me now,
20:51 and here we go. Perfect. Alright. So this is offset.com/spacedb. From here, you can learn more about how to work with things, understand the lexicon, and then there's a guide over here to learn the basics, as well as a few other useful pieces of documentation for anyone working through learning in SpaceDB. It is, of course, open source, so feel free to check out the repository. Something that I also found useful is examples repository, particularly the schemas directory. It's good for understanding how to model certain use cases. And we also have the SpaceDB or the offset playground, which allows you to
21:31 run tests against the models and definitions that you put together. So given all of this, I'm hoping that we can come up with some interest in use cases just to show people how to build that model. Because, again, I'm not coming into this completely, you know, often with Rawkode Live is, like, I've never heard of the project before. I've heard of it. I've never played about it. And we're supposed to be a little bit further along. So, hopefully, we can just take some of my challenges. And for me, the challenge was building the schema, the model,
22:01 understanding how to put that together rather than interacting with the code and speaking to the database and and querying things. So I really want us to spend, not labor it, but spend a bigger amount of time because your people understand how to put that together. That makes sense? Yeah. I think that makes sense and it's definitely the place you probably wanna spend the most time. Conceptually, I'm pretty sure most people that are, like, jumping into this are gonna understand, oh, okay. This is how you deploy something on Kubernetes that's cloud native and package it as a container.
22:32 And that's pretty much all it takes to run SpiceDB. It's mostly just like, what's the value for you and how are you modeling your domain? That's probably where people want to learn the most and understand the most. So totally agree. I think that it's where the cognitive shift is. Again, we've all you know, everyone can't keep putting words in people's eyes. I'm gonna assume most people have worked with permissions are now back to some degree. And I hope that they come into it with their own use cases so we can show them how to go from a use
23:01 case to build in the model, then we can get into playing playing with it in other regards. Nobody on this channel needs to know how to do a Helm Deploy. Like, we're way past that now. So at least I hope we're 2025, so fingers crossed. Alright. Now in the documentation, you do cover modeling and concepts and stuff like this, and there are examples here that we could kinda lean into and show. And I think maybe we just pick one and start with that. Possibly just the I think the the blog one here. Does that have a yeah.
23:30 Schema here. So maybe we can kinda work through this, but then we can tackle it and talk about maybe something that's a bit more cloud native. And then I'll throw this to the audience. Right? If you don't give me a suggestion in the next five minutes of something that you would like to see modeled with the schema, just to put, you know, Jimmy on the spot, then we'll go with one of my own things that I actually need for the Rawkode Academy platform, and I can provide more context on that as we go. Now when people are adopting and they want
23:58 to start bringing SpaceDB into their infrastructure or offset, I think you kind of said it a minute ago. Right? But the first thing we need to have is that knowledge of the domain. What are we building the model and the schema for to get started? And in this documentation example, we talk about protecting the blog. So I'm assuming the context is you're building a website, it has some sort of articles, and you have two different roles. Someone who could read an article, someone who can write an article, and maybe even as a third where someone can edit an article that has
24:32 already been written or published. And we could take this even deeper if we want to, but we'll keep it superficial for now. When you have that domain knowledge, as rating your schema step number one for adopting SpaceDB. Yes. Sorry about that. Yeah. Alright. I mean, I love talking to myself, but a conversation sometimes works a little bit better. So oh, we can just get a run through this. The the language, is this something that people have seen before? Did I mean, I'm assuming you just based loosely on JSON with some typing information. That was the idea was
25:10 to make it seem somewhat familiar to people. But I'm curious if there's anything that I I mean, I it's just based on something else that I have no knowledge of. I'm curious. Yeah. I I can kinda tell you the history of this. It's actually really funny. So inside the Zanzibar paper, they kind of have their own kind of syntax where they're kind of modeling the different, object types is that's the the SpiceDB terminology for this. And we built, like, a custom parser for it at first, and we're it was really slow and we're like, this is such a weird
25:43 format. Why did they do this? It took us, I forget how many months before we realized it was just the protobuf text format and we're face palmed because Joey, one of my cofounders, literally worked on Stubby and protobuf at Google for many years, so he's super deeply familiar with this whole tool chain. But, yeah, we basically realized, like, at Google they have lots of tooling around ProtoBuff and just everything is ProtoBuff, but, like, that's not really super ergonomic outside of Google. So we kind of squinted at how they were doing things and kind of envisioned something that
26:22 was at least more user friendly. And we've actually seen a lot of other projects that are kind of loosely in the same space as SpiceDB then adopt a very, very similar syntax, which means I feel like we kind of like knocked it out of the park in terms of making something like understandable and reasonable. But no, this is kind of a custom domain specific language, kind of loosely inspired, like, kinda just like c style, like languages. But the idea is you're kind of defining the different types of objects that live in your system and then you define relations between those objects.
27:01 So in this case, can see we we're defining like a user, but then you you need the users to exist so that when you start talking about posts, you can say, okay. There are readers of a post which are users and there are writers of a post which are users. But you could define any type of object that you need to represent in your kind of applications or your domain and then use those, to create relations. And then we have this distinction between a relation and a permission. You can think of a permission as like the end API
27:31 that you want applications to call into when they want to check a permission. So, here in this kind of blog example, we say permission read and you can see we actually have this additional syntax. You're not just saying permission read equals reader, but we're actually talking about, using the set semantics here to define all the possible ways you could have read access. And basically what we're we're doing by saying reader plus writer here is saying that if you're a writer, you also inherit the read, permission. So there is no scenario where someone should be given,
28:13 write access where they don't also get read access. And by doing it this way, it's it's actually super powerful. You could actually make this even more powerful if you say, permission read equals reader plus write and you actually reference the other permission, the write permission because the the main advantage to doing that is actually then if you change, the definition for who gets write access, that all propagates down to the read permission definition. So if you change, how people can get write access to this document, say you have like an admin or something like that,
28:52 and you just updated the write permission to say like, write is writers plus admins, that would flow then all the way down to the read permission if you defined that in terms of the write permission. So you kind of get like this really natural inheritance and like, dry, like don't repeat yourself syntax when you kind of modeled things this way. But yeah, the original Zanzibar syntax was pretty confusing and we kind of like distilled it down to just kind of like very simple, definitions of permissions and relations. So I think that's like a a pretty
29:27 good high level description here. But, yeah, it's totally inspired just to, like, look familiar, but there really wasn't much we could lean on in the space beyond, kind of the core data that basically Google was using for in their protobufs. Alright. Awesome. Okay. So I wanna make sure that I mean, that that history was great. That actually reveals a lot more. I love those kind of simple questions where you get a lot more of it. Like, that was fantastic. But, you know, as far as, you know, people watching this, we've got definition, which you said defines an object type. Right? So these
30:03 are the things that exist to entities perhaps in your application or your whatever it is you're building. We then have the permissions. These are the I'm assuming the lowest level of thing. You have some ability to do something on some object. Again, here is read and write. And then we have the relations. I'm assuming, you know, we've got relation reader, relation writer, we could have relation owner or like you could build this out to map to the domain of whatever is that you're trying to model. Are all those is there any other, you know, terms, lexicon that we're going to approach
30:35 as we start to model with SpaceDB that people may need to be familiar with? There are more advanced ones, but I think for, like, this core kind of example of just, the blog posts, I think this is really all you need. Okay. So let me scroll down here and we have the ability to see how to work with the node APIs and even the ZCLI. Maybe you could give the audience a bit of understanding and what is the ZCLI and and how should they and when should they use it? Yeah. So it's kind of unfortunate because we
31:07 had this command line tool that we named Zed and then, like, the Zed editor came out, like, a year later or something, which is just, like, way more I guess, like, it's not that it's more popular, it's just it's more applicable to more developers. Every developer has every text editor installed on their machine, but it's unfortunate naming conflict, but Zed is our command line interface to interact with SpiceDB clusters. So the cool thing here is Zed is kind of like a wrapper around our API, in a CLI tool. There's a bit more functionality than that, but
31:41 it's really nice if you just wanna like poke at a SpiceDB instance or a cluster, pull down some data, read it, manipulate it. You don't actually have to like sit down and write code, instead you can just kind of use and and, even write bash scripts if you needed to using the ZCLI to to poke at it. So all these examples were kind of showing you how you would implement it inside of a programming language, which was typically how you would integrate with your kind of applications in your product suite. You would actually maybe not for a schema,
32:13 some people manage the life cycle of their schema in like a CICD, flow, but, most other things like actually calling check permissions and and things like that, folks are going to be writing that from from inside their applications. So, the difference with Zed is, it's kind of more of a sysadmin or like ops tool for you to poke at the cluster and kind of ask it questions, debug it. We even have like really compelling features like an explain flag that helps you debug why a request was particularly slow. So all the instructions in this guide also
32:51 show you how to use it using zed if you don't wanna sit down and write code in a programming language. Perfect. Alright. Now this says here, you know, we're talking about migrations and we have a schema. Obviously, these evolve over time. So assuming I am vape coding my way through some sort of schema here and I change user and I say, you know what? That's a very vague term to define what, you know, some actor within my system is. And, actually, what I wanna call them, I use my own experience, like the Rawkode Academy has
33:23 learners. So I'm like, okay. Let's just search and replace user to learner. I had go. What are the gotchas that people should be aware of, and how do we handle schema evolution when working with SpaceDB? Yeah. So first off, SpiceDB itself is basically gonna be doing tons of validation around the data that's already written to a SpiceDB and the schema. So if you make a change, like rename user to learner, but you already have data written inside SpiceDB that created users, for example, or associated users with posts, and you go to try to apply that
34:01 schema, SpiceDB is actually gonna warn you. It's gonna throw up an error and say like, hey, you're trying to do this thing, but that would potentially leave data you've written to SpiceDB dangling. The idea being like it wouldn't be associated with any objects in your schema, so like that data would still be written but not be used, which could be surprising if you ever in the future wrote another schema that created a user type and you forgot that you had written data about users. Now all of a sudden those that that data would come alive and start changing permissions in
34:34 a way you probably didn't expect. So we do lots of validation to make sure you're not necessarily doing anything surprising or doing something that might bite you in the future. That being said, there are a lot of tricks. I wouldn't say tricks. There's a lot of things that, you can do in SpiceDB that you really wouldn't be able to do in a lot of other systems, like redefining a permission to be backwards compatible. And doing that kind of lets you iterate on these schemas over time and, not necessarily break existing applications as you add new logic,
35:13 and then slowly gives you the opportunity to kind of like deprecate the old one. Oftentimes, when you want to actually make a change, it's it's often just a one line change in the schema and you actually don't have to touch code anywhere because you've centralized that data and, and all that logic of how folks get access to something into SpiceDB, your end applications, they're just kind of making these API calls. And, the more the more granular actually your applications are to making these API calls so they can do things like, can this API key access this post?
35:47 By doing that, you you have all the freedom in SpiceDB to completely redefine how API keys get associated with users. Maybe they go through a service account transitory through that. Maybe you didn't have that service account at the beginning, but now you do. But because your end application only asked about the API keys access, you can add that layer of indirection and not have to touch any code in your application because you were just focused on the exact primitives you had at hand. You had the API key and you had like the post they were trying to access.
36:22 And then the other important thing to add here, great example with users, Spice TV doesn't necessarily prescribe how users should look. Inside of Google and in the Zanzibar paper, Google works out this assumption that they all have the same of core identity provider, and at Google, that service is called Gaia. And at Gaia, every user boils down to a super big unsigned in 64 bit integer. Spice DB doesn't make that same assumption because that's not how the real world works, and we actually let you model very complex users, using the same primitives you would model, anything
37:02 else in SpiceDB. So you could have like a really robust system where users have a different login providers and different credentials and different services accounts and API tokens, and you can model all of these things kind of custom to your end use case. And then as long as your application is asking like that last that last primitive, that very bottom primitive, you can refactor all that stuff, change it all, adopt a new, identity platform, swap identity platforms and, your application code just doesn't need to change. So that was a lot of information, but, yeah. Basically,
37:38 we're we're giving you as many guarantees as we possibly can as you iterate on these systems because that's that's a lot of the value is making sure that you're confident, in these changes. And a lot of folks end up basically using CICD around making changes to their their schemas. And you can actually write test cases and assertions and negative assertions, and even kind of exhaustively generate all the paths through the graph that space does driving SpiceDB to kind of discover any anomalies in a system you've modeled. And because it's centralized, you know that, like, everything is represented in that
38:12 one place rather than you kinda play, like, whack a mole and see, like, what is the subtle interaction between, like, microservices a's permissions and microservices b. It doesn't matter because they're all in the one central, kinda schema for SpiceDB when you when you do it this way. So lots of information. Sorry about that. Information is good. I mean, that's what people are tuning in to learn and to understand, you know. These things especially when you're, you know, if you're at a stage in your application where you're looking at SpaceDB and Zanzibar and all these other things. Right? It's like
38:44 I mean, I hope a lot of people are doing domain driven design. They understand their domains. They understand their body context. They understand everything with not everything, but, you know, there's a good a good baseline understanding of what is their modeling. Because I do think that is really important and it's gonna help them prevent, hopefully, a lot of naive assumptions and errors down the line. So, you know, people are hopefully in the right trajectory. I mean, I don't see WordPress adopting SpaceDB anytime soon, but, you know, more mature applications and enterprise applications, this stuff is super important.
39:14 So we're now in a position where, you know, we've got definitions of object types. We're building relations. We're doing permissions, but we actually have all we have so far is schema. Right? There's no actual data. And this is where we get into the the ZCLI or, again, you can use any of code examples, but you have to define the relationships. This is the ability to grant permissions to these types within your systems with other objects. And and here's a, you know, nice simple example. We just create a relationship between some post with ID one, writer to user Emilia. I
39:48 mean, I'm not assuming people here are gonna be set and using the ZCLI to do this. I hope you're doing this in code. But what is or what have you seen with people that are doing this and adopting this? You know, assuming they're not in a a greenfield project, they've got some sort of existing system and they have to do some sort of bulk migration of permissions and entities to SpaceDB. Is that something where the ZCLI is gonna help them? Is it something where you just expect them to write a script? Is there preexisting tools? Like, how do people with
40:18 existing data and infrastructure and applications migrate to a SpaceDB world? Yeah. That's a super good question. I mean, it's the user journey for most of kind of the adopters for SpaceDB. I think mostly we recommend, and this is kind of true almost for all technologies, you probably shouldn't just overhaul an entire system and just lift and shift, pick up everything, put it in the new thing, the old thing. What you really want to do is kind of make yourself familiar with the newer system and kind of be able to onboard that technology as like your team gets familiar with the
40:56 technology and kind of like levels up their skills for operationalizing it and just understanding how to use it. So what we normally recommend is actually focusing on one particular use case if you're not a greenfield application that knows you need this. And that use case is probably something you would struggle with to implement yourself. So maybe a customer recommend or requires that you build recursive teams. So in your system, you need teams that can embed other teams and you don't know how deeply nested that needs to go, but you also don't know how you'd implement
41:30 that yourself. Maybe your your SaaS app that's written on top of MySQL and MySQL, unlike Postgres, doesn't have recursive joins. So if you were storing something inside your database, the kind of natural inclination there would be like, okay. I would use a recursive join to just keep arbitrarily digging out and, kind of chasing foreign keys to the same table. But like if you have a database system that doesn't support that, how would you even implement that? You would pull that out in a logic maybe. A lot of people get stuck, on certain features like this.
42:04 And then that, I think those features are the ones that are like a really good opportunity to introduce a new technology like SpiceDB. So you would say, okay. I'm just gonna start with this one feature. What's the minimal set of data that I need to get to drive this feature? And the interesting thing about SpiceDB is at its core, it kind of works as a graph database. And how kind of graph databases work is there isn't like a create a user in a graph database. That's not really how it works. In graph databases, you just build these kind
42:38 of relations between things. So for example, the commands we have here for Zed says, we're associating a user Amelia as a writer for post one. There's no thing that we said where we created Amelia. There's no, like, create user Amelia. That doesn't exist. Just the mere existence of Amelia of a link basically existing in the system between a post and Amelia is what makes Amelia kind of alive in the system. If Amelia wasn't didn't have any relationships whatsoever, if you asked if Amelia has access, the answer would just be no because there's no data at all related to Amelia in the
43:17 system. So that aspect alone makes it so you actually don't have to load as much data as you think in a splice DB. There's no thing where you need to be like, all right, let's sync all the users into here unless you needed some kind of attribute between the users, and something else represented. So that cuts down a lot. The Zed tool does have so there are bulk import and export APIs in SpiceDB. Zed does actually expose all that and gives you kind of flags for, like, batching and things like that. If you, wanted to kind
43:51 of export something into SpiceDB really efficiently, it's basically a batch script away. But then some folks also just kind of lazy load this stuff. So you'd integrate it into your application and then when that data is first necessary, your application actually like write some data into SpiceDB and it would kind of be like a piecemeal migration. There's a lot of different ways you can actually do all this stuff, but I think it depends on kind of how you're adopting the technology and what feature you're trying to drive. So I hope that answered the question. Yeah.
44:27 I believe it did. Definitely. Alright. I like that. It's kind of decoupled. Right? But I think it also pronounced perfect. The data is decoupled from the actual system. You know, we have written and said, Emilia can write to post one. What is the process then if I've been very silly in my architecture and users handle is their idea using permissions and not some sort of UUID or good, and then they have the ability in the system to rename themselves. Is there the ability is then for me to speak to SpiceDB and say, please treat user Emilia now as user
45:07 x. So there there is not. I could actually see a way to move forward with that would be, like, adding yet another layer of indirection above user and then create like a I don't know, like an actual core user and then you treat user as an alias. So you could work your way out of that situation. There isn't like a mass rename built into SpiceDB or anything like that. That being said, we do recommend you use kind of not always GUIDs but like usually unique identifiers here. We definitely tell all of our customers you shouldn't be storing any like PII or anything
45:49 like super super coupled to any of this stuff. It does it does make actually like as a human interacting with things like on the command line a little bit more annoying when it's just, like, all GUIDs, basically. You just see the type and then, like, a really big number or something like that. But that being said, like, it is the right way you should be modeling these things is using kind of these core, I guess things you think of as a primary key in a database, like identifiers for your different objects so that you do have the freedom to
46:22 kind of rename these things because at like the core, you really don't want kind of metadata stored in your authorization system. That's like for the end applications. So you really don't care about usernames when you're talking about permissions. If they're coupled to usernames, it's actually really scary because you have to consider, like, those renaming semantics you were just talking about where, like, what happens if someone, changes their name to someone who, like, maybe deleted their account, but, like, you didn't delete all the relationships associated with it? If you rename someone, do they inherit a whole bunch of data that, like, you
46:56 didn't intend? Right? So there's all kinds of really scary edge cases we're trying to, like, push you towards avoiding by saying, like, hey. You should probably probably just use IDs for everything over here. Little little worse on the DevX side, but, like, the trade off long term for kind of the correctness of your system and chances of you making a mistake that's security critical go way down. Yeah. I mean, if we identify the modalities of people that are working with SpiceDB, they're probably not gonna be set and using the ZCLI for their day in, day out.
47:29 Like, it may be used as some sort of query tool, but that lack of developer experience with the IDs, I think, is acceptable for a more scalable and longer term system. So I think yeah. You know, we should not be using document titles as our primary ID, etcetera. I think we're, again, we're we're past that, but you never know. Alright. I think we kinda covered, you know, this schema and working with the ZCLI and how relationships work. I think if we head over to the playground now, maybe we can pick one of these examples and
47:56 find something that's a bit more interesting to dive into more of the the schema semantics and how this works. Do you have a a personal favorite from the example schemas that you would like to kinda talk about? I mean, probably scrolling up. I mean, we kind of already talked about the simple role based access control one. Maybe the caveat one is an interesting one to really dive into because this is kind of like a functionality that maybe the beginner wouldn't know exists in Spice TV but is actually super, super critical for a lot of different use cases.
48:34 You'll notice in the definition that you just pulled up, there is kind of this definition document. We kind of already have seen something similar to that, but you'll notice after relation reader, we have this pipe there. And so that's kinda similar if you're familiar with TypeScript. We actually let you kind of union type. So, you could say, like, readers are users or, I don't know, API keys. You you can actually make it so multiple types can be assigned to the reader relation. But what we're actually doing here is we're saying it can be a user or it
49:09 can be a user with this particular caveat named only on Tuesday. And caveats are kind of a concept that the team created. It's not a thing that exists inside the Zansbar paper, we did collaborate with Netflix on its creation, for one of their use cases. But it basically lets you, kind of do more dynamic relationships inside of SpiceDB. This unlocks all kinds of kind of, basically ABAC style use cases, attribute based access control, the idea that you can have dynamic attributes coming in as well as basically to augment the data that's already living inside of SpiceDB.
49:54 And then you can kind of execute some logic on that context that you're providing to say yes or no whether or not, a particular relationship, living inside of SpiceDB is valid. So, that that's a really abstract, way to describe it, but let me make it a little bit more concrete. Here we have a caveat named only on Tuesday and it's really, really simple. You pass in a string, which is the day of the week, and if the string you passed in equals Tuesday, then the caveat evaluates to yes. So when you write a relationship to SpiceDB
50:28 about, basically users, you would include, for users with a reader on this document. So when you're actually saying, okay, this user is a particular reader on this document, you can also provide context for this caveat or associate this caveat with the relationship. And what that's gonna say is, okay, this user is going to have reader for this document, but only if this caveat is true. So that is going to require requesters to provide the day of the week when they do a permissions check that requires this data. So that makes it really, really powerful, because you can kind of add all kinds
51:12 of dynamic aspects. You might say like this person is allowed to do this thing, but only if the IP address they're using to connect is from a particular subnet. So it's like from our private network, which means they're on the VPN. Right? You can encode all of this logic now inside of SpiceDB and enforce that to make, the relationship stored in it true or false depending on, like, completely variable context. That maybe it doesn't make sense to save that data inside of SpiceDB because it's changing too fast. Like saving the IP address of a particular
51:43 user probably isn't a great thing to store inside of SpiceDB because it's constantly changing. So you probably just wanna provide that as context if it is critical to your decision making for authorization. The other thing to note here is, the caveat language, the thing we're using to, kind of write day of week equals equals Tuesday. This is using cell. If you're familiar with Kubernetes, this is the the policy language built into Kubernetes. I think it's probably the best way forward when it comes to kind of policy purely because it is not Turing complete and we can
52:21 kind of guarantee based on, what's written by parsing the syntax tree actually how fast it's going to execute and then it has bounded execution. So unlike a lot of other kind of policy languages where you can just keep stacking policies or you like really don't know how long something is going to execute, we can actually put limits in SpiceDB that say these policies have to execute within this amount of like milliseconds. So we can still guarantee that you're gonna hit SLAs that you have, in terms of latency for getting these responses back. It was just a really, really powerful primitive,
52:57 for defining these policies in a way that they're not gonna inhibit you because kind of the stance that, we at AuthZED have is if you can represent it as data, it's way better and by data, I mean relationships living inside of SpiceDB. It's preferable to store things as much as possible as data because that data can be indexed and you can query it in a bunch of different ways. That is a more powerful experience than having to execute code to say yes or no for something because if you wanted to say, give me the list of all the users
53:30 that have access to this particular thing, that means you would have to go through every single user and execute a policy on each and every single one to filter that list if it was purely just being done with a policy language versus if it's represented as data, you can actually just query that data and it's probably indexed in something like SpiceDB where you can then just traverse that, kind of how that data is laid out on disk to determine what those users are and just return them very quickly. So, we think it's a more predictable and more
54:03 reliable way to have everything be data driven and then you just sprinkle on a little bit of policy where you need it and make sure it's bounded. So that's kind of like the idea behind caveats. And yeah, if you kind of like jump through, you can see test relationships on the different tabs at the top. We kind of have put in some relationships and you can see on the right hand side there's the space for the actual caveat name and you can write assertions about this or expected relations. But yeah, This UI also, I just wanna to mention,
54:37 this whole UI is running both SpiceDB and Zed just compiled to WebAssembly. And then we kind of have a custom UI built in Monaco, very similar to our Versus Code plugin. So this is kind of just like very similar to a Versus Code plugin, just like running purely in your browser, but we just took everything and compiled it to WebAssembly to get that to work. So it's real splice d b running in in your browser. It's real zed running in your browser to to to do all this and drive this experience. Wow. Very, very cool. Yeah. I
55:07 love following the WebAssembly thing right now. Just seems to getting more and more powerful. I've even seen something a couple of weeks ago where someone compiled Postgres to run inside of the browser, and you're like, why? But also very cool. So Yeah. What what's really neat about this is because it's all real when you kind of, like, hit the download button or export it, that's all kind of portable. So you can, like, work on something and iterate on the playground, share it with, like, your coworkers, and then when you're all good, you just, like, export it and then load it right into
55:35 SpiceDB and you're good to go. Okay. So let me try and pivot this caveat example to one of the use cases that I've got for the Rawkode Academy. So I'm about to deploy the ability to react to videos as you watch them on the website. However, I don't want fake reactions and fake comments on the video. I actually want to make sure that people have watched a certain percentage of a video in order to thumb it up, thumb it down, love heart, or even comment and tell me, you know, how annoying my audio is this week, which is
56:06 a very common complaint. So would I use a caveat then to say, you know, has watched, you know, 50% or something like that? I guess that would be like a PT and then it takes a percentage and that would be an integer or an I'm not sure what the I'm not sure. N number? N think it should have been. I think I think you're good. Order is is the opposite. I'm pretty sure. I'm I think it's, like, the n percentage. And because this is just salary, I can say, alright, if it's greater than a 50.
56:41 So Yeah. If if I have this caveat, I wanna make sure I understand this bit because this bit is actually new to me. I don't fully understand this. Right? So we've got a let's call it a video. We've got people that are allowed to watch a video. I guess it's a watcher. And and then messing up all your tests as well. Right? But you have the ability to watch a video if you're a watcher. And what we're saying is that all users can watch or users bug a caveat. So the caveat is a piece of
57:13 data on the user, an attribute, if you will. Right? So is that Yeah. The the way to think about this is, like, this is you're expressing types right now. So you're saying that you can assign either users with no caveat. That's what the first thing to the left of the bar is. That's just saying, you could just assign a regular user to this and they don't require the caveat. And if you if you write that relationship, that means that user doesn't care whether they're at 50% or not. They won't require that context when you ask, like, are they a watcher or
57:47 not. So that's one option. You could delete that left everything left of the bar, like including the bar, and then that would just say, okay, every single watcher, every single user you're going to write here has to have this caveat associated with it. Right? Which means whenever you write any of them, like, then, you have to at runtime provide the percentage whether the percentage is gonna be greater than 50 or not. So, if you write a relationship that is a user, with this caveat and then when you pass in at runtime, say they're they hit zero or, well, first of all,
58:31 let's say if you don't provide anything whatsoever, zero context, it's gonna actually throw an error and say, like, you need to provide me a context if you want this to work. And then you'll it will even tell you specifically what you need to provide. It'll tell you you're missing the percentage here. And then you would update your request and say, like, okay. Here's my percentage. Basically, you're not even gonna be able to run the permissions check until you actually provide the context, which is the the percentage. Otherwise, like, you just don't have enough information to actually solve this this request
59:06 because what it's gonna do is it's gonna basically find gather up all the users and then what it has to do to evaluate the users to say whether or not those relationships are even worth considering is plug in your context value, like your percentage, and then it's gonna execute the caveat for all of them and then it's going to filter them based off of that result. So, the other interesting thing just to note with caveats is, say you had multiple parameters going into this caveat, you can actually partially evaluate them, so partially apply, at different points in time. So you could
59:44 actually say, when you go to write a user, you could actually pre apply a percentage and say, like, this is the permanent percentage that's written to this user. I know they hit 50, so they're good forever. And for future requests to them, I don't need to provide the context, so I'm just gonna write when I say this user is a watcher, I'm also gonna write and say, like, and the context includes that they already hit 50% on the on the video. So, you actually have this this kind of duality of like when you care to provide the
1:00:17 context, some of it can be at the time at which you write the relationship and some of it can be at the time you actually make the query to say, like, I'm checking this permission. It's really powerful when you start kind of pre reapplying some, parameters to the caveats, but that's probably more advanced of the use case. Alright. So what I'm taking away from this is that this is a horrible way for me to build my 50% thing. I should not do it this way because it would require for every single user that I create
1:00:46 to have a caveat, which I then provide a value at runtime, which doesn't make a lot of sense. So realistically, if I were modeling this, I would probably just want to make sure a user has watched a certain amount of content and then consider them trusted and give them a new role, and then they have the ability to comment and thumbs up or something like that. Yeah. That's a good way to do it. But if you really wanna do, this is actually totally fine. There are trade offs associated with it. It totally works. But, yeah, I would definitely lean towards
1:01:13 some other kind of flag you can set on the account to say, like, alright. Yeah. This this one's legit. Yeah. So I don't mean to drag you onto a livestream just to get my support calls answered. But, you know, let's tackle one more use case. Right? Let's imagine I publish a course and everyone gets general availability access on a certain date. However, I want to give trusted community members access two weeks before. Is that something you would model as data using SpiceDB? Yeah, absolutely. There's another feature and it gets used similar to where you're using the caveat. If used as
1:01:46 part of the types that you define on a relation, you can actually use this feature we call the wildcard, which is effectively the idea of public or not. It says, when the wildcard is written to this value, so the wildcard is actually, it's both a type and it's a relationship that you can write. So, the idea is, you can say relation watcher user or wildcard user. And the reason why you do that is you're saying like, do I want this relation to be allowed to use the wildcard? So fundamentally we let you kind of use the
1:02:26 type system to gate what things are allowed to actually be wild carded or not, but then when you you can actually write a relationship that says basically user star is allowed to access this thing. And so that means any user, any user you provide whatsoever is going to just get true for that particular relation. They're they're totally good. Sorry if there's a little background noise. But basically what you could do then is say, all right, my trusted users, I'm going to add them by name or by ID, right? You're going to add them individually to give them
1:02:58 real access and then when your date that you're launching publicly hits, then you would write the wildcard relation and say like, all right, gates are open now, everyone can access this. It doesn't matter whether you're in the kind of private list before And that would be like a really good way to to model kind of like that early access. Okay. So, you know, people are working on CMS systems, etcetera, and they want an article to go live at a certain date, they would set up some sort of automation that runs on a cron every hour. Okay.
1:03:28 With the go live date is now a hit, you're writing to SpiceDB and saying this is now available to everyone. That is the the secret sauce there rather than develop caveats and pass in the date for every request. So that seems like it could be. Absolutely. Yeah. Because the caveats, the other thing just consider with them is like, they kind of live forever. Like, once you write a relationship that is caveated, that caveat will live with that relationship forever. So if you do something like a date and it's gonna have an expiration, for example, there's like no
1:04:01 process going through and like that understands the custom cell code that you've written that says like, oh, this will never this caveat, it will never evaluate to true ever in the future. So that's like kind of on the user to say like, all right, this this doesn't make sense anymore. I would have to go in and delete all these or like replace them all with non caveated versions, because there is this trade off where like you're gonna have to evaluate the caveat going forward. And like basically to solve that for the most common use case
1:04:29 and more, maybe not the most recent, but maybe two versions ago of SpliceDB, we actually released first class support for expiring relationships, which was one of the, most common usages of caveats. Users basically one wanted that to be way more performant because it is so common and for us to kind of like SpaceDB to do the internal garbage collection to say like, okay, like this relationship, it expires on this date after that point in time, it's no longer relevant, which means you should just delete it. So SpiceDB should just go through and kind of delete all
1:05:01 the expired relationships. And we can do that because it understands expiring relationships and not like the custom caveat code that you've written. So now that super common use case is built in and really, really optimized and there are some users for some use cases that are just using all expiring relationships and just, like, constantly kind of retouching those relationships to keep them alive over time. But they have, like, this default case where, like, if nothing were to happen, like, this per all these permissions would just totally cease to exist anymore, which is really, really powerful and interesting use
1:05:36 case. Yeah. That's fantastic. I had no idea about that feature, but I'm definitely interested in playing with that. So I'm assuming when I'm using, say, the Node. Js SDK, the Go SDK, and I create that relationship, there's just metadata. I say expire in July, '90 days, whatever, and that just is all handled for me automatically. Yep. Absolutely. And it's actually, like, a really subtle thing because notoriously distributed systems and, like, clocks are not, like, friends is the best way to put that. In distributed systems, you really have to use kind of events and the ordering of events
1:06:11 to determine things and causality to kind of understand how the system works overall. You can't just, like, look at a clock because not everyone's clocks are synced and there's things like leap seconds that can totally just destroy, a lot of your intuition around kind of time and the ordering of things. Fundamentally, expiring relationships actually is associated with time though, so there's kind of like this this friction where these features are kind of at odds. So we do the best we can to kind of like push that down in the way that makes the most sense rather than
1:06:41 like folks kind of like providing time from like their app servers and like the app servers are totally out of sync with like SpiceDB. So we try to based on kind of like what your data storage backend is for SpiceDB, we try to do like the best possible thing there to make all this work. But I just wanted to add that caveat, because I think a lot of the distributed systems folks would be like, something about that doesn't seem right, if you're kind of like using wall clocks for for some of this stuff. But, yeah, everything else in SPICE TP is
1:07:11 all kind of under the hood using event based kind of vector clocks as typical distributed systems would. Alright. Awesome. I want us to kinda explore the the test relationships and assertions before we finish. I'll be very brief with this last question then. But you have mentioned, you know, clocks and, you know, distributed systems, just vector clocks and all these fancy things. But let's talk about caching. Now, if I'm building the system and say I am I have an expiry relationship, whether that's minutes, hours, whatever. Right? There's something here that has to expire and I'm sending
1:07:44 a request to SpaceDB, is it normal practice to say, okay, I'm going to trust this for a percentage of time as the expiration passed back with the the request. Is that something I can figure? Or would you just say that the performance of SpaceDB and, you know, the domain that is in, which is, you know, security and permissions, you should never catch. Like, what are your thoughts on scaling and operating this thing as I build out my system? Yeah. A good way to think of, like, what SpliceDB even fundamentally is, is it's a really sophisticated
1:08:17 distributed cache. So kind of, we call it a database, but it's a little bit different from a lot of other databases. It's probably like closest to like Redis in this sense in that, Spice TV itself to kind of hit your low latency kind of authorization requirements. Right? If we like take a huge step back, before you do any work on any of your API servers, like you first have to check a permission to see if the user is allowed to do the thing, which means before you do any work, have to do this. And then you also have to consider there's
1:08:51 gonna be a network opt to the service. So there's gonna be like at least one or two milliseconds where you like reach out to Display TV and ask it for something. And already, depending on a whole bunch of use cases, maybe you want, maybe your SLA is like ten milliseconds and we've already used two to talk to Spice TV. Right? So basically Spice TV's goal is to keep as much as possible in memory, ready to be served directly back to the user, to the application basically as quickly as it possibly can. That being said, we keep as much as
1:09:24 possible in memory to do that and then what the structure of kind of SpaceDB looks like is we break down requests recursively into kind of structural kind of traversals through a graph and cache partial evaluations of the graph and how you kind of travel through that graph. And so, like, if you have two permissions checks and structurally they share some of the same data they have to, like, go through, so say you had, like, the reader permission and then the writer permission from the blog post earlier, but the writer permission was also, sorry. The the reader permission was also defined
1:10:04 by talking about the writer permission. Right? It's also checking writers. If you did a permissions check on writers and then you did a permissions check on readers, half of the permissions check for the reader would already be cached because you already looked at all the readers for that particular or sorry. You already looked at all the writers for that particular thing. So that means half of the work of figuring out whether someone has permission was already kind of preloaded and pre cached in SpaceDB by the time you did that. So, we're doing a lot to keep as much
1:10:34 kind of in memory lazily, kind of as you request things to kind of maximize memory usage, but then also like make sure that cache hit rates incredibly high. The really nice thing about all this stuff is it's kind of temporal. So, after like maybe two hours, like, that old permissions data, probably never gonna get queried again, so we can actually just evict that stuff from memory. So we're we're not necessarily, like, hanging on to stuff indefinitely in memory. So we can actually be pretty lean as to, like, what our memory footprint is while trying to keep as much in memory as
1:11:09 possible. So if your question is like, should I be caching these things? I would say the most sophisticated cache you would already have is literally SpiceDB. So if if you're kind of having issues where you want something to be cached, what you can do is just deploy a SpiceDB more close to that particular endpoint. So say like you are running SpiceDB in one particular region, in a cloud provider, but then you have this one use case where like maybe you have, like, a hundred thousand queries per second. You might actually wanna just dedicate another SpiceDB cluster just
1:11:45 sitting right in front of that. The same shared data, it's all using the same, canonical data and relationship storage, but this one is just running directly for that one use case. So all of the caching built into SpiceDB itself is just gonna be focused on that one particular use case and optimizing that one. So there's definitely different architectural ways you can deploy SpiceDB to hit your cache hit goals. But I don't think that writing a naive cache in front of the service is probably going to include all of the semantics you need to encapsulate consistency and the
1:12:24 correctness of the permissions because if you think about it a stale permission, basically making an authorization decision based off of a stale permission is a security vulnerability. So, like, this is some kind of scary critical data. Like, you you really don't wanna try to, like, just use naive, kind of caching, mechanisms and especially when people can revoke permissions kind of dynamically throughout the whole system. Alright. I feel like I just got into trouble, but that was totally worth it. So thank you for for covering all that. That's a super fair question. A lot of people
1:13:00 ask us about that. But, like, once you understand what Spice TV is doing, you're like, oh, okay. Yeah. I wasn't gonna do better than that. Yeah. I mean, we could go into the whole cluster and topology and the best way to architect this, but we are very short in time and I don't want us to to kinda run over. So maybe that's a a session for another day or maybe people should just check out offset.com and and use the managed model. Because I mean, that's just a lot easier. But we'll talk about that when we finish.
1:13:24 So we I've broken the relationships by changing the entire schema of a model now. So, you know, in order to show how these work and how people can do some validations, I'd like to update our tests and our sessions to reflect what we're now doing with users, videos, watchers, the watch permission even if we don't use the caveat. So we've got some video here. We've got a watcher. I can just type in this like a spreadsheet, which is lovely. I'm updating the relations. So what we're seeing here is that we have some sort of type user that
1:13:56 has a watcher relation to a document. Now we don't have documents. We made this a video. So I'm assuming I'm fixing this. Please let me know if I Yeah. You are. You are. Some things are turning green. It's throwing different errors. The nice thing is there's kind of autocomplete all built into this stuff too. You saw, like, video autocompleted. Another thing just to note in the top left corner, like right below where it says schema, there's kind of this toggle right now it's on like the grid kind of Excel mode, but you can also hit like the
1:14:25 angle brackets, which is going to put it in text format. And so say you wanted to make like a ton of changes all at once, you can actually use kind of the find and replace shortcuts in Code right here, like kind of mass, like bulk change some things. So you could do, like, find and replace on, the only only on Tuesday and replace it with, your your, caveat for watchers being over 50%. Alright. That was very helpful because I was able to then switch from the watch permission from the relation. So if we pop back
1:15:00 here, we should be green, which means that Fred and Tom can both watch videos on SpaceDB and Kafka. If you look at the bottom too, there's there's this kinda check watches at the very bottom that's kind of going off. And so if you kinda you can drag that bar a little bit further up and you can see more, I believe. Maybe not. This is saying watch is the name of the permission and not the relation. Oh, so I actually That means watchers. Yeah. Yep. Alright. Let's just update my schema. Watcher. No. That made it worse.
1:15:46 Ah, okay. Because of the like because I changed the schema. Oh, yeah. Okay. Yeah. You could just change that to just user if you want and to just drop the caveat altogether. We don't need to use that caveat. Right? So now we've got this wonderful feedback loop. Right? I'm evolving my schema. I've got data, which we can look at in multiple fashions to understand what is going on here. We then have these assertions, so we can actually run these. They should fail now. Right? So it's not even validating because we don't have documents anymore. So
1:16:15 let's say document and video. And if we don't have the first doc, we have the space d b and Kafka. And then we'll get into the the differences here in just a moment. Let me see if I can get the validation to pass first. And then we don't need any caveats. We're not playing with those at the moment. So is oh, view. Watcher. Yeah. Then I think you got some quotes at the beginning of line two and seven. You've got, like, a single quote at the very beginning there. I recently switched my keyboard to one that has
1:17:01 these new magnetic switches, and it's very eager to type now. So yeah. Alright. What did I get wrong now? So filter validate. We've got some sort of problem and it's saying a relation or permission to exist. Yeah. So this is actually telling you that the the assertions themselves are failing. So what you've written is is totally valid, but it's telling you that, hey, I actually am looking to see if user Tom is a watcher and they are not. And the reason that is is because I don't know. Because Tom is a watcher on Kafka and not SPOTCP. Yeah.
1:17:47 Alright. So we switched this. This is cool because now we're we're seeing how this works. Alright? So let's return it again, and this bit's okay. But now we've got a cert caveated. So we don't have caveats, but we can build specific test cases to check that the caveats do pass when they are applicable. So I will remove this. And then we have a final one, which is to assert false. Yeah. This is saying that Tom is is definitely not a watcher on SpliceDB. And if we recall correctly, we never wrote a relationship that gave Tom a watcher on
1:18:20 SpiceDB, only Fred. Alright. So why am I getting is this just an old failure? Or Yeah. You're just on the last validation run tab. So because the last one succeeded, it's just showing you old errors. That's specifically what that is for. Alright. Yeah. And then This this tab, this last tab, expected relations, I actually love this tab, but I think most people struggle to understand what it says. This one is literally saying the of the lines where the squiggles are right now, like one and and four. You you basically write these and then you say,
1:18:59 please tell me all of the users that have access to this permission. And then if you hit compute and diff, that button on the right, it's actually showing you a diff of, like, what's gonna change. Like, it ran through all the data you had in the graph, and it determined that for the video Kafka, there's only one watcher, and that's Tom. And then it even tells you why. It's because there is a direct relationship written where Tom has specifically given video Kafka watcher. So if you imagine you have something more complicated, this is gonna generate a giant kind
1:19:37 of full exhaustive list of how everyone got access to everything. And the nice thing of having this kind of, like, diffing syntax is you can kind of have what you assume to be true and then what the computer ultimately finds as reality, and then it's just gonna highlight very specifically the differences so that you can find any, like, oops. I definitely didn't think about that or, like, this user shouldn't have access to that. And you can imagine this is incredibly powerful when you have, like, a really complicated model or you're modeling your whole kind of product
1:20:08 portfolio because now you know that, like, your system is actually bulletproof. Like, you've walked through all the possible, like, ways folks could get access to things and exhaustively at least. I recommend folks don't, like, handwrite these, but just, like, review what ones are generated to make sure that, like, your model is actually representing the thing in your head and, like, react like, reality where rubber meets the road is is actually what you think it is, and, no one has access to a particular thing that they they shouldn't. Nice. What I like here is that I've
1:20:42 looking for a video called Tom, which now doesn't exist. So now we have no Tom video watchers. But I'm assuming if I just come in here and say SpaceDB and then compute is gonna tell me that Fred. Yeah. That's awesome. I like that. Yeah. It's super cool. I feel there there isn't really like a good explanation written somewhere that's like, this is exactly how you use this tab. But holy holy crap. That's like super, super powerful. Yeah. So I think we've covered a lot. Right? You can generate schemas, build relationships, make assertions, and then you have expected relations at the
1:21:16 other end. This becomes a complete test suite for the data that is your permission model across your entire application. And, you know, there's a bunch of schemas here and there's also the schemas and the examples repository. So I encourage people just to go and play with this. You know, I didn't have to run any commands my machine. I don't have to run any Docker containers. The playground was just sat there ready to let us explore and learn, which is invaluable. And now that I know it's all done with WebAssembly with a real space DB, it's just made it a little
1:21:44 bit cooler. So awesome. Yeah. The other thing I'd just add here is it's almost the exact same code that runs inside the Versus Code extension. So also if you wanna do those stuff locally, like maybe you don't you don't trust like this cloud hosted play.allsaid.com. The Playground itself is open source, you could just run your own hosted instance, or you could just do it all inside Versus Code in your own editor. So Sweet. Alright. I'm gonna pop us back over to big face mode, and we can finish this off. So I really appreciate you just you know, that's been, an hour and
1:22:20 a half of your time to sit here and and just cover what I'm sure is is really simple basic stuff for you, but I hope this is valuable to people that are looking to improve their permissions game, adopt SpiceDB, and just, you know, take their application to that kind of next level, more cloud native and better than naive assumptions. Because we've all done, you know, permission one, user one, user two, permission two columns and databases, and we know it's wrong. But there's never been, I feel, an easier way to do it than there is today with space to be. So I
1:22:49 really, again, appreciate your time and thank you so much for joining me. Do you wanna just take a couple of minutes to tell us, you know, is SpaceDB finished? Is Offset finished? What's coming next? What challenges? What problems are you solving next? And what should people look forward to? Yeah, mean, all software is never finished, right? Software has to kind of like live and breathe just like people. There's always going to be folks kind of working on maintaining it and adding new features that customers require. Like I said, just two versions ago, we launched a pretty major feature
1:23:24 like the expiring relationships that fundamentally changes how a lot of people use SpiceDB. So like that clearly means we're not done, SpiceDB isn't done. Is it production ready and used by some of the largest companies on the planet? Yes. So it's probably good enough for a lot of use cases that you would consider it for, but I would say there's always kind of work in progress around kind of developer experience and making sure these things operate how humans want them to operate. So a lot of other kind of authorization solutions are focused on solving kind of authorization
1:24:04 for like one app, but SpiceDB is kind of a solution that's kind of targeting your platform team running this across a product portfolio or across your whole business. So to that end, that means we're actually integrating with a lot of different teams. There's like often a platform team operating SpiceDB at their business and then there's app developers integrating their products with SpiceDB. And we kind of have to make all these folks have better experience user experience and and an experience that they can kind of collaborate with each other. So a lot of, the focus in the open source more recently
1:24:43 has been around taking schema snippets like, what we were just kind of working on and being able to package those up and share them. And that way, if you had a really big deployment and you wanted to kind of like break down your schema and have this team own this portion of the schema, and write tests for that and understand that. And then this other team owns this portion of the schema. And then when you apply that to SpiceDB finally, like it combines them all together, runs all the tests, make sure that there's, like, a comprehensive,
1:25:15 kind of, correct schema and migration path to that new schema. And and I think that, like, this kind of workflow around kind of folks collaborating both internally, but also externally. So say you build a SpiceDB integration with your open source project, it'd be cool if you could package that integration with a schema package as well so that anyone that wants to use that can just, like, import this part of the schema into their schema, and now they can run this other kind of integration tool and get it all for free inside of their, inside their SpiceDB deployment.
1:25:51 So we're kind of playing with, a lot of that, like the packaging space right now to see if we can enable, like, a really nice, integration story both internally across teams, but externally across software projects. And all that's open source and, folks can play with play with it today. Right now, it's built into Zed, but in the future, we're looking to build it directly into SpiceDB. So there's an issue on Zed where, kind of documents the whole thing that folks can use to get started with. And then there's just flags built into zed to start
1:26:21 playing with it today. Yeah. That would be a really awesome feature because most people's domains are not novel. Right? We're all solving the same problem to some degree. So why not reissue reuse and reshare some of this logic? I love that. That's a great idea. Alright. Any last words before we say goodbye? Don't build your own authorization. That's not that is like my number one thing. I end all my talks, like any kind of public engagements with that. And like SpiceDB, it's a really cool system. Obviously, think it's cool because I built it, but maybe it's not the right solution for
1:26:57 where you are as a business. But if there is one lesson I've learned throughout this whole thing, diving into the authorization space when my background kind of wasn't that before as pure distributed systems, it's just that folks should not be building it themselves. Folks today, they wouldn't dream of building a custom database for every single kind of SaaS app that they build. They know that they shouldn't be building their own database, but there's just as much research and authorization. All that research started around the same time as database research, but folks still think they can go out
1:27:32 and, like, build a custom authorization model that's gonna solve the problem for themselves, with no, like, experience or backing or research whatsoever. So I just think that's, like, a huge gap right now in the industry that, like, this mindset needs to change. Folks need to realize that they should be kind of using foundational tools to help them model this stuff. Whether that tool is placed to be or not, that remains to be said. That's your decision, but you should go out and look at SpiceDB and maybe look at other alternatives so that you don't kind of build yourself
1:28:04 into a corner with your own kind of custom logic code that no one else can help you with because you invented that. So Awesome. Alright. Again, I really appreciate your time. Thank you so much for joining me. I hope you have a wonderful morning, evening, lunch, whatever it is where you are, and I'll speak to you again soon. And to everyone watching, have a great day. Thank you.
Technologies featured
Meet the Cast
Stay ahead in cloud native
Tutorials, deep dives, and curated events. No fluff.
Comments