WEBVTT 00:00.000 --> 00:11.880 We are ready to start and now let me welcome Jaldano, who we talk about 00:11.880 --> 00:16.240 serdities and to an encryption, permissions and jazz. 00:16.240 --> 00:22.880 Let's welcome him with a round of applause. 00:22.880 --> 00:23.880 Thank you very much. 00:23.880 --> 00:31.880 So thank you for the interview, my name is Geo, I'm a software engineer, I've got 00:31.880 --> 00:33.880 a garden computing. 00:33.880 --> 00:39.880 As you mentioned today we will talk a bit about serdities and to an encryption and 00:39.880 --> 00:43.600 our jazz does permissions. 00:43.600 --> 00:49.560 Before we start, I would like again to take a moment to recognize or acknowledge one of 00:49.560 --> 00:52.880 maybe one of the main reasons we are all here today. 00:52.880 --> 00:56.880 How many of you have read this paper? 00:56.880 --> 00:59.880 Of course. 00:59.880 --> 01:07.880 Well, if you haven't, I highly suggest that you do, that this is a literally gold mine. 01:07.880 --> 01:16.880 To me, what I found especially interesting about it, aside from all the technicalities which 01:16.880 --> 01:22.880 are of course interesting was a simple but I think very powerful idea. 01:22.880 --> 01:30.880 What is your up, work offline, sick magically, when connected and you, in all of these, 01:30.880 --> 01:32.880 rating control of your data? 01:32.880 --> 01:39.880 And yes, I know it's 26, like we have 5G everywhere, but also, I don't know if you heard 01:39.880 --> 01:42.880 last year, guess where I live? 01:42.880 --> 01:46.880 So, yeah, if you don't know, we had a power outage in Southern Europe that lasted for a couple 01:46.880 --> 01:50.880 of days and everything went nuts. 01:50.880 --> 01:53.880 So let's talk about the real problem here. 01:53.880 --> 02:00.880 Imagine we have two people, let's call them Bob and Linda. 02:00.880 --> 02:05.880 They want to work on something together. 02:05.880 --> 02:09.880 Both of them are offline because reasons. 02:09.880 --> 02:13.880 Now Bob starts saying, the gut is blue. 02:13.880 --> 02:20.880 A few moments later, Linda comes in and says, the gut is yellow. 02:20.880 --> 02:25.880 So, now, what color is the gut? 02:25.880 --> 02:30.880 No, it's yellow. 02:30.880 --> 02:37.880 No, look aside, the thing is that with additional approaches, like Nico was mentioning, 02:37.880 --> 02:41.880 there's not really any rule to define the behavior. 02:41.880 --> 02:47.880 The most common one is, let's say, our last, right, right, right, our wind's approach. 02:47.880 --> 02:53.880 Basically, your state, well, this is also the most common for complex data types. 02:53.880 --> 02:59.880 Basically, your state, it's effectively whatever comes last to your server. 02:59.880 --> 03:06.880 So in that case, Linda State will have one other, other, other Bob. 03:06.880 --> 03:10.880 The thing is that in this case, the state was whatever the server came last. 03:10.880 --> 03:17.880 So if Linda and Bob took each other directly, each one will have had the state of the other. 03:17.880 --> 03:20.880 If that was just the basic rule. 03:20.880 --> 03:28.880 And yeah, and you have to let us, because you seem to don't know which, which, where is the truth at the end. 03:28.880 --> 03:33.880 Another solution could be starting to do a lot of computer solution. 03:33.880 --> 03:49.880 You know, you are where you get these models or pop-ups saying, oh, this is the red, it's those are your red, it's, and the user picks what should be the, the final state or correct state. 03:49.880 --> 03:55.880 They don't, on the side of this is that, I think, can never hear anyone saying, I love the solving merge conflicts. 03:55.880 --> 04:02.880 So I don't, I don't know if any of you do does, but never heard of one of anyone. 04:02.880 --> 04:06.880 And then, let's not approach could be in the traditional term resource logging. 04:06.880 --> 04:16.880 So one person, like, only a single person can edit or touch our source or modify it at any given time. 04:16.880 --> 04:18.880 But that could, it's collaboration. 04:18.880 --> 04:24.880 So that was one of the main things I liked about the paper, which was allowing people to work on data also while offline, 04:24.880 --> 04:26.880 red and in control over the data. 04:26.880 --> 04:35.880 And plus, like, I don't really understand how people can really collaborate or, like, communicate and get a lot of, 04:35.880 --> 04:39.880 if they're both offline, I cannot communicate. 04:39.880 --> 04:46.880 So yeah, in this case, the cut is basically that collaboration is over, we don't have anything. 04:46.880 --> 04:50.880 So, and this is where serity is coming. 04:50.880 --> 04:56.880 Now, how many of you knows what a serity is? 04:56.880 --> 05:04.880 Okay, let's say, half of us, that's good. 05:04.880 --> 05:11.880 Okay, a serity, so serity stands for conflict-free, replicated data type. 05:11.880 --> 05:18.880 And there are data structures that are mathematically designed to merge without conflicts. 05:18.880 --> 05:20.880 And the key inside here is mathematical. 05:20.880 --> 05:25.880 In a sense, that it's not on a best step, best effort, Bayesian, or it's not a restricts. 05:25.880 --> 05:31.880 They are mathematically ensured to be, to merge conflict-free. 05:31.880 --> 05:37.880 Let's look at, over-singplified, practical example. 05:37.880 --> 05:43.880 This is kind of web-coded, a web-coded serity. 05:43.880 --> 05:45.880 And it's a counter. 05:46.880 --> 05:50.880 As you can see, when we construct these data structure, 05:50.880 --> 05:55.880 we initialize with our node ID, so it's ourselves with our own counter zero. 05:55.880 --> 06:02.880 And then we can increment by adding whatever number we want to our own state. 06:02.880 --> 06:06.880 Then we can merge with other people's state. 06:06.880 --> 06:13.880 So in that sense, then we keep track of others, other changes over other peers that we sync with. 06:13.880 --> 06:19.880 And at the end, the final value, it's always going to be the sum of all peers' counters. 06:19.880 --> 06:25.880 And these ensures that eventually, when everyone sync their data with each other, 06:25.880 --> 06:32.880 the final state will converge to the same one for everyone. 06:32.880 --> 06:38.880 Quoting the log of first paper, we are not trying to resolve conflicts with these approaches. 06:38.880 --> 06:45.880 We are designing them away, and the main point here is eventual consistency. 06:45.880 --> 06:53.880 So in our case, with a well-designed serity, let's say one that mixes colors. 06:53.880 --> 07:00.880 All changes are persisted, they're preserved, and they're merged sensibly, according to our own logic. 07:00.880 --> 07:06.880 Everyone is happy, cut this green, and everyone lost their work. 07:07.880 --> 07:15.880 I mean, this conception here is that when I talk to people about managing all sorts of things kind of conflicts or the work of everyone is preserved, 07:15.880 --> 07:23.880 they tend to think about it as a, like if everyone works is preserved in the history of the change. 07:23.880 --> 07:32.880 There are some implementation, some libraries that also retain the history of changes, so you can do time travel or get edits over time. 07:32.880 --> 07:46.880 But that's not an intrinsic property of serity, like what they do is literally only having a consistent final state, which is mathematically probable. 07:46.880 --> 08:00.880 And there is also, for me, at least, a useful mental model to think about them, which is, I think about serity as local state with superpowers. 08:00.880 --> 08:07.880 If you're familiar with React or, I guess, any other front and library really, you know, you state. 08:07.880 --> 08:15.880 So basically, you have these local state that you can update and react then for you updates the UI. 08:15.880 --> 08:24.880 When I think about serity, since serity is, I think about the same thing, so updating local state, which then triggers the renders. 08:24.880 --> 08:36.880 But at the same time, syncing them to their devices, so that the same state changes happen for every one of the same time or when the sync. 08:36.880 --> 08:46.880 So it's local first, in the most pure way, let's say, like it's, you write on to local state and you get instant feedback. 08:46.880 --> 09:02.880 In jets, we do this by swapping out, you state, we use co-state and co-stents for co-value or collaborative values, which is our own primitive for synced serity, let's say. 09:02.880 --> 09:11.880 And with this, we get magical synced state across multiple clients. 09:11.880 --> 09:24.880 And these, basically, changes the work texture, because in addition to client server architecture, we have our server, old-ingled the logic called the business logic called the validations. 09:24.880 --> 09:32.880 And clients are just teen view layers that just present data. 09:32.880 --> 09:45.880 These, as a few disadvantages, like, first of all, you need to go over the network to do any update, and that creates lower UI, and it's a bit frustrating. 09:45.880 --> 09:51.880 Like, we know how you guys can feel bad when the network is low. 09:51.880 --> 09:59.880 And second, they are not available offline, like your server is down, there is no way you can make those requests. 09:59.880 --> 10:04.880 Most importantly, because your server holds the logic, so it's not on your client. 10:04.880 --> 10:12.880 With local first, on the other hand, we shift all the logic and permissions to the clients. 10:12.880 --> 10:23.880 They hold authority to the state, they hold all the logic, and they do the violations, they do everything themselves. 10:23.880 --> 10:37.880 And the middle part, the middle part is just optionally a sync and storage layer, so that can persist data long term for cashing or for whatever reason. 10:37.880 --> 10:44.880 But it's not alternative, so the state's authorities are still all the clients. 10:44.880 --> 10:55.880 And yeah, with this inversion, the good thing is that servers or your infrastructure becomes a commodity. 10:55.880 --> 11:01.880 And in fact, if the sync server is that dumb, you don't really need to have one. 11:01.880 --> 11:12.880 You can just technically sync between clients, between each other, without needing to rely on a central authority. 11:12.880 --> 11:15.880 Or someone that sings data for you. 11:15.880 --> 11:20.880 And this, as Nico mentioned before, gives us an amazing benefit. 11:20.880 --> 11:22.880 First of all, users control their data. 11:22.880 --> 11:27.880 They are authorities over their data, and they own it. 11:27.880 --> 11:35.880 And most importantly, for me at least, as a frontend person, maybe, is that operations are easy. 11:36.880 --> 11:38.880 You're effectively updating local state. 11:38.880 --> 11:45.880 So every variety, every state changes is done because it's on local disk, it's on local, it's on memory. 11:45.880 --> 11:48.880 And then there is something else sinking to somewhere else. 11:48.880 --> 11:54.880 But the thing happens locally, and it's faster. 11:54.880 --> 12:01.880 And then, yeah. 12:02.880 --> 12:05.880 No, that's not true. No, they're all fine first by default. 12:05.880 --> 12:11.880 So that's not what they're going to get with local first, most of the times. 12:11.880 --> 12:20.880 There is an issue though, which is kind of the elephant in the room when talking about local first applications. 12:20.880 --> 12:24.880 Other stop users from doing nested things, like they own the data. 12:25.880 --> 12:34.880 Other, we prevent people from reading data that shouldn't read or writing or modifying data that shouldn't be able to. 12:34.880 --> 12:39.880 In traditional context, you know, the server is the gatekeeper. 12:39.880 --> 12:49.880 So they said they did it there, it does the validation, you on the server, you can perform checks. 12:49.880 --> 12:54.880 But the thing is that we just wanted to limit servers. We took them off the equation. 12:54.880 --> 13:02.880 So how do we, how do we enforce this? How do we make sure that no one does bad things? 13:02.880 --> 13:05.880 There are few approaches, which are maybe two naive. 13:05.880 --> 13:07.880 We can just check on the clients. 13:07.880 --> 13:12.880 So we can implement our apps to check local state and see. 13:12.880 --> 13:19.880 And so your code can check if you should show the users the actual state. 13:19.880 --> 13:24.880 But I mean, clients can be modified. 13:24.880 --> 13:28.880 So everyone can open your dev tools, change your code, and then access to data or modify it. 13:28.880 --> 13:31.880 But if I think that they, the shouldn't. 13:31.880 --> 13:34.880 Second approach is having the SERP server. 13:34.880 --> 13:41.880 So we're seeing infrastructure by the data changes before forwarding updates to the clients. 13:42.880 --> 13:50.880 The issue here is that we need smart server again at this point, because we need to copy the logic of the clients on the server, 13:50.880 --> 13:56.880 or on the sync servers to check which data can be seen to which client. 13:56.880 --> 14:00.880 And it also so we need to copy validation logic, permission checks. 14:00.880 --> 14:05.880 So we are just reinventing a traditional backend. 14:05.880 --> 14:08.880 Third approach is just don't sync everything. 14:08.880 --> 14:13.880 So I have only the sync server getting all the data, but then just check for permissions at the very end. 14:13.880 --> 14:21.880 But again, still we need custom logic and we lose the magic of strategies. 14:22.880 --> 14:27.880 Other ways of this, jets does these. 14:27.880 --> 14:33.880 We are trying to tackle this problem with we do with cryptography. 14:33.880 --> 14:38.880 Sorry, give me a second. 14:38.880 --> 14:45.880 So we use cryptographic primitives to enforce permissions in a three distributed way. 14:45.880 --> 14:48.880 Now, jets is not exactly. 14:48.880 --> 14:54.880 I mean, it is to some extent, but it's not exactly a full CRDT. 14:54.880 --> 14:59.880 But we have some similar properties and we decided to have other trade-offs. 14:59.880 --> 15:02.880 So let's see how it works. 15:03.880 --> 15:06.880 We have linda. 15:06.880 --> 15:12.880 If we have performing rolling ashes over their updates. 15:12.880 --> 15:18.880 And then at the end sign a lot of the stage, ush with the skin author. 15:18.880 --> 15:23.880 We can verify effectively that she was the one making those edits. 15:24.880 --> 15:29.880 Now, Bob can do the same. 15:29.880 --> 15:40.880 And this way we have a verifiable and independent verifiable list of transaction in jets and a final state. 15:40.880 --> 15:52.880 Now, in order to give people write permissions, we can store the information inside a group in jets. 15:52.880 --> 15:58.880 Which is just another covalu or another come up. 15:58.880 --> 16:06.880 So this way we know in the group, we chooseer can modify things inside this state. 16:06.880 --> 16:16.880 On the other hand, everything we need to give reduxes to people is instead of ushing those edits in plain text. 16:16.880 --> 16:23.880 We can just encrypt them and do rolling ashes over those encrypted changes. 16:23.880 --> 16:27.880 And store the keys and give the keys to user that needs to read data. 16:27.880 --> 16:30.880 Where do we store the keys? Again, same covalu. 16:30.880 --> 16:34.880 So same group which has which have keys. 16:34.880 --> 16:44.880 At this point doing permission changes just means changing those keys in that group. 16:44.880 --> 16:48.880 And revealing the keys to the right people. 16:48.880 --> 16:52.880 So this is actually a very simplified version of how jets works. 16:52.880 --> 16:55.880 There are some more things under the hood. 16:55.880 --> 16:58.880 If they are interested, please contact us. 16:58.880 --> 17:02.880 We'll have to give you more insights. 17:02.880 --> 17:10.880 But the nice thing I think is that in this model, the things are very completely oblivious to your approach. 17:10.880 --> 17:18.880 Because it only needs to pass data round to pass difts around within each client. 17:18.880 --> 17:24.880 And in fact, it only needs to pass down encrypted difts. 17:24.880 --> 17:28.880 So it's a completely transparent component from your infrastructure. 17:28.880 --> 17:35.880 And so for instance, if you use jets cloud to do all of your things server, 17:35.880 --> 17:39.880 you don't have to trust us with your data. 17:39.880 --> 17:45.880 And nor your user need to trust you if you want to self-host the things server. 17:45.880 --> 17:50.880 So user effectively have control over their data. 17:50.880 --> 17:54.880 Now, that's another point. 17:54.880 --> 17:58.880 Yeah, it's so client, but yeah, I need to send the emails. 17:58.880 --> 18:01.880 How do we do that? 18:01.880 --> 18:12.880 Well, that's the only problem here is that what if you have some business logic that you don't want to expose to clients, 18:12.880 --> 18:18.880 but you want to all of them in a trusted environment? 18:18.880 --> 18:30.880 Again, quoting the log of the paper, there is no cloud for us, at least in jets, is just another client. 18:30.880 --> 18:35.880 And this is an experience, a bit, a confusion point when it'll come back again first, 18:35.880 --> 18:39.880 which is that we are so used to traditional client server model, 18:39.880 --> 18:47.880 then whenever we think about something not running on our client, we assume it's a server. 18:47.880 --> 18:54.880 In fact, while most apps can just work like this and be fine, 18:55.880 --> 18:59.880 workers and server workers are just other clients. 18:59.880 --> 19:04.880 So, just to give a quick example, this is how we do permissions in jets, 19:04.880 --> 19:07.880 or like we do the fine scheme as in jets. 19:07.880 --> 19:15.880 We can see how we can define an ownership for our cat, for in this case, Linda, 19:15.880 --> 19:23.880 and our Bob can update the cat, given she had permission from, given to him from Linda. 19:23.880 --> 19:26.880 And yeah, that's it. 19:26.880 --> 19:28.880 Thank you very much. 19:28.880 --> 19:33.880 And I think right. 19:33.880 --> 19:37.880 Yes, we will now take questions. 19:37.880 --> 19:42.880 If there are in the room or in the chat, no, in the chat. 19:42.880 --> 19:48.880 So, please raise your hand if you want the mic. 19:49.880 --> 19:54.880 Yeah, you. 19:54.880 --> 19:55.880 Thank you. 19:55.880 --> 19:57.880 It's really cool. 19:57.880 --> 20:01.880 I was wondering about the role of these servers that basically act as some sort of, 20:01.880 --> 20:04.880 you know, middleman sometimes, if you want to. 20:04.880 --> 20:05.880 Okay. 20:05.880 --> 20:10.880 So, how do you decide which, like, what servers actually store? 20:10.880 --> 20:11.880 Are these servers completely public? 20:11.880 --> 20:14.880 Can anyone, because they only received encrypted things? 20:14.880 --> 20:15.880 Yeah. 20:15.880 --> 20:18.880 Or do they have a white list of allowed agents or something like that? 20:18.880 --> 20:22.880 So, in our own implementation, like, we have a set of 20:22.880 --> 20:25.880 sync servers around the world, as a different, different 20:25.880 --> 20:27.880 edges that couldn't communicate with each other. 20:27.880 --> 20:28.880 And they're public. 20:28.880 --> 20:33.880 So, in our sense, anyone can read them right from those, from those 20:33.880 --> 20:36.880 sync servers. 20:36.880 --> 20:41.880 The thing is that you can only write your data and read the data you have access to. 20:41.880 --> 20:44.880 Even if, you know, everyone is running to the same database. 20:44.880 --> 20:47.880 There is no issue, because you can only get the data you will. 20:47.880 --> 20:52.880 You can technically maybe get encrypted data, but you will not able to access. 20:52.880 --> 20:54.880 You will not be able to access it. 20:54.880 --> 21:00.880 Of course, then, if you want to self-host it, you can do additional checks. 21:00.880 --> 21:05.880 You know, to allow your clients to think to that, to your sync server. 21:05.880 --> 21:10.880 Because you don't want to people to free boot your sync server. 21:10.880 --> 21:13.880 In theory, they can be open. 21:13.880 --> 21:16.880 Thank you. 21:16.880 --> 21:18.880 Are there a question in the room? 21:18.880 --> 21:19.880 We have two. 21:19.880 --> 21:21.880 Here. 21:21.880 --> 21:27.880 Is there an easy way to compact the logs of operations? 21:27.880 --> 21:31.880 So, we don't do it yet. 21:31.880 --> 21:34.880 We are exploring ideas on how to do it. 21:34.880 --> 21:35.880 I cannot answer you. 21:35.880 --> 21:38.880 I don't give you the solution, because we don't get yet there yet. 21:38.880 --> 21:44.880 But in theory, what we want to do is compacting those stages. 21:44.880 --> 21:50.880 Because one issue of this approach is that then there is a big chance to grow a lot of our time. 21:50.880 --> 21:53.880 So, yeah, that's very exciting that I do. 21:58.880 --> 21:59.880 Thanks. 21:59.880 --> 22:01.880 That was a really great introduction. 22:01.880 --> 22:02.880 Thank you very much. 22:02.880 --> 22:03.880 I just started the day. 22:03.880 --> 22:07.880 I apologize to you, but this is actually a comment. 22:07.880 --> 22:11.880 Which is, I just wanted to clarify that we didn't write. 22:11.880 --> 22:13.880 There is no cloud. 22:13.880 --> 22:14.880 It's just somebody else's computer. 22:14.880 --> 22:18.880 I believe it was Chris Waterston, who created the bumper sticker. 22:18.880 --> 22:19.880 Okay. 22:19.880 --> 22:21.880 So, just making sure credit goes where it's due. 22:21.880 --> 22:22.880 Okay. 22:22.880 --> 22:24.880 So, I'm talking to that wherever you are. 22:24.880 --> 22:25.880 Sorry about that. 22:25.880 --> 22:26.880 No, it's a quite alright. 22:26.880 --> 22:29.880 But I just want to make sure we give appropriate credit. 22:29.880 --> 22:30.880 Okay. 22:30.880 --> 22:31.880 Thank you. 22:34.880 --> 22:38.880 Thank you for the talk. 22:38.880 --> 22:40.880 How is the time synchronized? 22:40.880 --> 22:43.880 Because those hashes are depend on time, on time. 22:43.880 --> 22:45.880 And it must be synchronized on clients. 22:45.880 --> 22:49.880 So, is it solved or is it depends on synchronization? 22:49.880 --> 22:52.880 Yeah, that's one of the trade-offs we made. 22:52.880 --> 22:55.880 Right now, jazz is based on work clock. 22:55.880 --> 22:57.880 So, it's not really synchronized. 22:57.880 --> 22:59.880 Sorry? 23:00.880 --> 23:02.880 On the other side? 23:02.880 --> 23:03.880 Yeah, yeah, exactly. 23:03.880 --> 23:08.880 It's on the clock on the device of the user. 23:08.880 --> 23:12.880 So, we made this trade-off. 23:12.880 --> 23:13.880 It's not ideal. 23:13.880 --> 23:15.880 There are maybe a better solution. 23:15.880 --> 23:17.880 We'll be exploring them in the future. 23:17.880 --> 23:19.880 We already have started doing some work. 23:19.880 --> 23:22.880 But yeah, for now it's work clock on the client. 23:22.880 --> 23:24.880 And looking at the user layer. 23:24.880 --> 23:26.880 So, specifically, there was a user preference. 23:26.880 --> 23:27.880 Right? 23:27.880 --> 23:30.880 Of like, how is this disagreement reconciled? 23:30.880 --> 23:33.880 In this case, there was a choice of color combination. 23:33.880 --> 23:34.880 Right? 23:34.880 --> 23:37.880 And I'm curious about what frameworks there are. 23:37.880 --> 23:40.880 Because what I'm seeing from the user is that there are sometimes disagreements. 23:40.880 --> 23:44.880 Essentially, like, okay, that as an organization, for example, 23:44.880 --> 23:45.880 we now need to reconcile. 23:45.880 --> 23:47.880 I'm curious about frameworks for that. 23:47.880 --> 23:51.880 So, in jazz, if you feel good about jazz, 23:51.880 --> 23:55.880 we don't, like, in jazz, especially, we decided, 23:55.880 --> 23:59.880 we found out that last variety of wins is what we, 23:59.880 --> 24:02.880 what users need, 95% of the time. 24:02.880 --> 24:06.880 So, what we do is just keep the, like, last, 24:06.880 --> 24:09.880 the last that it wins over the others. 24:09.880 --> 24:12.880 But, we also keep the wall history of edits. 24:12.880 --> 24:17.880 So, in our case, you can implement your own logic on top of this story, 24:17.880 --> 24:20.880 rather than accepting our default view. 24:20.880 --> 24:23.880 Other frameworks do things a bit differently. 24:23.880 --> 24:26.880 I don't know the world context to be honest here. 24:26.880 --> 24:29.880 But, yeah, like, in jazz, you can, no, it's not easy right now. 24:29.880 --> 24:32.880 Like, the framework doesn't really support it out of the box. 24:32.880 --> 24:34.880 But, you could do that. 24:34.880 --> 24:38.880 You can do, you can implement your own resolution logic. 24:38.880 --> 24:40.880 Great. I think we ran out of time. 24:40.880 --> 24:41.880 We had a very good question. 24:41.880 --> 24:43.880 Thank you. Y'all, I know for this amazing time. 24:43.880 --> 24:44.880 Thank you very much. 24:50.880 --> 24:52.880 Thank you.