0:39:43 Awesome.
0:39:43 So let's shift gears a little bit and
get a little bit more technical since
0:39:47 one ingredient we'll need to make all
of this happen is not just moving data
0:39:52 around, which we've explored in many other
conversations on this podcast so far.
0:39:57 But one particular aspect of that is
also that like, not just two random
0:40:02 devices are exchanging data in a
completely trustless way, but a device
0:40:07 might also be owned by a person who
has a particular identity or might even
0:40:13 on that given device have maybe there
might be multiple identities at play.
0:40:18 And so how do you retain an identity?
0:40:20 How do you, kind of exchange identity
information, that your, I love the way
0:40:27 how you put it, like your device ring,
how all of those devices can trust each
0:40:31 other, how all of that is made work,
how, and I think there's this typical
0:40:35 tension in security where if you want
to make it secure, that often comes at
0:40:40 the cost of convenience and vice versa.
0:40:43 And that's sort of.
0:40:44 Sweet middle ground where it's
both convenient and secure.
0:40:47 I think that's also very tricky.
0:40:49 So this is an area that you've really
deeply explored and you've built a
0:40:54 whole bunch of different projects.
0:40:56 I think one of them is
being the Lofi.ID, project.
0:41:00 You also have another project
on GitHub called Local Vault.
0:41:03 So maybe you want to give us an
introduction to what you've been
0:41:07 working on there, and then we
can take it one step at a time.
0:41:11 Yeah, so big picture overview.
0:41:13 is that if you are going to own data
on your device, and that's going to be
0:41:19 the source of authority for that data,
which is the premise for local-first,
0:41:24 then I believe that you both need to
be able to secure that data, meaning
0:41:29 securing it at rest, which involves
encryption, and you're going to be
0:41:33 able to need to Securely ensure that
data goes only where you want it to go.
0:41:39 Plain text data being sent around
and backed up in other places,
0:41:43 that's not going to cut it.
0:41:44 So we are going to need encryption
to be part of this equation.
0:41:49 And To boil a lot of real complicated
technology down to hopefully
0:41:54 something that just about anybody
can understand, we have this who's
0:41:58 protecting the master key problem.
0:42:02 No matter what encryption scheme you
design, whether it's password based,
0:42:06 where you derive an encryption key from
something that I type in, or whether
0:42:11 it's I've generated a key and I'm going
to Randomly, and that is your encryption
0:42:15 key, no matter which mechanism, or there's
a bunch of other variations thereof,
0:42:19 but no matter which mechanism you have,
you have this kind of encryption upon
0:42:24 encryption upon encryption, but at the
very top of that chain, you have the
0:42:27 master key, the master password, whatever.
0:42:30 And how do you protect that?
0:42:32 That's the common problem.
0:42:33 And in fact, going all the way back
to the work that I did at Hero,
0:42:37 the Web3 company that I worked at,
they had a very similar problem.
0:42:41 They were trying to create smart
contracts around the Bitcoin chain with
0:42:45 the separate blockchain, and they needed
the ability to, you know, to round trip
0:42:50 transactions in a completely trustless
way between one blockchain and the Bitcoin
0:42:56 blockchain, between Stacks and Bitcoin.
0:42:57 And they have this exact same
problem, which is who's going
0:43:00 to hold the master keys?
0:43:01 And how are you going to do
that in the open, but not
0:43:03 let everybody have it, right?
0:43:04 So we always run into this problem of It
all sounds well and great until we get
0:43:10 to the final piece of the puzzle, which
is how do you handle the master password?
0:43:13 I've been banging my head on
this for years, trying to figure
0:43:16 out there's got to be some way.
0:43:18 And the advent of biometric passkeys
was when the lightbulb went off for me.
0:43:23 Because What Passkeys do and what
the biometric subsystems on these
0:43:28 devices do is they offer a, I think,
compelling answer to that question,
0:43:34 which is there is no perfect storage
for the most secure root, master,
0:43:41 passkey, whatever you call it.
0:43:43 There's no perfect solution, but the
best that we can get is dedicated
0:43:47 hardware on the device that is not
Just free and open to any app, right?
0:43:53 If we can have a dedicated hardware
for this purpose, the secure enclave or
0:43:58 whatever it's called, and then we can
have operating systems that are designed
0:44:01 to very strong, strictly control access
to that, and it's designed in like a
0:44:06 write only way, you cannot read from it.
0:44:08 You can write to it once, and
then you can never read from it.
0:44:11 You can send data in and get results
back out, but you can never ask that
0:44:15 thing to give you its private key.
0:44:17 That really offers, I think, the most
compelling answer we've had so far
0:44:21 to where do we store the master key?
0:44:24 But one of the big problems with that,
it's not in and of itself a solution
0:44:28 to this, to this question is because.
0:44:32 I don't have access to that key.
0:44:34 That means I can't use that key
for encryption purposes myself.
0:44:40 I can create a passkey with my thumbprint
or my face or whatever, but I can't
0:44:45 get access to that key material to
use it for my own encryption purposes.
0:44:49 And I couldn't figure out how we were
going Make passkeys work in a zero
0:44:54 server assumption where there's no
servers and in a way that I could
0:44:58 piggyback upon it to create encryption.
0:45:01 And then it occurred to me that we can
actually bury the key material in the
0:45:06 passkey by way of the user ID field,
or there's actually another mechanism
0:45:11 that is coming along that I think
will be even better than the user ID.
0:45:14 But the main point is, we can actually
piggyback on top of these passkeys.
0:45:18 And in this secure part of the
device, store something in a way
0:45:22 that I think is maybe 99 percent
guaranteeable, that's a lot better
0:45:27 than almost 0 percent guaranteeable
with anything that's in userland apps.
0:45:31 Is it perfect?
0:45:32 No.
0:45:33 But it's absolutely a, you know, a
paradigm step up in terms of security.
0:45:39 And so the whole rest of everything
that I'm building is based on that
0:45:43 one assumption, which is where we're
going to solve the master passkey
0:45:46 problem is by basing this on passkeys.
0:45:50 That does have some
questions that it raises.
0:45:54 How are we going to onboard apps?
0:45:57 on devices that do not already
have biometric capabilities.
0:46:01 They don't have these secure hardware.
0:46:04 I think the good news is that more
and more devices are getting that.
0:46:07 And I think that will continue.
0:46:08 I don't think we will see a,
you know, a pullback in that.
0:46:12 I think we will see more and more
devices getting those capabilities.
0:46:15 So over time that becomes less and
less of a problem, but we do need
0:46:19 an exit ramp for not just telling
somebody, sorry, you're out of luck.
0:46:24 So I've been working on some ideas
around creating kind of a secondary
0:46:29 way of doing things that's not
biometrics based, pattern drawing
0:46:33 that's more complicated and can
create more entropy, things like that.
0:46:37 So I think we do need some exit
ramps there, but I'm going to make
0:46:39 the assumption that for the primary
class of devices that we want to
0:46:44 target here, we have the biometrics.
0:46:47 Once we have that, once
we have that capability.
0:46:49 We needed a way to be able to manage
pass keys without relying upon servers.
0:46:54 So the first library that I wrote
was WebAuthn Local Client, which was
0:46:59 designed to wrap around the web API
that exposes the passkey subsystem,
0:47:04 but doesn't make any assumptions
about communicating with the server.
0:47:07 the use cases in local-first don't need
what the server would do anyway, so that's
0:47:13 not a problem, but it's just no other
libraries out there that I had found where
0:47:17 it could work if you didn't have a server.
0:47:19 So I wrote a library that exposed
that API in a way that made the
0:47:23 assumption you weren't going
to communicate with the server.
0:47:26 You were going to store things securely.
0:47:28 You were going to generate
the challenges on device.
0:47:31 You were going to keep track of
the key and verify that was coming
0:47:35 out was not man in the middle.
0:47:36 You were going to do all of that.
0:47:37 on device, not on server.
0:47:40 So that's what WebAuthn local client was.
0:47:41 That was the first little
piece of the puzzle.
0:47:45 Then I said, okay, well now we need a
way to, piggyback on top of the passkey
0:47:51 system and create something that we can
use for encryption purposes so that we can
0:47:55 protect data both at rest and in transit.
0:47:58 we need some keys.
0:47:59 And I did a lot of research in this.
0:48:01 I'm not an expert.
0:48:02 I'm not a mathematician.
0:48:04 But I settled on, this was back when I was
working at Socket, I settled on, Elliptic
0:48:09 Curve keys, specifically the Edwards
key, the ED25519 key pair as the best
0:48:17 master key pair because you can generate,
that can be used for signing, and you
0:48:21 can generate a sub key pair from that.
0:48:23 That's the Curve 25519 keys
for encryption and decryption.
0:48:28 I settled on that as the best, but
that's not the only way of doing it.
0:48:31 And certainly anybody else could
substitute their own encryption,
0:48:34 or maybe we're going to need to
upgrade that encryption in a post
0:48:38 quantum world in some few years.
0:48:40 But, that's where I landed was,
let's use that, because I think
0:48:43 that's good enough and strong enough.
0:48:45 And I found the Libsodium library,
which is big and complex, but it's,
0:48:49 I been ported to tons of platforms
and that was important to me.
0:48:53 And so I based the ideas around securing
our data on that type of key pair.
0:48:59 So we generate a 25519 key pair.
0:49:03 We take the seed of that, or in my
library, I call it an IV, but IV
0:49:07 or seed, we take the seed of that.
0:49:09 And that's what we store in the passkey.
0:49:11 And with that information coming back
out, each time you put your thumbprint
0:49:14 or your face ID in, you can reconstitute
that key pair and then decrypt
0:49:19 whatever data was previously encrypted.
0:49:21 That is how we fix that
master password problem.
0:49:26 So I built a library to help you do that
and that's called local datalock is the
0:49:30 library that wraps around the WebAuthn
local client, but then it does the
0:49:35 generated encryption key, stick the seed
into the passkey, it does all that stuff.
0:49:41 it does not do anything
about storage of it.
0:49:43 Right?
0:49:44 So you might use local data lock when
all you care about was transmitting
0:49:47 secure data, but it does provide
the pieces for the next one.
0:49:52 The next one was we need to figure out
how we're going to store that data in
0:49:58 an encrypted fashion on the device.
0:50:01 And then, so it's encrypted on
write and decrypted on read.
0:50:05 How are we going to do that?
0:50:06 Well, I actually realized I need
two pieces, not only one to manage
0:50:09 the encryption piece, but actually
I needed a library to manage the
0:50:12 storage piece, because there's
a lot of different variations of
0:50:15 storage, as we were just talking
about with OPFS and things like that.
0:50:19 So I built the Two libraries
to help with this piece.
0:50:22 One library is, I've spun out actually,
it's not even local-first really, it's its
0:50:28 own thing, which is just abstracting local
client storage in a key value way across
0:50:35 all the five major storage mechanisms.
0:50:37 So cookies, local storage, session
storage, indexDB, and OPFS.
0:50:42 And technically under OPFS, there's
two different ways of managing it.
0:50:45 One is more device limited, but
it's the in thread communication
0:50:51 that you can do, asynchronously.
0:50:53 But the more broader device support,
basically all devices at this
0:50:58 point, or all modern devices at
this point, is OPFS in a worker.
0:51:02 and if you do OPFs in a worker, which
you're nodding because you've seen
0:51:06 the same problem, but managing workers
and all of that stuff is difficult.
0:51:09 So that's what this library does, is it
abstracts across all of those mechanisms
0:51:13 the exact same asynchronous key value API.
0:51:17 And that library is called Storage.
0:51:19 It's part of my BYOJS Bring
Your Own JavaScript initiative.
0:51:23 so we'll have a link to that.
0:51:24 But that storage library, even if
you didn't do anything local-first,
0:51:28 you just wanted to store data, I
think that would be useful to help.
0:51:31 Think of it as kind of a more
modern Local Forage, maybe.
0:51:34 Local forage has been around for a decade,
but it's not really maintained anymore,
0:51:38 and it didn't support all the mechanisms.
0:51:41 I think storage is a compelling
option to look at if you're sticking
0:51:47 anything on a local device, even in
local storage, maybe have a better
0:51:50 API and a more secure API for that.
0:51:53 So first of all, storage there, that
has nothing to do with encryption.
0:51:55 It's just The raw reading
and writing from a disk.
0:52:00 And then the last piece of the puzzle,
the one you mentioned before, is the
0:52:03 local data vault . So that library is
what takes storage, WebAuthn, local data
0:52:08 lock, and all those pieces together,
and gives you that local vault, which
0:52:15 is a secure, encryption secured, based
on passkeys, encrypt on write, Decrypt
0:52:20 on read key value storage mechanism.
0:52:23 And you can, of course, choose which
of those places you want to store, like
0:52:27 store it in IndexedDB or store it in OPFS.
0:52:29 But it does all the encryption
and decryption stuff for you
0:52:33 based on the passkey subsystem.
0:52:35 So that's what I've built so far.
0:52:38 Where all of that is going
is towards, there's two ways
0:52:43 that I see this happening.
0:52:44 First of all, I think apps can start
to use, web apps can start to use those
0:52:49 libraries, whatever pieces of that makes
sense to you, use all of it, use part of
0:52:54 it, but start to use those pieces to do
some of this stuff yourself in your own
0:52:58 apps, build your own solution if you want.
0:53:01 I also think that we need to
lower the barrier for apps
0:53:04 to do a lot of this stuff.
0:53:05 And I also think that the more
consolidated of approach we get,
0:53:09 the better chance we have of
something like this catching on.
0:53:12 And so instead of just writing like
a standards doc and saying, if you do
0:53:17 it, you have, you must do it this way.
0:53:19 the approach I'm going to take is to
build a companion Wallet app that allows
0:53:24 you to manage as a user, any number
of your own identities, Protected, of
0:53:29 course, through this passkey subsystem.
0:53:32 And apps will have an SDK that they
can interact with the Wallet app,
0:53:37 whether that Wallet app is a browser
extension, like we mentioned a little
0:53:40 while ago, or whether it's a literal
actual side, you know, companion app.
0:53:44 They'll be able to interact
with that app to ask that app,
0:53:48 Hey, tell me who this user is.
0:53:51 Tell me that it's the same
user as they were before.
0:53:53 That's one question.
0:53:55 So instead of them needing to build
their own authentication, they'll
0:53:57 simply make a call to this Wallet and
say, verify for me that this user is
0:54:01 who they say they are and give me back
their identifier, which might be their
0:54:05 key or some other UUID that you specify.
0:54:08 That's one question.
0:54:09 But also I think those apps shouldn't need
to roll their own encrypt all of my data
0:54:15 and decrypt it all and all of that stuff.
0:54:17 So they'll also be able to provide
the data to the Wallet app and ask
0:54:22 it to encrypt it for them through
that SDK and decrypt it for them.
0:54:26 And again, based all
of that around passkey.
0:54:28 So they don't need to
invent any of that stuff.
0:54:30 The Wallet app will just
take care of it for them.
0:54:33 And then the last piece of the puzzle is.
0:54:35 if you build an app, let's say like
it's a, you know, it's a note taking
0:54:39 app, or it's a social media app,
or whatever, and it does need to
0:54:41 communicate with other devices, instead
of you doing your own synchronization
0:54:46 logic, I think we can actually have
the Wallet app built with peer to peer
0:54:50 capabilities so that my Wallet app on
my phone and my Wallet app on my laptop
0:54:55 and on my tablet can synchronize my
identities, but can also synchronize
0:54:58 userland app data through the Wallet.
0:55:01 Use the Wallet as a tunnel
to do synchronization.
0:55:04 when I say synchronization, I do not
mean that I'm solving anything that what,
0:55:10 what the larger local-first community
says when they say synchronization
0:55:13 with all the CRDTs and all the
merging and stuff that I want to
0:55:17 leave open to this community to solve.
0:55:19 You can plug in whatever.
0:55:21 CRDT systems you think make sense and
whatever strategies you make sense.
0:55:25 I'm simply going to provide the transport
layer through peer to peer various peer
0:55:29 to peer technologies in this Wallet app
so that those bits can get from my phone
0:55:34 to my watch, to my laptop, to my tablet.
0:55:37 And then you'll, your app will
decide what do we do with that?
0:55:40 In your own app logic, you'll decide
how do we merge these competing
0:55:44 sets of bits that are coming in.
0:55:46 I just don't want for people to have to
go invent all of their own wheels there.
0:55:49 And I think a single unified Wallet
app will allow people to do that.
0:55:54 there's other things that I want that
Wallet app to do, but that's kind
0:55:57 of the main, starting point, the 1.
0:55:59 0 that I want this Wallet app
to do is to give that to the
0:56:02 local-first community and say, please
consider building upon that Lego.
0:56:07 Perfect.
0:56:07 So this was a lot and, kudos to you
for doing such comprehensive research,
0:56:14 deliberating the different options.
0:56:16 There's always like so many different
paths that you could go in regards
0:56:20 to like all of the different
decryption encryption mechanisms, like
0:56:25 choosing, should you use Libsodium?
0:56:27 Should you use WebCrypto?
0:56:29 Should you use other things, for
what it's worth for Overtone?
0:56:32 I've also landed on using
Libsodium, which, I needed to even
0:56:36 compile my own WASM version to
trim it down a little bit more.
0:56:40 but, yeah, so you've covered a
lot of ground there and I have
0:56:44 a few follow up questions where
I would love to learn more.
0:56:48 also one observation that I just,
as someone who appreciates like
0:56:53 good terminologies and clear
concepts, I just love the term Vault.
0:56:58 As something that, both signals like, Hey,
this is something where it can put stuff
0:57:02 in and get stuff out and it is secure.
0:57:05 So a vault being sort of that combination
of your storage mechanism and that
0:57:11 search mechanism has nothing to do
with encryption at that point, but if
0:57:14 you then combine it with encryption
and decryption, that makes a vault.
0:57:19 I think that's a very intuitive concept
that is, that works both as a concept for
0:57:24 developers, as well as even for end users.
0:57:28 like I think this is what also 1Password,
for example, has started to use.
0:57:33 And I think, 1Password users are
familiar with that also, I'm sure
0:57:37 for other password managers as well.
0:57:40 And so that as a concept, I
hope that it's not just a.
0:57:44 a concept that is used within the
local vault and like the stack that
0:57:49 you're exploring here but hopefully
that's something that as a term,
0:57:53 can be useful for others as well.
0:57:56 Yeah, I agree.
0:57:57 I think it does communicate
what it needs to.
0:57:59 I workshopped that with some of my
social media community, by the way.
0:58:03 I had lots of different suggestions and
I, you know, kind of pieced together
0:58:06 various things, but I workshopped
some of the naming of this, you know,
0:58:10 crowdsourced it because I wanted to
make sure I got a name that really
0:58:13 communicated properly, what I was up to.
0:58:16 So to me, it sounds like you've landed
on a great option here and I might
0:58:20 actually steal that for myself and,
the ways how I'm like in my own data
0:58:25 stack, where I have a database right
now, it's not encrypted address,
0:58:28 but I want to encrypt it more.
0:58:30 And so maybe I can also use
for the SQLite database there.
0:58:35 Maybe I can also start calling
that a vault if it's encrypted.
0:58:38 I like that a lot.
0:58:39 and I also like how you've
already thought a step further.
0:58:43 it's not just as that, like as a tech
stack that can be implemented by a
0:58:48 given apps or high level libraries,
but also from a user perspective, if
0:58:53 you're not just going to use one app,
the kind of part of the entire promise
0:58:57 here is that, like here you have data
in one app and data in another app.
0:59:02 That, and maybe those apps want to
work together and that is actually
0:59:06 something that is like really, really
difficult in today's web2 world.
0:59:12 Where like, just think about
like how much of an effort it is.
0:59:15 That's maybe the best we got.
0:59:16 Maybe it's like a Slack, integration
that like Slack is like a little bit more
0:59:22 aware of like what that Figma link means.
0:59:26 And, I can open it all in my browser.
0:59:29 So from my perspective, it kind
of feels like, Oh my gosh, why
0:59:31 don't you have that context?
0:59:33 So if we, embrace a little
bit more of the user.
0:59:37 The identity concepts, and then also let,
that dictate a little bit of the share,
0:59:43 the context sharing and access control.
0:59:45 I think that can lead to
much better user experiences.
0:59:49 there've been many, many years of
attempts to create in the mobile space.
0:59:54 there was like web intents and then
web share and share intents and like
0:59:58 all these other variations and it went
through various different names and
1:00:03 standards processes stumbled with it.
1:00:05 I don't even know where that currently
stands, but that's exactly where I'm
1:00:08 headed is basically, let's just get around
any of those limitations and allow, for
1:00:13 example, a use case where, you know, I
might be in a local-first note taking app,
1:00:18 and I might have written a note and I want
to, you know, copy a piece of that note,
1:00:22 and I want to send that out to one of my
text messaging recipients or one of my
1:00:26 chat recipients or whatever, so I can take
that note and I can synchronize, I can
1:00:31 share that information to this other app
in a fully secure, end to end secured way.
1:00:36 But it ends up in my other app, and
that other app pops up, and there it is,
1:00:40 in the exact same way that, you know,
you can currently do sharing intents.
1:00:45 Native apps have that, but the web has
always been, you know, a third class
1:00:50 citizen at best in that sort of cross
app collaboration and in sharing story.
1:00:57 And I think we can make it a
fully first class story this way.
1:01:01 And I think that also takes us in
possibly even a step further that
1:01:05 goes beyond today's conversation.
1:01:07 so far we talked about identity
and also a part of that identity is
1:01:12 like authenticating as assuming that
identity or being denied that identity.
1:01:17 that's often abbreviated as Auth, but
Auth can also mean another non abbreviated
1:01:24 word, which is authorization, which I
think this is not yet covering that,
1:01:29 but there, I want to plug another very
interesting project that is more around
1:01:34 authorization, which is called Beehive.
1:01:37 that's also been published on
the Ink and Switch website.
1:01:41 and there's currently,
I think, not yet a full.
1:01:44 Inc & Switch style essay about that, but
there are some notes being taken on this.
1:01:50 And so this is a project that, Brooklyn
Zelenka and Alex Good is currently
1:01:54 working on that is, also ongoing
research in combination with AutoMerge.
1:02:00 And Brooklyn has been exploring a lot
of that, as her previous work On vision
1:02:05 and related projects, so, and this is
where, the authorization concepts to my
1:02:10 understanding is sort of based around
the ideas of capabilities and, that
1:02:17 different users can basically, share
capabilities, and privileges basically
1:02:22 up to a level that they have themselves,
whether it's read or write and so on.
1:02:27 So I'm sure this is like an equally
deep and challenging topic and, but they
1:02:32 feel a little bit, complementary to me.
1:02:35 So hopefully there's like some
convergence here as all of
1:02:39 those are like very deep topics.
1:02:41 I did see that Beehive
announcement just recently.
1:02:44 I think that's great.
1:02:45 I think we need a lot of different
flowers blooming in this field to figure
1:02:49 out and find the places where there's
going to be overlap and collaboration.
1:02:53 By the way, just as a little bit of a
side note, I literally just yesterday.
1:02:57 learned something that maybe everybody
else listening has already known
1:03:00 and I didn't know, but just for the
benefit of the audience, the word
1:03:04 auth is you, A U T H as you correctly
point out, is a little too ambiguous.
1:03:08 It's a little too shortened
because we don't know, do you mean
1:03:11 authentication or authorization
1:03:13 but I saw somebody do auth
Z for authorization versus
1:03:17 auth n for authentication.
1:03:19 So if we just add on that one extra
letter to that shortened word auth,
1:03:23 n or auth z then we know maybe
better what we're talking about.
1:03:28 So I learned that yesterday and I'm
going to use that going forward.
1:03:32 Amazing.
1:03:32 I was not aware of that, what that
little letter N in that context meant.
1:03:38 there's also what you've
mentioned, web auth N.
1:03:41 Maybe that is what it's already using.
1:03:45 Perfect.
1:03:45 Well, today I learned, thank you
for sharing that little learning.
1:03:49 and kudos to everyone who
was already aware of that.