0:00 Kent Bull | KERIA Tutorial | KERI Conference 2026
0:02 Okay, we are getting started.
0:05 All right.
0:08 This is primarily developer focused.
0:11 We're getting down into the nitty-gritty
0:13 nuts and bolts.
0:15 And I imagine since it's developer
0:16 focused, we'll probably have a smaller
0:18 audience. I'm going to go through and
0:19 get to know each one of you.
0:21 Some of you I've never seen before.
0:23 Who?
0:25 Oh, thanks. Great.
0:27 I don't think I've ever met you before.
0:29 Will you tell me your name?
0:31 This is everybody. This is Joseph
0:32 Hunsaker.
0:33 Everybody knows Karla McKenna.
0:36 One of my bosses at GLEIF. And I do have
0:39 to remind me your name. Matthew? Yes,
0:40 – Matthew. – Matthew.
0:42 Matthew Hillstone.
0:43 – George McEwan. – George McEwan, okay.
0:45 Mitchell with healthKERI. Mitchell
0:47 with healthKERI, okay. I don't think
0:48 I've met you before. That's cool.
0:50 Mark Scrimshire ONYX.
0:52 What was the name of the company? ONYX?
0:54 ONYX, okay. And then the name, Matt?
0:56 Mark Scrimshire. Mark Scrimshire, okay.
0:59 Nice to meet you.
1:00 So, what this tutorial is for you
1:04 if you're wondering what is KERIA, what
1:07 is Signify,
1:09 what is this signing at the edge
1:10 architecture that many of the qualified
1:12 vLEI issuers in the GLEIF ecosystem
1:15 have embraced.
1:17 For example, Provenant,
1:19 Finema,
1:21 I would say there's a
1:23 CFCA in China. And we've got a number of
1:26 others that are
1:28 Trade Go.
1:29 Certizen, that's correct. So, the
1:31 platform you're seeing today is used in
1:34 production by a number of
1:36 our qualified vLEI issuers
1:38 and other people .., there's
1:41 the Veridian wallet, they've built on
1:42 top of this architecture as well. Now, I
1:44 should caveat that
1:46 the wallet you're seeing today
1:49 is a demo wallet. It's not Provenant's
1:52 wallet. No QVIs use the wallet. It's a
1:55 demo wallet to walk you through the
1:56 features.
1:57 Now, the goal of today's presentation is
1:59 so that you can walk away as a developer
2:01 knowing how do I configure and run this
2:03 thing? What is this API surface area?
2:07 What are the capabilities? What can this
2:08 thing do for me?
2:10 We will actually
2:12 have a demo. And if you look at this
2:15 wallet right here, this is something
2:16 yes, I use Codex to help me make this.
2:19 I actually made one of the first
2:22 wallets in the world for DigiCred for
2:24 student credentials based on Signify-TS
2:26 and KERIA. This is way better than
2:28 that.
2:29 It's more of a developer
2:31 wallet, I'll admit it. Their DigiCred
2:33 wallet was way better user experience
2:36 which geared towards students for
2:37 non-technical people. This wallet is
2:39 geared for you all. So, if you want to
2:41 look inside how does this work as a
2:43 developer? It's geared towards your
2:44 mental model. Cuz quite honestly, for a
2:47 customer
2:48 for a non-technical person, this is
2:50 already way too complicated. This is a
2:51 developer user experience. So, it's for
2:54 you to categorize and understand what
2:56 are the subject matters of API surface
2:59 area for me to worry about. Did you have
3:00 a question, Matthew? – So, this is
3:01 basically is it meant to be a web
3:03 application? Is it meant to be an
3:04 extension or a mobile app or all any of
3:08 the above? – I'm going to repeat that
3:10 question because it's a very good
3:11 grounding question for what is this
3:14 architecture. He said, is this intended
3:15 to be a web app? Is it a mobile app?
3:17 What is this intended to be used for?
3:20 So, let's actually
3:21 Or a browser extension. Or a browser
3:23 extension. So, let's actually pause and
3:26 jump back to the presentation cuz I
3:27 answered that question. Very good
3:29 question. I can tell you're thinking.
3:31 Okay, so then we ask what is KERIA? When
3:34 is it useful?
3:35 KERIA, the architecture, let's just jump
3:38 straight to the nuts and bolts. It's
3:40 this architecture right here and we're
3:41 going to answer your question right
3:43 away.
3:44 So, that web app that you were seeing
3:47 is a browser web app.
3:49 Most people use it as either a browser
3:52 app or like on a cross-platform
3:55 application basis, Ionic Capacitor
3:57 or React Native.
3:58 Anything that uses TypeScript that's
4:01 compatible with Libsodium in the
4:03 browser, specifically Libsodium wrapper
4:05 Sumo,
4:06 that can that can work with React
4:07 Native, you can run the Signify and
4:10 KERIA architecture. Well, why would you
4:12 want to do that? Well, let's understand
4:14 a little bit more about the "what"
4:16 and the "why" will become evident.
4:19 I'll preface this by saying
4:22 there's two broad categorizations of
4:24 wallets in the KERI ecosystem. The
4:26 terminology that I'm about to use is
4:28 mine. I started using this because it's
4:30 it's a way for me to categorize
4:33 how the different wallets are.
4:37 You can use whatever terminology
4:39 makes the most sense to you. I call the
4:41 Signify client wallet, Signify and KERIA
4:44 architecture, I say lightweight wallet.
4:47 And I call what Locksmith is, Philip
4:50 Feairheller from healthKERI,
4:52 Locksmith is a heavyweight wallet. Why
4:55 is that the case? I'm about to describe
4:56 why and we're just you're going to
4:57 understand it from the very beginning of
4:59 the presentation.
5:00 Lightweight refers to
5:02 what the user has in their hands.
5:06 With Signify, all they have is an edge
5:08 signing client. They don't store their
5:11 credentials.
5:12 Keys only ever exist unencrypted in
5:15 memory in whatever browser or web view
5:17 instance they have, but that's all
5:19 that's ever stored here is just the
5:21 unencrypted keys and just enough state
5:24 to do whatever your operation you're
5:25 doing, whether it's issuing credentials,
5:28 doing an interaction event, doing a key
5:29 rotation,
5:31 doing an OOBI resolution. A bare minimum
5:33 of state is kept here, which is why I
5:34 call it the lightweight client.
5:37 The heavyweight client essentially
5:38 takes, you could say this edge signing
5:41 architecture,
5:42 and your key store, heavyweight wallets
5:45 put all that together locally. You could
5:47 think of local first software where all
5:49 of your keys .., if you'd have a heavy
5:52 weight wallet, you'd have everything in
5:54 in one app on your phone, and you would
5:56 not have a server agent. The lightweight
5:58 wallet has a server agent, and you might
6:01 say, "Well, is that okay from a security
6:03 perspective? What about the keys? Where
6:05 are the keys? Are we
6:07 custodying keys here?"
6:09 We're going to get into the nuts and
6:11 bolts in the later slides. The
6:14 answer is that
6:15 there are keys, key seeds that are stored
6:18 here, but they're only ever stored in
6:19 the server encrypted.
6:22 The way that it works, and we'll get…
6:23 there's some more slides… is the root
6:26 master key here in the Signify
6:28 lightweight wallet client is an
6:31 encryption decryption key.
6:33 It's also a KERI AID.
6:35 It performs a delegation from the
6:37 in-memory
6:38 identifier to the agent identifier. If
6:42 you're familiar with the concept of a
6:43 witness, a witness is a non-transferable
6:46 identifier, right?
6:48 And but it's a regular
6:49 KERI identifier. You can get a key event
6:51 log. You can resolve an out-of-band
6:52 identifier to get that Key Event Log
6:54 with that one event plus some location
6:56 scheme records and endpoint rule records
6:59 for a witness. Well, an agent is a
7:01 little bit like a witness, and there's a
7:02 common capability between witnesses and
7:06 agents at least in the most commonly
7:08 deployed form. HealthKERI actually did
7:10 witnesses the right way in the sense
7:12 that it's only a witness.
7:15 But, just because of an artifact of
7:17 accident of history, witnesses in the
7:19 beginning
7:20 of GLEIF's implementation of the
7:23 the KERI spec, witnesses and mailboxes
7:25 were combined.
7:27 Mailbox is a store and forward
7:28 mechanism. Cuz what happens if your
7:30 phone goes offline and it's a
7:32 lightweight client? You still want to be
7:33 able to receive messages when that phone
7:35 comes back online, right? You don't want
7:36 to not be able to receive messages
7:38 because your phone's off or it's dead
7:40 battery.
7:41 So, what you do is there's a mailbox.
7:44 A mailbox
7:45 runs in a persistent process that has
7:48 an IP address,
7:49 a way to essentially send it messages,
7:51 which is similar to a DIDCOM relay.
7:54 Now, I see that a couple of people came
7:55 in here later. Before I
7:57 sort of finish off the mailbox topic,
7:59 I'm just giving you a warning. I'm going
8:00 to come in to ask your names and sort of
8:01 introduce you to everyone else cuz
8:03 we're all developers here, so we get to
8:05 to know each other. All right, so I'm
8:06 talking about this concept of a mailbox.
8:09 An agent functions as a mailbox. It's a
8:11 store and forward mechanism. It's a
8:13 persistent internet presence.
8:15 The primary responsibilities of an
8:17 agent, it's a mailbox, it's a delegation
8:20 communication proxy, which we'll get
8:21 into later,
8:23 and it's the primary data store.
8:25 Your ACDCs are stored here,
8:28 not here.
8:29 Your contacts, your out-of-band
8:31 identifiers, your Key Event Log, it's
8:32 all stored here. It's all signed here.
8:35 Nothing is signed here
8:37 on your identifiers.
8:40 With a small caveat, remember I said
8:42 it's a mailbox, it's a store and forward
8:44 mechanism, it's a delegation
8:45 communication proxy.
8:47 As it performs those functions,
8:49 remember, we're in zero trust. It's a
8:51 signed everything
8:53 architecture, no shared secrets
8:55 architecture. When the agent itself,
8:57 which is an identifier, it's an actor in
8:59 this ecosystem, when the agent is
9:01 sending communications, it does have its
9:03 local key that it'll sign messages so
9:07 that everything coming from the agent
9:09 can be signed and verified.
9:11 But, the agent does not have any of your
9:13 keys. That's the thing.
9:15 Go ahead, question. – Is this strictly a
9:17 delegation model? – Strictly delegation.
9:20 KERI delegation. Okay.
9:23 And what's interesting, so how it works
9:24 and this is… architecture slides are fun
9:27 because you can spend a lot of time on
9:28 them and then we'll breeze through the
9:29 rest of the
9:30 the slides.
9:32 The way that you provision an agent, so
9:35 when you
9:37 instantiate it in memory,
9:39 the way that you boot an agent there's
9:41 it's two-phase process. You do boot and
9:44 then connect. When you do your boot up
9:47 (I need to touch my computer more often,
9:48 I guess.
9:50 Oh, it's thinking that we're not
9:53 paying it enough attention.
9:55 Let's give it some attention here.
9:58 Change. I love this picture. I got to go
10:01 there someday. This is in France. It's
10:02 the one of the most beautiful places
10:03 I've ever seen in my life.
10:07 I'm going to take my wife there.)
10:11 We're back up.
10:18 process, you're actually signing a
10:19 delegation event. You send it over here.
10:21 You request from the agency. So, you
10:24 actually send the initial boot to the
10:26 agency. It provisions the agent and
10:29 starts the delegated inception process
10:32 in the agent identifier. It's first
10:34 event
10:35 in its Key Event Log is a delegated
10:38 inception. It accepts the
10:40 delegation request and then when it
10:41 responds on the connect, it actually
10:44 completes the delegation handshake.
10:47 This is a strict KERI delegation
10:49 relationship between your edge signer
10:51 and your agent identifier.
10:54 I have some
10:56 other graphics here to show you that the
10:58 agent has the responsibility of managing
11:00 the database for
11:02 your identifier, any credential
11:05 registries, and credentials that you've
11:06 got. Now, the keys that are stored here,
11:09 remember they're only ever encrypted.
11:12 And they're encrypted
11:14 with the key that is derived from the
11:16 passcode you have at the edge. This
11:19 passcode never moves over here, ever. It
11:23 only ever stays at the edge. That's why
11:25 it's called a signing at the edge
11:26 architecture.
11:28 [inaudible]
11:33 Not quite. This together is the
11:35 lightweight architecture.
11:37 The heavyweight wallet combines both of
11:40 these responsibilities into one thing.
11:43 This runs on a server.
11:45 This runs on a client.
11:48 Makes sense?
11:50 (This is leaking.
11:52 That's really weird.
11:55 Just got to drink it all.
11:57 I wasn't abusive to
11:58 this. I don't know why it's leaking all
11:59 over there.)
12:01 Let's move on.
12:04 So is there anybody that has any
12:06 lingering questions on the architecture
12:07 before we move on? – The agent on the
12:09 right side is the whole thing. It's not
12:11 just the one component?
12:14 – So this is multi-tenant in the sense
12:16 that the agency can have multiple
12:17 agents. I expanded out what you're going
12:20 to have inside of an agent. – So there's
12:22 multiple clients.
12:25 – Well, there can be multiple clients.
12:26 Yeah. – All using the same
12:29 agency, but they have a different… – Yes,
12:31 this is the orchestrator for
12:33 the multi-tenancy for a given server
12:35 process.
12:37 – So therefore one agent per Signify
12:40 client. – Correct. That's
12:43 a good point. It's a one-to-one
12:45 relationship between Signify controller
12:49 and KERIA-agency agent. – And
12:52 all of the components underneath the
12:53 agent are what's inside of it.
12:55 – Yes.
12:57 And there's a dedicated LMDB database
13:00 for agent. Actually a set of
13:02 files.
13:03 Now that we beat that to death,
13:07 KERIA means KERI agent. That's what it
13:11 means.
13:12 So it actually originated
13:14 something called the simple KERI Web
13:15 Auth Protocol and that evolved to Signify,
13:18 sign at the edge. Where you have your
13:20 link to the original hackMD document. I
13:21 remember when this is being first talked
13:23 about back in 2021, 2022. There's a
13:25 current WebOfTrust repository with the
13:27 original
13:28 simple-KERI-for-web-auth (skwa). It's
13:30 actually some of the best documentation
13:32 of the
13:33 different alternatives and ways to think
13:34 about it if you want to really sort of
13:35 do a
13:36 some software archaeology.
13:39 But the basic idea
13:41 encryption key at the edge
13:43 and the identifier seed salts in the
13:46 agent. Now you have the encryption key
13:48 at the edge
13:49 and what happens is you will pull those
13:51 encrypted salts
13:54 from your agent locally to the edge in the
13:56 browser and use them to do signing of
13:58 events
13:59 for any of your managed identifiers.
14:02 Okay, so…
14:06 what's the agent? We sort of beat that
14:07 to death. Let's go ahead and move on.
14:09 I don't think there's anything [more to discuss, red.]
14:11 We haven't really talked about delegation
14:13 communication proxy. We'll get into that
14:15 a little bit later, but once again, it's
14:16 your storage server for
14:18 ACDC's contacts, OOBIs, challenge
14:21 response, and all that.
14:23 At a high level, what are the
14:25 features we have in
14:27 in the Signify/KERIA architecture?
14:30 It's just the same things that you're
14:32 going to have in the heavyweight wallet
14:34 architecture. It's just all the events
14:36 are signed at the edge. We've got client
14:38 creation boot and connect like we talked
14:40 about. Client creation, that's actually
14:42 something specific to the lightweight
14:44 wallet architecture, but all the rest
14:46 is applies to the lightweight and
14:48 heavyweight. Identifier creation,
14:50 rotation, interaction, I should have put
14:51 signing on there. Out-of-band identifier
14:53 generation and resolution, challenge
14:55 creation and response verification,
14:57 credential issuance, grant admit, and
14:59 the full IPEX prop
15:01 flow, if you're familiar with the other
15:02 verbs.
15:04 And we're going to get to the KERIA
15:05 configuration. So that's sort of what
15:06 what we've got the capabilities of
15:08 this architecture here.
15:10 You will leave here knowing how to
15:11 configure a KERIA server. We're about
15:13 20 minutes in. We'll get to that. I'll
15:15 make sure we get to that. Question.
15:18 – Credential issuance. So, is
15:20 for
15:21 the AID [inaudible]
15:24 they're issuer
15:25 Is that? – No, that's a good question.
15:27 Let's actually go back. So,
15:29 which identifier does the issuance?
15:32 Is it the Signify controller that does
15:34 the delegation to the agent? No.
15:37 What's called a managed AID is what does
15:40 the issuance.
15:42 So, the Signify controller delegates to
15:44 the agent and it says, "Agent, make me
15:46 an identifier." And the agent says,
15:48 "Okay, well, you have to give me a
15:48 signed event."
15:50 So, you create the key locally
15:52 that's going to end up as the
15:54 stored encrypted seed.
15:56 When you have that in memory, it's
15:57 decrypted, you create the inception
15:59 event for a managed identifier, then you
16:02 send that to your agent, and your agent
16:03 says, "Okay, great. I'll create a
16:05 managed identifier record in my
16:07 database."
16:08 And this is the level at which you're
16:10 going to start to issue credentials.
16:12 So, it's actually one layer deep below
16:15 the Signify controller.
16:18 Does that make sense?
16:19 Or enough for now?
16:20 [inaudible]
16:23 Yeah, so we'll have a demo later. It'll
16:25 probably clear it up a little bit.
16:27 – Why are you generating the key and
16:29 sending the key
16:30 at that client and not generating it and
16:32 sending it at the agent itself? It feels
16:34 like the
16:35 generation of the key would be more
16:36 secure at the agent side. – It's not
16:39 because the server can be compromised,
16:40 right?
16:42 We don't
16:43 store any keys here unencrypted.
16:46 The keys only ever exist at the edge,
16:49 which is why it's called the signing at
16:50 the edge architecture. – I see. So, you're
16:53 encrypting the key, and then that
16:55 encrypted
16:56 key is stored there. – Yes, the encrypted
16:58 key is stored in the agency, but
16:59 remember, the agent never has access to
17:02 the unencrypted key ever.
17:05 All signing occurs at the
17:08 edge. This has implications when you use
17:10 HSMs (hardware-security-module).
17:12 Because you have to send your event to
17:14 the HSM to be signed.
17:17 HSMs are another signing at the edge
17:19 architecture.
17:21 It's just the HSM is the edge.
17:24 Question.
17:25 - [Why store encrypted key in the agent?, red.]
17:27 Well, think about it. If you lose
17:30 your lightweight client, you don't want
17:31 to lose your seed, right?
17:33 All you have to remember,
17:35 the reason why it's a lightweight
17:36 architecture, all you have to remember
17:37 is your passcode.
17:39 If everything fails and you lose
17:41 your phone, well, you've got a
17:43 server agent where you can, as long as
17:45 you have a password manager and you have
17:47 your root passcode,
17:49 well, you can
17:50 reconnect to your agent and reconstitute
17:53 the keys locally by decrypting them. So,
17:56 storing them in the agent
17:57 is actually very handy.
18:00 Yeah.
18:01 You could store them in a mobile
18:03 app if you wanted to do that and change
18:04 the storage model, you could totally not
18:05 even store them on the server. They're
18:07 just stored on the server from a
18:08 convenience perspective.
18:10 And really, you could build an agent
18:12 replication or state
18:14 migration architecture if you really
18:15 wanted to on top of that.
18:17 [inaudible question about the format of the passcode]
18:22 Yes, 21 characters.
18:23 But, it's actually exactly 21
18:25 characters.
18:26 If you put in more than 21 characters,
18:28 it chops it off the 21. And if it's less
18:29 than 21, it doesn't let you do it.
18:32 So, it doesn't do any stretching right
18:34 now. It has to be 21 characters.
18:36 And I can we can go into the
18:38 dirty details of why that's the case
18:40 sometime.
18:42 Yeah.
18:44 Okay, so we went into the features
18:45 outline.
18:46 I'll show you a demo.
18:49 [hardly audible confirmation]
18:53 [that this has nothing to do]
18:57 [with witnesses and watchers]
19:01 Correct, let me
19:03 clarify. Let me give you a caveat.
19:06 Whenever you create an identifier, you
19:08 can specify witnesses
19:11 as Backers.
19:14 Well, yeah, it's not the agent.
19:17 What I'm saying is that
19:20 the agent is not a witness. The agent is
19:22 not a watcher. Well,
19:25 Anything that stores Key Event
19:28 Logs acts a little bit like a watcher.
19:30 But technically in the way it's commonly
19:32 thought of this is not a witness. This
19:33 is not a watcher.
19:34 That's a separate service that's run.
19:37 Is that what you're asking?
19:38 Great. Okay.
19:40 Did you have a question?
19:44 So a quick demo to answer your question
19:47 to make it clearer what does the
19:49 signing? Let's actually run through a
19:50 wallet. So this is the wallet that I
19:52 made. Let me actually pop over to the
19:54 browser here. What I'm going to do…
19:56 If anybody knows about the Signify React
19:59 TS example repository
20:01 in the WebOfTrust community
20:04 you'll probably recognize this button.
20:06 This is the only thing recognizable from
20:08 back when RootsID originally
20:10 contributed the wallet. I did
20:12 heavy coding with Codex over the last 3
20:14 days
20:16 to get this in this in this state. So
20:17 we've got a heck of a lot more features
20:19 and it looks way better than the old
20:20 ugly one did. I think this is still kind
20:22 of garish, but
20:24 we'll connect.
20:27 I'm going to connect. Now what
20:28 what I'm going to do here is I'm going
20:29 to paste in my passcode. (It's kind of
20:31 hard to see I guess with some of those
20:34 the screen separations there)
20:36 I'm going to paste a passcode in.
20:41 There we go.
20:42 I'll just go ahead and show. This is
20:43 a 21 character passcode.
20:46 Oh, that's fine. This is
20:47 a throwaway passcode. But thank you.
20:49 Good security consciousness.
20:54 Oh, thank you. Yeah. Good point.
20:56 All of that is luckily just dev stuff.
20:59 But thank you.
21:01 You're making me think about
21:05 something I saw on X about a person who
21:08 Oh, yeah, they had a
21:09 a policeman took a picture of somebody's
21:11 Bitcoin private key and it was it
21:13 was on their…
21:15 not even a picture,
21:16 but it was the body cam footage and
21:18 then somebody got like million dollars
21:20 taken out of their Bitcoin wallet or
21:21 something like that.
21:23 But thanks for the security
21:24 consciousness. Luckily, I don't have
21:25 anything worry worrisome in my
21:26 clipboard.
21:29 There shouldn't be. You should double
21:30 check for me.
21:31 [laughter]
21:33 All right. If you find some, let me
21:34 know.
21:36 Now, this generate here. So, by the
21:38 way, this is open source Apache 2 stuff.
21:41 This will generate…
21:43 I'll just make a new one.
21:46 So, and then I'm going to copy and
21:47 paste it so I can reuse it.
21:49 When I connect here, so what's going
21:51 to happen this pass code will
21:52 instantiate in memory a Signify edge
21:54 signing client.
21:56 I'm going to click connect.
21:57 It's provisioning the agent. Now, I've
21:59 got the agent. This is sort of a
22:00 dashboard. I'm going to go to the
22:02 identifiers.
22:03 I have zero identifiers right now.
22:06 The Signify client AID in memory is not
22:09 assigning identifier.
22:11 It's not an identifier that will issue
22:13 credentials.
22:14 I have to create an identifier. So, I'm
22:16 going to click create identifier.
22:18 And I'm going to say… – Is this creating
22:21 one of those [inaudible]
22:23 – This is what? – This is creating one of
22:24 those managed identifiers. – Managed
22:26 identifiers, correct. This is creating a
22:28 managed identifier. I could change from
22:30 salty which is deterministic…
22:33 So, this is if you saw the healthKERI
22:35 demo
22:36 they had
22:37 keychain versus random. Salty is
22:40 essentially random. I'm surfacing some
22:42 terminology that really should be hidden
22:44 from the user. I just went really fast.
22:47 Salty is deterministic, Randy is
22:48 random.
22:50 We could make a delegated identifier
22:52 if we wanted to. I'll go ahead and put
22:53 some witnesses in there.
22:55 And if we would look at the advanced
22:56 options, we can sort of specify signing
22:58 threshold and things like that, but I
23:00 like to hide those options unless you
23:01 actually know you need to use them.
23:03 We created an identifier with
23:07 three… Let me just sort of pop into the
23:09 details here.
23:11 It's a little bit hard to reach from the
23:12 back.
23:14 But this is our AID. This is our managed
23:16 AID. This is not the Signify controller
23:19 identifier.
23:20 The Signify controller identifier just
23:21 connected to the agent. And actually, I
23:23 can I have a page for that. So
23:26 if we go to the client, let's scroll up
23:28 a little bit.
23:30 This shows you some details about what
23:32 we've been talking about so far.
23:35 The controller AID, which is derived
23:37 from my pass code,
23:40 is this AID right here. It delegated to
23:43 the agent AID.
23:45 This is a KERI delegation relationship
23:47 between these two identifiers.
23:49 And here's some more interesting stuff
23:51 about… Okay, the sequence number of the…
23:53 Technically, as you can see, since it
23:55 starts with E and if you know CESR,
23:57 they're both transferable identifiers.
23:59 So you could rotate keys for either the
24:01 controller or the agent.
24:03 And you can see the sequence number that
24:04 the controller's on. We're on sequence
24:05 number 1.
24:07 And so you as you see, (remember how I
24:09 said delegated inception?) the first
24:11 event for the agent is delegated
24:12 inception. You can see the first message
24:14 it's showing in this here is "dip", which
24:16 is delegated inception.
24:18 So this is the little control panel that
24:19 I added
24:21 to show both the Signify controller and
24:24 the delegated agent. I don't think
24:26 there's anything else that we want to
24:27 show here. We created an
24:29 identifier.
24:31 And we can go in there. You can see
24:34 there's a couple interesting things you
24:35 can I can copy the agent out-of-bound
24:37 identifier, which if we curl that, let's
24:39 actually show that.
24:42 I'm going to copy that. We're going to
24:43 go to…
24:45 You can already kind of see where I'm
24:46 going here. Let me zoom in a little bit.
24:50 So what if we wanted to see
24:54 what the Key Event Log is for that
24:55 identifier we just created? Well, we
24:57 copied its out-of-bound identifier,
24:58 what does it look like? If we
25:00 curl that, this is running on my
25:01 computer now. This is a big old honking
25:03 CESR stream. It looks like the Matrix.
25:06 Let's format it so it's a little bit
25:07 easier to read. So, let's do
25:10 pipe it to a little colorizer. I went
25:12 kind of like JQ I wrote for CESR. 2FA
25:15 annotate
25:17 colored
25:19 pretty
25:21 Okay. So, it's a little bit colorized.
25:23 I'll walk through this kind of
25:25 slowly.
25:26 So, you'll see
25:29 this is the inception
25:30 event for the first managed identifier I
25:32 created. It's an inception event. Notice
25:35 it's not a delegated inception event.
25:37 This is a dedicated identifier. That's a
25:40 managed identifier where you use…
25:45 The root pass
25:47 code that you made is like the root
25:49 seed.
25:50 You generate another root seed for this
25:54 managed identifier.
25:55 It's encrypted and then sent to the
25:58 agent and you pull that back when you're
25:59 going to do a rotation for this managed
26:02 identifier. Is that making sense now?
26:05 Perfect. Okay. Any lingering
26:07 question on the relationship?
26:10 – Yeah.
26:13 When I think of the AID, I think of
26:17 entity of some sort. I'm the
26:19 controller. The AID
26:20 is essentially me as a controller.
26:23 The AID of
26:25 the agent is the agent AID Those
26:28 two make sense, but I don't understand
26:29 why you
26:30 why I would have a bunch of managed
26:32 AIDs.
26:32 Like is it In the case of a university,
26:35 am I making…
26:37 I don't know. Like what is the
26:38 use case where… I Why would I have to
26:40 manage
26:42 several
26:43 AIDs?
26:44 – So, it could be that one of your [identifiers]… Let's
26:47 say you're a legal entity
26:49 and one of your identifiers
26:52 is for your legal entity itself. And
26:54 another one might be for you as the CEO.
26:57 Another one might be for a different
26:59 role that you're playing for engagement
27:01 context role credential.
27:10 And it there's a variety of
27:11 different reasons why you might have
27:13 more than one. But generally speaking,
27:15 it's not going to be very many,
27:16 depending on what you're doing.
27:18 – They should all be under the
27:20 the controller's
27:22 jurisdiction [inaudible]
27:24 – I mean it could be. Maybe
27:26 you're working for a corporation and
27:28 they say we want you have an account for
27:29 this and an account for that and have
27:30 different identifiers. It really just
27:33 depends. – Okay, so the root controller
27:36 could be an employee.
27:37 And then
27:40 this company makes
27:42 a KERIA server for their employees.
27:46 And then they [inaudible] people
27:47 or something like that. They have roles
27:50 that might need to communicate with
27:51 other
27:53 entities or something.
27:55 You wouldn't think of the corporation as
27:57 just one Signify controller and then
27:59 managed AIDs per employee.
28:01 You would think of each
28:04 employee at that corporation as having
28:05 their own Signify controller. And maybe
28:08 one, usually probably one, one or more
28:11 managed identifiers.
28:12 Right. And the company would have
28:14 one or more KERIA instances. Yeah,
28:17 that's right.
28:19 Question. – I was just going to make
28:20 a comment on the managed ID discussion.
28:22 We discussed that in a SAID perspective
28:26 as we try to, how do you do,
28:28 prevent cross-context correlation.
28:31 And so we've been looking at managed IDs
28:33 and like all issues.
28:35 I think that's the same scenario we're
28:36 discussing here. We have individuals
28:38 that have multiple managed IDs
28:41 that they can use in different contexts.
28:43 – Oh, for sure.
28:45 Like you could have somebody that says,
28:46 I want my
28:48 whatever SEDI credential with under
28:50 this identifier…
28:51 – Or that the state may issue multiple
28:53 SEDI credentials.
28:57 – I see.
28:58 [inaudible]
29:10 But a credential is not an
29:13 Well, what he's getting at
29:14 is that he's… if I'm understanding
29:16 you right, Chris, is that
29:18 SEDI may allow issuing the same SEDI
29:21 credential to different managed
29:24 identifiers that you have cuz you might
29:25 want to segment, for your own privacy, the
29:28 usage of a given identifier. – So you can
29:30 both issue your AID, managed
29:33 AIDs [inaudible] state for
29:35 endorsement.
29:37 So it's effectively your steady
29:38 credential duplicated
29:40 to whatever level you want to go. – [inaudible]
29:42 your ID from being a main
29:45 [inaudible]
29:49 Okay. So
29:49 So it's like sharding
29:51 your identity. Like effectively
29:53 if
29:54 you know, I might want to have a
29:56 managed ID for my
29:59 university or another one for my
30:02 financials or another one for my
30:05 whatever. Just
30:07 like so sharding pieces of me. Yeah.
30:10 As an
30:12 individual, but as an employee,
30:14 I might shard my identity in different
30:16 ways that are custom to my company or
30:18 my organization or what I'm
30:20 doing.
30:20 – Yeah. That's right.
30:28 – The infrastructure provider for the
30:30 agency configuration:
30:33 What prevents this individual to
30:36 mess with this with the signer
30:39 keys or I guess with the agent because
30:41 it's not [inaudible]. – Good
30:43 question. So, encryption.
30:45 [inaudible]
30:46 Yes. The administrator
30:48 of the multi-tenant agency server
30:52 has access to zero keys. Because the
30:55 keys are always encrypted at rest
30:58 when they're on the agency.
31:00 The only time the keys are unencrypted
31:02 is after they've been pulled to the edge
31:05 client and your master decryption key
31:07 decrypts them.
31:10 Even if somebody
31:12 compromised the server, they could still
31:13 never use your keys.
31:15 – Got it. So, the signing goes up in at
31:17 the edge always. Oh, I thought
31:19 it was at the edge. Okay.
31:22 – It took me a couple of little whiles to
31:23 understand it when I was first learning.
31:26 And what's cool is, you
31:28 learned more quickly
31:30 than I did. It took me a while to really
31:32 track this down and sort of ask the
31:33 right person and sort of figure it out.
31:35 And I didn't feel
31:37 comfortable with it until I read through
31:39 the code to see exactly how it works and
31:41 I could show you exactly where. But
31:43 yeah, all signing happens at the edge.
31:46 Now let's go through some
31:48 of the slides, see if we've got some more ..,
31:50 We've talked about this:
31:52 edge controller signs events.
31:54 Sends to the delegated agent, which we
31:57 talked about is the agent. The agent is
31:59 in KERIA.
32:00 We've got it handles identifiers, all
32:02 these other capabilities that we saw.
32:04 Okay, we have two signing libraries. I
32:07 recently updated SignifyPy to be on par
32:09 with SignifyTS. Yes, the latest version
32:11 of SignifyTS was released yesterday,
32:13 030.
32:15 And the latest version of SignifyPy is
32:16 0.2.0. I should I should re-release that
32:19 just 0.3.0 to be sort of consistent. But
32:23 SignifyPy is updated in actually, no,
32:25 it's 0.4.0. Even worse.
32:27 I got to align the version numbers. So,
32:29 SignifyPy is updated in PyPy
32:33 SignifyTS has been updated in npm as of
32:35 yesterday.
32:36 And what I don't have on the slide here,
32:38 so there's KERIA, the most recent
32:40 version of KERIA has been released at
32:42 0.3.0.
32:44 There's going to be a 0.3.1 very soon
32:47 because while I was preparing for this
32:48 presentation, I found a delegation bug
32:50 or missing feature. And we fit we
32:52 patched that this morning. As soon as it
32:53 gets the PR gets approved, we'll patch
32:55 it in.
32:56 Anyway,
32:58 yeah, that's what we've got: two
32:59 libraries right now, SignifyTS and
33:00 SignifyPy. And Cardano
33:02 has Signify Java.
33:05 They have some clients who wanted a Java
33:07 implementation, so they implemented the
33:08 entire surface area in Java, in case you
33:10 want to know. Now, the Cardano
33:12 implementation has only ever so slightly
33:15 diverged from the WebOfTrust
33:17 implementation. It's very, very close.
33:18 And so it's if you needed the Java
33:20 implementation, it's very doable to, if
33:22 you wanted to, use the WebOfTrust
33:23 standard implementation.
33:26 These are the
33:28 gotchas. This is what's going to
33:30 save you time. And I was okay, so we
33:32 got to be done in 9 minutes here. I want
33:34 to get through all of these and some of
33:35 the config.
33:36 We've been answering questions
33:37 throughout. Please continue to stop me.
33:38 This is where you're going to need to
33:41 come back to me. You or someone on your
33:42 team will have to come back to me or
33:43 somebody from the KERIA community cuz
33:45 you're going to hit these problems.
33:48 What is the passcode? Where
33:50 are the keys stored? And we've
33:51 cleared a lot of these up cuz
33:54 you're going to have to re-explain this
33:56 architecture to every team member. And
33:58 they're going to ask, "Where are the
33:59 keys?" They're going to ask exactly what
34:01 you asked, "Well, what if somebody
34:02 compromises the server? Is that a
34:03 problem?" You're going to have to
34:05 explain to them, "No, the keys truly are
34:07 at the edge."
34:09 It's like it takes some individual
34:11 missionary work to get it between minds.
34:15 And you say, "Okay, what is encrypted
34:17 and decrypted and when?"
34:19 We've already taken care of the major
34:22 misconception or misunderstanding that
34:23 people often have with KERIA. So, you're
34:25 already ahead of the curve.
34:27 And some people ask, "Okay, what about
34:29 storing the passcode? If I'm making a
34:30 web app, can I just store it in indexDB
34:33 or localStorage?" That's a big no-no.
34:36 And the reason why
34:38 is any same origin JS code from you can
34:41 read and exfiltrate that passcode.
34:45 Now, if you want to use something like
34:46 Ionic Capacitor, they do have a
34:49 secure storage plugin that'll work with
34:50 the trusted execution environments or
34:52 other hardware you have on a device.
34:53 It's called the Capacitor secure storage
34:55 plugin. It does not save to indexDB or
34:59 localStorage.
35:01 Now, for a development time convenience,
35:03 sometimes to speed up development, you
35:05 might want to say, "Okay, I want to be
35:06 able to refresh the page." Maybe you
35:08 don't have hot module reloading figured
35:10 out, for whatever stack you're working
35:11 with. If you want to store it
35:13 temporarily as a dev thing to make it
35:15 easy to refresh and not have to recreate
35:17 your state cuz it's annoying to have to…
35:19 I'll show you exactly what I'm talking
35:20 about. I'm going to refresh here.
35:23 And boom, I have to put… I'm
35:25 logged out. I have to go and put my…
35:29 reconnect, which this can be annoying if
35:31 you're doing a ver- a very rapid
35:32 iterative development loop.
35:35 So, as you might you want to say, "Well,
35:36 when I refresh, I want to deep link and
35:37 go back to that deep link so that I can
35:40 quickly develop."
35:41 If you want to add that in a development
35:43 time, that's okay, but don't let it go
35:44 to prod. Do not let that go to
35:46 production.
35:48 And use the secure plugins if
35:50 you're going to use something like Ionic
35:51 Capacitor.
35:53 Where are the keys stored? We beat
35:54 that one to death. We know that Signify
35:56 controller key is the edge encryption
35:59 key and delegation key only.
36:01 AID root salts
36:04 that are only ever unencrypted at the
36:06 edge, which is where all signing
36:07 happens. You can just think of it as an
36:09 HSM.
36:11 And when they are stored in KERIA,
36:14 they're encrypted.
36:15 They're encrypted before they're even
36:16 transmitted.
36:19 Okay, the other biggest one, you're
36:21 going to forget this. I forgot
36:23 this a couple times in the last couple
36:24 of days.
36:26 You need “KERI_AGENT_CORS=true”
36:29 so that it properly responds to
36:31 preflight requests, the preflight
36:32 options requests.
36:34 So, make sure when you're viewing your
36:36 “keria start”,
36:38 whether you're starting in a
36:39 Docker container,
36:41 whether you're running it local… just the
36:43 regular raw Python virtual environment,
36:45 you need “KERI_AGENT_CORS=true”.
36:47 You put that as environment variable in
36:49 your in your CI scripts, in your
36:51 deployment scripts.
36:53 We really should just make this the
36:54 default behavior. I need to do a PR to
36:56 make that the default behavior. I mean,
36:57 I don't know anybody that doesn't deploy
36:58 this way in production, so we'll
36:59 probably make that the default so that
37:01 you don't hit that over and over again.
37:04 Okay, multisig. How is multisig handled?
37:07 Multisig in KERIA is just like it is in
37:11 heavyweight wallets KERIpy
37:14 with the exception of
37:16 what transmit the messages. What's the
37:18 mailbox?
37:19 When you're doing multisig, you need to
37:21 know how to communicate with each
37:23 member, which means you need to know
37:25 where their witness or whatever's acting as
37:27 their mailbox is so that you can send
37:29 them your multisig notifications.
37:31 In KERIA, that's your agent or their
37:34 agent.
37:36 Other than that, it's the same.
37:38 There was one I said there's a
37:39 delegation but there let's see. Let me
37:41 think about
37:42 There has been some I'm trying to think
37:44 of some bugs we've had over the last
37:45 year. Yeah, for all intents and
37:47 purposes, it's the same except for it
37:48 goes through the agents instead of a
37:49 witness.
37:51 Okay.
37:53 Okay, this is the only the other thing.
37:54 So, we're looking at 5 minutes. Good.
37:56 We'll be done with KERI config. Okay. I
37:58 do have a blog post that goes through
38:00 this pretty exhaustively. So, if you go
38:02 to kentbull.com
38:04 /posts/configuring-keripy-keria-controllers-witnesses/
38:08 You can go there. It's just
38:10 kentbull.com right there that post.
38:13 And I go in detail, but we'll quickly
38:14 walk through the most important parts of
38:16 a config file.
38:17 If you want to start up a KERI agent
38:19 server, you need a config file that has
38:22 at least the date property.
38:24 And one other thing
38:26 you must have this block right here with
38:29 the curls, which is controller URLs, cuz
38:32 what happens is it takes this value and
38:34 binds to that port.
38:36 And this name right
38:38 here matters.
38:40 Let me go forward to that.
38:44 This name has to correspond to the name ..,
38:47 when you do “keria start --name "keria",”
38:48 these two names need to match up.
38:51 That's the hardest part.
38:53 And then the other hard part is
38:55 that you must have a value here so
38:58 that it can pull out the host and the
38:59 port to bind to that port. That's what
39:01 Python reads to do the port binding.
39:04 As long as you've got the port open, the
39:06 host right, you can use 0000 if you need to.
39:09 And these names match, then you're good
39:11 to go.
39:12 Now, the other parts of the config, you
39:13 might say, "What would I use
39:14 the other parts for?" So, IURLs are
39:16 essentially identifier or AID URLs.
39:19 Who are the contacts
39:21 that I want to resolve on startup for
39:23 every single agent? Cuz this config is
39:27 the agency config.
39:29 The way that config works in KERIA is
39:31 you configure the agency,
39:33 and then it copies its config to every
39:36 agent. So, if you want to bootstrap ..,
39:39 Let's say you have preferred
39:40 witness infrastructure and preferred
39:42 credential schemas that you want every
39:45 agent in your agency to know about, you
39:47 put them in your IURLs section, and
39:49 there's actually a DURLs section
39:51 specifically designed for credential
39:54 schemas and partial ACDCs. Like if you
39:57 have a trust chain like the GLEIF trust
39:59 chain, and you want your agents to
40:01 pre-resolve it,
40:02 there's an IURLs
40:04 section for identifiers, and you'll
40:05 notice
40:07 these are all witnesses. So, what I'm
40:08 saying is I want every single agent
40:13 that boots up here to resolve these
40:15 three witnesses so that I don't have to
40:17 through the steps of resolving them
40:20 every single time.
40:21 Anyway, so there's some tocks. This is
40:23 some more some more advanced stuff if
40:25 you need to do some CPU tuning and IO
40:26 tuning. This is where you're getting
40:28 more low-level into the async. So,
40:30 tomorrow I have a talk, HIO async
40:33 frameworks. It's even lower level
40:34 than this. This is where we'll get more
40:36 into tocks, but this is more into the
40:38 KERIpy
40:41 async framework called HIO, hierarchical
40:44 IO that Sam [Smith] designed. That's what these
40:46 are refer… As long as you know
40:47 what it's for
40:48 that's enough to sort of start to ask her
40:50 off and that sort things. Okay.
40:52 We kind of understand
40:55 why to use KERIA. Use KERIA when you
40:57 need a lightweight wallet. KERIA is
40:58 signified when you need a lightweight
40:59 wallet. When to not use KERIA? When
41:01 you need a heavyweight wallet.
41:03 [laughter]
41:05 And we talked about configuring. Now, go
41:07 build your AI agents with security
41:10 behind them and your steady agents.
41:13 [applause]