0:00 Fergal O'Conner | Signify Security Architecture | KERI Conference 2026
0:02 So hello everyone and welcome. My
0:04 name is Fergal O'Connor. I'm the identity
0:07 solutions lead architect at the Cardano
0:09 Foundation. I've been there for the last
0:11 four years now helping out build out
0:14 our open-source identity solution known
0:16 as Veridian.
0:18 Last year we launched the first
0:23 mobile wallet in the KERI/ACDC
0:25 ecosystem to production. This is a
0:28 production-grade mobile identity
0:30 wallet. It's gone through security
0:32 auditing and pentesting. And in
0:34 general we put a lot of effort into the
0:37 user experience of this wallet and how
0:39 we could bring KERI and ACDC to the
0:42 masses and make it more accessible.
0:43 The wallet itself is based on
0:46 KERIA and Signify-ts. And throughout
0:49 the years, we've put a lot of
0:52 effort into contributing to KERIA and
0:54 Signify-ts in the open source community.
0:56 Particularly because we were trying
0:58 to bring in this extra user experience.
1:00 There was kind of gaps in the existing
1:02 software that was required to deliver
1:04 that user experience we wanted. And
1:06 also some kind of security edge cases
1:09 kind of operationally that we had to add
1:11 in, to align with our pentesting.
1:15 Today I'm going to be going over
1:17 kind of the security architecture of
1:19 KERIA and Signify-ts. This is in the
1:21 advanced track so we'll be quite
1:23 technical. I think it's generally
1:26 okay if you have kind of a background in
1:28 into KERI but some parts might be
1:31 a bit low level.
1:36 Now, the first tagline I want to
1:38 start with is: KERIA is a cloud agent
1:41 In the KERI ecosystem.
1:43 And kind of in line with everything
1:45 that Sam [Smith, red.] was speaking about this
1:47 morning, I put the tagline
1:49 here of “Agent in the cloud, controller at
1:51 the edge”. So just because you're
1:52 using a cloud agent doesn't mean that
1:54 you give up control of your keys.
1:56 So if you have a mobile wallet which is
1:58 using a cloud agent based on KERIA
2:00 your keys will always do the signing at
2:02 the edge on your phone. And I
2:05 also took this snippet
2:08 directly from the KERI specification.
2:11 Sam defined that a controller
2:13 application needs to do five functions.
2:16 This is keypair generation and
2:18 storage, key event generation and
2:20 signing and key event validation. Of
2:23 course this is at the lowest level of
2:24 KERI. It doesn't talk about higher
2:26 level protocols such as ACDCs or OOBIs or
2:29 IPEX and so forth. But if you have
2:32 that controller application with those
2:33 five functionalities. You can,
2:37 if you wish, split it across two kind
2:40 of software deployments of a controller
2:43 application on the left and a controller
2:45 agent on the right. So KERI is your
2:47 controller agent. The split here is
2:50 that your controller application, say
2:52 your mobile wallet will have to do
2:54 the keypair generation, key event
2:56 generation and signing. And then your
2:59 controller agent in the cloud can do
3:01 keypair storage and key event validation. Now
3:03 the keypair storage of course has to be
3:05 encrypted because your agent cannot
3:07 access those keys because that would
3:09 break everything. And I think also
3:12 with this diagram you could put the
3:13 keypair storage in either side that works
3:15 in the setup of the deployment.
3:17 But critically the key event validation
3:20 is pushed to the agent in the cloud.
3:22 Okay. So particularly when you start
3:24 adding in other protocols such as
3:25 ACDCs and so forth, you're pushing all
3:28 of this complex validation logic that
3:31 must be spec compliant and so forth
3:33 to the cloud and abstracting away the
3:35 details in a way that your controller
3:37 applications can be a bit more
3:38 lightweight at the edge. All you have to
3:40 do is sign some events, essentially, and
3:42 not do all of the complex validation.
3:44 Okay. So today we're going to cover
3:48 kind of three areas.
3:50 First and foremost the kind of
3:52 service architecture of KERIA and Signify
3:54 How it works in general. Then
3:57 we'll delve a bit deeper into the trust
3:59 relationship between the cloud and
4:01 edge. What keys live where you know
4:04 what must be signed to establish this
4:06 trust relationship and so forth. And
4:08 then finally to wrap it all up
4:12 we'll see and explore how to use KERI
4:14 to interact with the rest of the world
4:15 once you set this up.
4:19 So on the service architecture…
4:22 As an overview before we get into the
4:24 diagrams:
4:26 KERIA is of course a KERI agent in the
4:29 cloud. It's based on KERIPy directly.
4:32 So is the Python service that uses
4:34 KERIPy as a direct dependency. Most
4:37 of the complex validation is from KERI
4:39 core. It's essentially an orchestration
4:41 unit wrapped around it. It's a multi-
4:44 agent service. So it allows you to
4:47 provision many agents for many
4:50 controllers
4:52 and kind of to summarize it's a set of
4:55 HTTP endpoints essentially for
4:56 controlling these agents. So
4:58 provisioning them utilizing them and
5:00 to interact with the rest of the world.
5:03 Signify on the other hand is your edge
5:05 client library. This is what your
5:06 controller application would use.
5:09 Again the main idea here is to sign at
5:11 the edge. I believe in the early days
5:14 people were going to call Signify 'KATE':
5:18 “keys at the edge”. They stuck with
5:20 Signify however. But it's essentially
5:22 just
5:23 basically like an API wrapper around
5:26 KERIA. Except they can do this key
5:28 event generation and signing as well.
5:31 So it understands bits of CESR and so
5:33 forth. The relationship is: for every
5:36 edge client there is one cloud agent,
5:38 a direct one-to-one mapping. And it's
5:41 available in multiple languages. So
5:44 within the WebOfTrust the two complete
5:45 implementations are Signify-ts in
5:47 TypeScript and SignifyPy. I don't
5:50 believe SignifyPy is used in production
5:52 but Signify-ts is used by most people in
5:55 this ecosystem, to be honest, that aren't
5:56 building directly on KERIPy. In the
5:59 Cardano Foundation we've also built a full
6:01 Java implementation of Signify. It's
6:04 fully feature complete. That's
6:06 actually been used internally at the
6:08 Cardano Foundation and a number
6:10 of other projects that we're working on
6:13 which have actually gone to
6:14 production.
6:15 And in general one nice thing about
6:18 Signify is that right now it gives
6:21 you a higher level API that is more
6:23 accessible to actually utilize KERI.
6:26 So if you were to build directly on
6:28 KERIPy there's a steep
6:30 learning curve to understand how it
6:31 works internally. And it would be
6:33 very easy to go wrong. Whereas with
6:35 Signify the API is a bit more like:
6:38 create this identifier, create this
6:40 ACDC registry, issue this credential.
6:43 I think having that higher-level API
6:45 also brings much more accessibility to a
6:47 wider audience for adoption and
6:50 because it's available in multiple
6:52 (programming, red) languages that also makes things
6:54 easier. I'm not going
6:56 to say it's super simple to add new
6:58 languages for Signify but it's much
7:00 more trivial than porting KERIPy to
7:04 various languages.
7:06 So if we to look at this
7:09 overview diagram of KERI is here in the
7:11 center as I mentioned it's a multi-
7:14 agent service. So we have agents A, B and
7:16 C.
7:18 Each agent has its own fully isolated
7:20 database. These databases are mostly
7:23 provisioned by KERIPy. They're a set of
7:24 LMDB databases but they're fully
7:27 separated
7:29 and for each agent you have exactly one
7:31 Signify client and they have a secure
7:33 API between them. Okay. So client C
7:36 cannot talk to agent B.
7:40 All of your state will be held in the
7:42 cloud. Signify is completely stateless
7:45 except for the key material that you
7:46 give to generate and derive the keys.
7:50 All signing happens at the edge. So
7:53 Signify will push signed events up into
7:55 KERIA and your agent will you know do
7:57 whatever with that. It'll make propagate
7:59 it to witnesses send an exchange
8:01 message to a verifier or so forth.
8:04 And all interactions with the rest of
8:06 the KERI network. So agents,
8:07 witnesses, watchers, controllers and so
8:08 forth, all happen via KERIA. And
8:12 these will all be direct CESR inbound
8:14 and outbound streams. So the Signify
8:17 clients will never talk directly to the
8:18 other agents, witnesses and watchers.
8:22 It's always through your agent directly.
8:26 And if I take that diagram and maybe
8:28 zoom in a little bit on KERIA.
8:32 Again we have the three clients and
8:34 three agents. Each agent has its
8:36 isolated database,
8:39 and KERIA itself is a set
8:41 of HTTP endpoints. So there are three
8:44 endpoints 3901, 3902 and 3903.
8:49 The last one 3903 is used to provision
8:54 new agents. Okay. So if you come along
8:56 if say Signify client D installs a
8:59 wallet on their phone which uses Signify
9:01 and they go through the onboarding
9:03 process, they'll be able to provision
9:05 a new agent through this endpoint
9:08 which will set up all the database and
9:10 so forth. And that endpoint uses the
9:12 the “agency” it's called internally, and
9:15 the agency has its own database to track
9:17 you know which client relates to which
9:18 agent, which identifier that was
9:21 created by a client relates to which
9:23 agent.
9:25 It's pretty small, to be
9:27 honest. This port 3903 in production
9:30 shouldn't be left open because
9:33 otherwise you could just write a loop
9:35 and keep provision new agents with more
9:38 databases. So in Veridian we completely
9:42 block that port from public access
9:44 and we have one-time boot URLs that
9:48 are sent by emails to protect the
9:50 infrastructure.
9:52 Once the client is onboarded in and
9:54 they have their agent up and running
9:55 within KERIA in the service they can
9:57 then use the 3901 port on the top left
10:00 which is the admin API. This is just
10:02 a set of REST endpoints, create
10:05 identifier issue ACDC and so forth.
10:07 It's completely
10:09 authenticated. So of course only one
10:12 client can talk to one agent. We'll
10:14 see more on that in the coming slides.
10:18 And then your agent, it
10:20 might be talking to other nodes in
10:23 the KERI network to say "propagate
10:25 events for witness receipts", and so forth
10:28 or send an exn message. Like
10:31 everything in the KERIA implementation,
10:32 everything's async. So the response will
10:35 often come back in on a different port.
10:38 When it comes in, it'll come on to the
10:40 message router. And the message
10:42 router will based on the headers
10:45 it'll look up in the agency: "okay, someone
10:48 external is trying to talk to this AID
10:50 which agent should I route to", and it'll
10:52 route to the correct agent and they'll
10:54 parse the incoming CESR stream
10:56 using that database specifically.
11:00 So that's kind of generally
11:01 operationally how it works and again
11:04 just to recap there are three different
11:06 ports. The boot port is used to
11:08 provision new agents. The admin port
11:10 serves all the rest endpoints for the
11:12 clients and the external 3902 port is the
11:15 CESR endpoint for inbound
11:17 interactions; okay? So
11:21 if we to delve a bit deeper into the
11:23 trust relationship between KERIA and
11:25 Signify. So, you've onboarded
11:28 into the system but how do you actually
11:29 authenticate on that API?
11:32 I created this sequence diagram here.
11:36 It's probably going to be the most
11:37 technical part of the talk. On the
11:40 left we have the Signify client and
11:42 here we have the two ports that the
11:43 client uses: the boot port and the admin
11:46 port. I don't know how clear it is to see
11:48 there but there's a blue box there in
11:50 the top left which is the boot
11:53 sequence to provision a new agent
11:56 So,
11:58 Signify itself is completely stateless
12:00 except for a passcode that you must give
12:03 it; okay? This passcode is used to
12:06 derive key material. It's a 21-
12:09 character salt essentially, in the
12:13 CESR base64 URL variant.
12:16 Signify has an API to generate these
12:18 passcodes or they can be generated
12:20 externally. It doesn't matter. Yeah, you
12:22 just pass it to Signify when you're
12:23 connecting, booting or connecting to the
12:25 API. This 21-character passcode,
12:29 which is a salt, then gets stretched
12:34 in a hierarchal-deterministic way using a
12:37 path and the Argon2id function.
12:41 This allows you to drive
12:44 keys, ed25519 keys specifically.
12:48 At index zero, you get your first
12:50 signing key. Index one you get your
12:52 rotation key. These two keys
12:55 together you can use to generate an
12:56 inception event for your client AID
12:58 which I've called 'CAID' here. So this
13:01 client AID will be used by Signify to
13:04 communicate with KERIA and to
13:06 authenticate on the endpoints. It's
13:09 KERI 'direct mode', there are no
13:11 witnesses because this is directly
13:12 between client and agent. This client
13:15 AID is not used to interact with the
13:17 outside world. It's only used to
13:19 authenticate on that endpoint in
13:22 KERIA. So once you've generated
13:25 the inception event for the client AID
13:27 (you of course sign it with your signing
13:29 key) and then you send the signed
13:31 inception event on the boot port.
13:35 Once KERI receives this if it's a valid
13:37 inception event it will provision a new
13:38 agent. So it'll set up all of the
13:40 databases. It'll generate a salt for
13:42 that agent in the cloud because the
13:44 agent itself also needs its own AID.
13:48 And this AID which is a AAID here, agent
13:51 AID is actually a delegated identifier.
13:54 Okay. So it's delegated back to the
13:55 client AID. So there's this kind of
13:57 tight connection between the two AIDs.
14:01 And it'll send that back in the
14:03 response and because it's delegated and
14:05 KERI uses cooperative delegation. The
14:08 Signify client will need to approve of
14:09 the delegation and send that back the
14:12 approval event which is just an
14:13 interaction event essentially which
14:15 contains the delegation seal. The
14:19 main reason you would do delegation here
14:21 is because Signify is completely
14:23 stateless. You know it can't remember on
14:26 its own what agent the ID was talking to
14:29 that it set up with initially. But if
14:32 KERI can give you back all of your
14:33 Key Event Logs and it can verify it, it
14:36 has proof within its own Key Event Log
14:38 that it the agent AID was the one it
14:39 created this kind of trust
14:42 relationship with. I don't think Signify
14:44 does that yet, but it could.
14:47 Yeah. One thing I've conceptually been
14:49 confused about is that and you probably
14:51 just explained it, but I needed to hear
14:53 it again. Is who's
14:56 delegating to whom and what is being
14:59 delegated? You probably just said it,
15:00 but I need to hear it again. And is for
15:03 just that event or is there delegation
15:05 used later, beyond ...?
15:06 Well, when you create a delegated
15:08 identifier in KERI, it essentially
15:10 means this identifier is not valid until
15:14 the other identifier approves it. So
15:16 they put essentially the AID of the
15:20 delegator inside their KEL in a seal in
15:23 a new interaction event. And now every
15:25 time the agent ID would want to do a
15:27 rotation event, the rotation event is
15:29 not valid until the Signify client
15:31 approves it. Okay, so it's like a
15:33 two-step approval. GLEIF use this with
15:36 QVIS for example. So if a QVI rotates
15:38 its keys, GLEIF has to approve it for that
15:40 rotation event to be valid. So
15:42 cooperative delegation and KERI is just
15:44 another security mechanism essentially.
15:46 But once that delegation is done,
15:47 then the agent can sign for the
15:52 controller for something. No, no,
15:54 no, no. It's not a delegation of
15:56 authority. That would be more like
15:58 issuing ACDC to someone.
16:00 Cooperative delegation is a security
16:02 mechanism essentially for rotation
16:03 events.
16:04 Okay.
16:04 It also for superseded recovery where
16:07 you can like step back in the KEL and
16:10 fork like recovery. It there's the
16:14 mechanisms in which that's allowed are
16:16 much stronger, much more powerful in
16:17 delegated identifiers. So delegated
16:19 identifiers are for security
16:20 essentially. Yeah, it's cooperate
16:22 delegation. But in this case, it also
16:24 has the nicity of the Signify client
16:26 knows it should be talking to this agent
16:28 AID. It has proof that's who it
16:30 should be talking to. So at this
16:34 point you essentially have your agent
16:38 fully provisioned and fully ready in the
16:40 cloud. And you have your stateless
16:42 client which just has your 21-character
16:46 passcode which in the code is also
16:48 called a brand but yeah, there's
16:50 different naming everywhere. At this
16:53 point, this is only needs to be done once,
16:55 you can now use the other
16:57 endpoint to do whatever you want to do
16:59 create identifiers, issue ACDCs, and so forth.
17:02 Now the first thing you need to do
17:04 because of stateless is to fetch the
17:06 state of the KELs for direct mode. So
17:09 it fetches both the KELs of each of them
17:12 And the sequence number of the
17:13 derivation path that way it knows how
17:18 to derive the keys again for its current
17:20 signing key. So on your client AID if
17:22 it did a number of rotations once it
17:24 starts up again it needs to initialize
17:26 itself with the state and this is an
17:28 unauthenticated endpoint because it
17:30 doesn't know what key to generate yet.
17:34 Once it has done that and derived its
17:36 current keys it can create HTTP requests
17:40 on the REST endpoints
17:42 And fully sign them with the client
17:44 AID and the responses will be fully
17:46 signed by the agent AID. So,
17:50 we're not using bearer tokens here.
17:51 The HTTP requests are signed back and forth.
17:56 Does that make sense? Any questions?
18:07 I won't explain this, cuz I might run out
18:09 of time, but the passcode that you use
18:10 to boot you can rotate that full
18:14 passcode. So you can switch to a new
18:16 salt essentially. This functionality
18:18 exists in KERI and Signify already.
18:21 The reason you might want to do that is
18:22 because you might think your passcode's
18:24 exposed. Now, if it's fully exposed,
18:26 you're already gone. But let's say
18:28 you have a time window to recover from
18:30 that. You can actually rotate the
18:31 passcode. How that's done, I won't
18:35 explain right now. I'll do it at the end
18:36 if I have time. This QR code, suppose
18:39 you might be able to see that work
18:41 is a link to the markdown file from Phil [Feairheller, red.]
18:44 in the repository.
18:46 Which explains everything I just
18:47 explained this and everything I'm about
18:49 to explain quite clearly. If you want
18:53 to look at it after
18:57 finally one other thing that I want to
19:01 mention is
19:02 so I just said that the HTTP requests
19:04 between the client and agent are fully
19:07 signed. They use an RFC 9421.
19:12 Okay, so this is an existing standard
19:14 outside of KERI.
19:16 It's just been slightly adapted to
19:17 KERI, which just means the key that you
19:19 should be using for signatures is the
19:21 latest key state of the KEL essentially.
19:24 This is the in-vanilla Signify-ts
19:28 and KERIA; this is how you how you do it.
19:32 I have an open PR for ESSR support. I
19:35 think Phil mentioned ESSR in the last
19:36 talk.
19:40 On our fork of Veridian. We've been using
19:42 ESSR for yeah I don't know the last like
19:46 14 months or something. The problem with
19:48 the signed-header approach is that you
19:50 have your authenticity because
19:52 everything's signed by the AIDs but you
19:53 don't have your confidentiality. You
19:54 have to lean on TLS. So if the TLS
19:57 connection was compromised, you lose
19:59 confidentiality. Whereas with ESSR
20:03 it's
20:04 basically your best way of combining
20:08 authenticity and confidentiality. So
20:10 sign -, combining encryption and digital
20:12 signatures.
20:14 It's what is used by SPAC and the
20:18 trust spanning protocol. So Phil [Feairheller, red.]
20:21 implemented it in KERIPy. We've
20:23 extended it down to the API between
20:26 Signify and KERIA. It looks
20:29 something like this. I won't
20:31 spend too long on this, but it's
20:33 designed with Sam [Smith, red.]. It's
20:35 like a HTTP request tunneling kind of
20:39 thing. So the green at the top left is
20:43 the original request
20:45 Which we would send say
20:48 HTP request for put 'slash' identifiers with the
20:51 body and the headers and so forth.
20:54 We serialize it into a HTTP string
20:57 and then we do a cryptobox seal
21:01 with Libsodium to encrypt it to the
21:03 agent AID. So only the agent can decrypt it.
21:07 Cryptobox seal is a form of
21:11 hybrid public key encryption. So for
21:14 those of you
21:16 who are aware, asymmetric keys are
21:18 incredibly inefficient at encrypting
21:21 data. it's just not really feasible.
21:24 Symmetric keys are much quicker.
21:27 The crypto box seal from Libsodium
21:30 is a form of hybrid public key
21:31 encryption which uses your asymmetric
21:33 key to derive a symmetric key
21:36 essentially. I don't know the internals
21:38 of it, but it's what SPAC uses.
21:42 This sealed box then can become the body
21:45 of a new request which we send to this
21:48 post 'slash' endpoint.
21:50 So when we do this, every request that's
21:53 sent from Signify client, nobody knows
21:55 where it came from. They don't know what
21:56 we're even trying to do. They don't know
21:58 that we're trying to update an
21:59 identifier because it's going to post.
22:01 Only the agent will be able to decrypt
22:03 it. And in the headers, we put a
22:06 signature over this, essentially. Now,
22:08 the signature needs to be over the
22:10 digest of the body, a timestamp for
22:13 replay-attack protection, and the sender
22:15 and receiver AIDs.
22:18 And additionally in encrypt sender sign
22:20 receiver, you also have to encrypt the
22:22 sender. That's why the sender is also
22:24 a header of the original request which
22:26 was encrypted. Only then are
22:29 you fully secure from all the attacks
22:31 that Sam (Smith, red) mentions in his SPAC paper.
22:40 Okay. So
22:40 yeah we've gone over the general
22:41 architecture and also gone through
22:45 the trust relationship. Now, finally,
22:46 the last kind of piece to tie it up will
22:48 be how you use KERIA to interact with
22:50 the rest of the world. Up until
22:52 this point, you've basically installed a
22:54 wallet and onboarded onto your cloud
22:56 agent and done nothing else.
22:59 The first thing you'll probably do
23:05 is create an identifier, maybe resolve a
23:08 OOBI, but probably create an
23:09 identifier. In the codebase these are
23:12 known as managed AIDs because the client
23:15 AID we created earlier is only used
23:17 indirect mode to talk to your agent.
23:20 It's only for that communication.
23:21 It's not used to receive credentials,
23:23 issue credentials or anything else.
23:29 We can use the '/' identifiers endpoint on
23:33 KERIA to create managed AIDs. And
23:37 these are,
23:39 well, they may be private or public
23:40 bur these are AIDs you would use to interact
23:41 with the rest of the world or use in
23:42 your use case, they're more user facing.
23:44 But once again the keys remain
23:47 at the edge. Now this is a bit
23:51 technical but for those of you
23:54 who know KERIPy: In KERIPy you
23:58 have a 'Hab', which represents an AID and
24:02 you can incept a Hab and you can sign
24:04 with a Hab and so forth. You can have
24:05 group Habs. Also within KERIPy
24:08 there are Signify Habs and Signify group
24:09 Habs. It's just so the code knows that
24:11 the keys are not readily available. The
24:14 keys exist somewhere else at the edge.
24:16 So if you see that in the code that's
24:18 why it exists. Now,
24:22 you might be asking where did the keys
24:23 come from?
24:25 Maybe a naive approach would be to use
24:31 the passcode that we used to create the
24:32 client AID and derive more keys.
24:36 That would be problematic because of
24:39 passcode rotation and it also would go
24:42 against what Sam said this morning of
24:43 being able to use just your KEL to
24:45 derive exactly which sequence number
24:48 on the derivation paths is required.
24:52 So actually for
24:55 for each new AID you actually create
24:57 a new salt. They're fully
24:59 separated.
25:01 It's of course randomly generated by
25:03 Signify at the edge. And it's stored
25:07 encrypted on KERIA. This is the default
25:09 mode in Signify.
25:14 It's of course encrypted with the client
25:18 AID. And you have a salty keeper
25:19 which tracks
25:21 you know, for this AID, what encrypted
25:23 salt does it have, what derivation pad
25:25 is it currently on, how many rotation
25:26 events is done, and so forth.
25:30 The main reason you would want to split
25:32 these is if you did a passcode rotation
25:34 and your one passcode had all your keys
25:36 for all of your identifiers when you
25:38 want to rotate that passcode for
25:40 whatever reason, you would have to issue
25:42 a rotation event for every single AID.
25:44 And that would get very cumbersome as
25:46 well if you also had group AIDs. You had
25:48 to coordinate that. So this way there's
25:50 a kind of a clean separation kept from them.
25:54 You can also .., I think Phil had this in
26:00 his last presentation as
26:02 well, you can also use' Randy', which
26:04 means, just instead of a salt, which is
26:06 used to be stretched with argon 2 ID
26:09 to generate keys, you can just randomly
26:10 generate keys directly and store them
26:12 encrypted in KERIA; same idea.
26:16 this is kind of goes back to that first
26:18 slide I had where from the spec that
26:20 your keypair storage can be done
26:22 by your agent.
26:26 Now in case you don't want to sign with
26:29 Signify.
26:48 In case you don't want to sign
26:50 with Signify or expose your salt
26:52 over the internet like that, you can
26:54 also use an external source for
26:56 signing such as a HSM. This, I
27:01 believe there's a current open
27:03 PR in the community to fix that on
27:06 KERIA. But you can use HSMs and
27:09 directly sign all of your key events
27:12 externally.
27:15 Now once you've created an identifier so
27:17 you would generate that
27:19 inception event generate the salt
27:21 whatever post that to KERIA,
27:24 to communicate with the rest of the
27:25 world you would need to generate an
27:27 OOBI. So each managed ID can now set up
27:29 their OOBI. This is probably going to
27:31 get a bit technical now but
27:35 if you know how OOBIs work this will
27:36 make sense. If you don't, this is
27:38 probably too much information, but in
27:41 KERI nodes or whatever can have
27:44 various roles in the system such as
27:46 witness, watcher, agent, controller.
27:49 If you were to build a wallet with just
27:52 just KERIPy and not have the split of
27:54 controller, agent, your OOBI would look
27:57 something like, you know, /OOBI,
27:59 your AID/controller.
28:01 Okay, you have the controller role by
28:03 default over your AID. But there are
28:06 other roles in the ecosystem.
28:10 One is Agent of course. So you may
28:14 As the controller of your managed AID
28:18 authorize your agent in KERIA to
28:22 act on your behalf in the agent role
28:24 essentially. So this indicates to
28:26 everyone else in the world if you want
28:28 to talk to me, direct all traffic to
28:31 the agent. The agent will handle that
28:33 essentially and this is called an
28:35 endroll authorization.
28:40 Again, this is a bit low level, but the
28:42 agent itself needs to say where its
28:45 endpoint is which is the two 3902 port.
28:48 it needs to create a signature over that
28:50 to commit to say "I'm at this URL" Veridian.id,
28:55 or whatever. That's called a location
28:58 scheme in the code
29:01 And additionally
29:07 another thing that came out of our
29:08 pentest was actually securing the
29:10 communication not just between the
29:11 Signify client and the agent but
29:14 agent to agent.
29:17 What we've implemented on our fork is
29:21 we've added full ESSR support that's
29:23 also in line with SPAC and the trust
29:25 banning protocol. So all of the CESR
29:27 streams inbound and outbound
29:31 essentially wrapped in the most basic
29:32 form of the trust spanning protocol.
29:35 The work for that in KERIPy I merged a
29:39 while ago with Phil that's done. The
29:41 KERI work I still need to open a PR
29:43 for but we'll be contributing that
29:45 back soon. And finally, this is
29:50 probably the most technical part, but
29:52 this is only if you understand OOBIs. If
29:54 you don't, then it's probably too
29:56 much, but just to kind of show the
29:58 relationship between all of the AIDs
30:00 that we mentioned today. There's
30:03 kind of six slots here. The top
30:07 one is a managed ID I created using the
30:10 admin endpoint. This is its key
30:14 event log. So it ends in two 'z's
30:17 that's its AID. It has the three demo
30:21 witnesses from KERIPy. These are
30:24 the signatures and the witness receipts.
30:28 If you look at the very bottom I give
30:31 the end-roll authorization
30:34 from
30:36 my controllerAID that ends in two 'z's
30:39 to this endpoint AID that ends in 'XA'. I
30:42 gave it the role of agent.
30:46 So this over here, see the cursor?, Yeah,
30:50 This is my managed AID. This is my
30:53 cloud agent 'XA'.
30:57 I can also see that my cloud agent here.
31:00 It signed a location scheme to say you
31:03 can find me at this URL and no other
31:05 URL. That's how OOBIs work. It's very
31:07 very particular.
31:12 If you look at the
31:17 one up
31:21 here, this is the Key Event Log of the
31:23 agent. You can see it's a delegated AID.
31:25 It's delegated to this AID here, which
31:28 is my client AID from the initial
31:30 sequence diagram. The second one is my
31:33 client AID KEL. And here's the
31:35 interaction event that approved the
31:36 delegation. So you can actually look in
31:38 the KEL and see the full kind of
31:39 sequence of what I mentioned end to end
31:42 essentially. But yeah, that's
31:46 all I had. I think I have seven more minutes
31:52 So I will very quickly go back to this.
32:06 When we created the client AID, it had
32:08 a signing key and a rotation key
32:11 on sequence number 0.
32:14 If you were to drive more keys and do
32:16 a rotation event on that same passcode,
32:18 it would just look like a normal
32:19 rotation event where the next key
32:21 becomes the current key and there
32:24 would be a new next key that's blinded
32:25 for postquantum security. But if you
32:28 want to switch from an old passcode to a
32:32 new passcode, okay, in such a way that
32:34 you don't need to remember the old
32:35 passcode when you're done and you don't
32:38 want to because someone's going to
32:40 compromise it,
32:42 then you need to generate your new
32:44 signing key and new rotation key on the
32:47 new passcode. All right, so here's the
32:51 rotation key hashed from the new
32:54 passcode. Here's the one
32:57 from the new passcode as well. And
33:00 here's the unblinded one from the old
33:01 passcode. So if you issue a rotation
33:04 event, you have to unblind a threshold
33:07 amount of next keys from the previous
33:09 event. So this one from the old passcode
33:11 has to be here. Otherwise, it's not a
33:14 valid rotation [red.] event. And this or a
33:16 rotation event, sorry. And this rotation
33:18 event has to be signed by both of these
33:20 keys. Okay? Because each new event
33:23 has to be signed by a threshold number
33:25 of new signing keys. And it also
33:30 needs to be signed by a threshold amount
33:32 of previous rotation keys. So,
33:36 that's why it needs to be signed with
33:37 both of these. And the trick here
33:41 is if you look at the threshold, the
33:43 threshold is splitting away 1 and 0.
33:46 So the old passcode even though
33:49 the key is inside the rotation event, it
33:51 has no authority from this point on. It
33:53 has a weight of 0. It can do nothing
33:55 essentially. But it just fits the
33:57 validation logic of rotation events but
33:59 completely gets rid of the old passcode.
34:01 Okay. So it's kind of a it's a partial
34:03 rotation, essentially, for a single-sig identifier,
34:06 which is kind of unique.
34:08 Yeah that's it. Any questions?
34:13 Have you mentioned anything
34:14 about retiring an AID? Could you discuss
34:18 that if that's okay?
34:20 Yeah, I mean it's not really
34:23 specific to KERI and Signify but
34:31 If you want to
34:32 abandon an AID, as Sam (Smith, red.) calls it,
34:35 You have to do a rotation event which
34:38 just sets all the thresholds to zero I
34:40 believe. So at that point there's no
34:42 more signing authority of also of the
34:45 the signing keys and the rotation
34:47 keys essentially. So it's just dead. It
34:49 can't do anything. It's called
34:52 abandoned at that point. But I don't
34:54 believe anyone's done abandoned AIDs.
34:55 It's probably in KERI core and KERIPy
34:57 but it's not exposed in Signify.
35:05 – I have some questions that may
35:07 be tough for you to answer and
35:09 because I've struggled with these over a
35:11 long period of time looking for an
35:13 answer. So the one might be simple
35:17 the first one might be simple is what
35:19 could work offline in a wallet without
35:23 the agent being online.
35:27 You know can you sign things?
35:29 Can you issue credentials?
35:31 In the current model? No. You could sign them
35:37 and cue them up, but they wouldn't
35:38 actually be effective on the network.
35:39 They need to be on the KEL or TEL or
35:42 witnesses, etc.
35:43 Yeah.
35:44 So, you need some infrastructure.
35:46 But you might be able to prove ..,
35:49 you might be able to sign something, but
35:51 it couldn't be logged
35:54 anywhere. Could you sign
35:55 something, right?
35:56 You could sign something. Yeah.
35:58 Okay. And if you're using direct mode
35:59 KERI where there's no witnesses and
36:01 watchers, then you don't need the
36:02 infrastructure level. So you
36:05 you could sign something and send it.
36:07 Yeah.
36:07 Okay. So one of one of my concerns with
36:09 KERIA in general is that to my
36:12 knowledge it doesn't support high
36:15 availability and disaster recovery kind
36:18 of modes
36:19 today. Right. So if the hard disk
36:21 crashes or sorry: solid state disc drive
36:23 crashes,
36:27 you're out of luck on your KERI
36:31 service. Is that correct? And
36:34 what is the roadmap, if any to
36:37 make it high available or
36:40 disaster recovery of KERIA
36:43 I have a whole talk about that tomorrow
36:45 about the
36:45 road map. – Oh awesome. I know that's a
36:48 tough question, but it's an
36:51 important one, I think.
36:54 And then there's a similar question is
36:58 Sort of with vendor lock in. So you
37:00 host your own KERIA or use
37:04 another one from one of the
37:07 QVIs or providers. And you
37:10 have some vendor lock in at that point,
37:13 what can you do to move to another KERIA,
37:16 hosted by someone else? Has that been
37:18 discussed?
37:20 Again, that's something that's more on
37:22 the road map.
37:24 Like
37:25 you can do that. You have control of all
37:27 the keys. More of a problem would be
37:29 the data. So, you would have to have,
37:32 the previous provider would
37:34 need to be okay with moving that unless
37:36 you're going to sync down to Signify,
37:38 but it's not all available
37:40 on the KERI interfaces, right?
37:44 Yeah. But you could make it available,
37:45 right? So, that doesn't exist yet. Yeah.
37:46 what you're exact asking for it.
37:48 Okay.
37:49 Yeah.
37:49 Okay.
37:50 Yeah. But it is something that
37:51 we've been thinking about. It's just
37:54 again on the road map. One problem I
37:58 have with the
38:00 if it's
38:03 with this
38:05 Is if you lose your KERI instance,
38:06 you lose all of your AIDs.
38:10 The passcode that you have, that
38:12 you're entering only gives you access to
38:14 KERIA essentially. So if you lose
38:16 your encrypted salts, you've lost your AID.
38:18 I didn't realize that was
38:20 that those things were
38:22 "salty". I thought those were ..,
38:26 the encryption key was also derived from
38:28 the passcode, but no, it's
38:29 the encryption key is, but having the
38:32 actual cipher text to decrypt,
38:35 it's stored on KERIA. So you do use
38:38 your client AID. Oh, you use using
38:41 asymmetric encryption or symmetric
38:44 encryption.
38:45 Asymmetric.
38:46 Oh,
38:46 it doesn't need to be fast. Okay. It's
38:48 just salts,
38:50 I believe. Anyhow, but these are
38:52 stored encrypted on KERIA. So, if your
38:54 KERIA provider went .., disappeared,
38:57 you've lost all your AIDs, unless you
38:58 have backups to these.
38:59 Yeah.
39:00 the combination of .., without
39:04 redundancy of data,
39:06 ideally across regions, and so forth, and
39:09 without this recovery, it really
39:11 makes KERIA vulnerable in production
39:13 today.
39:14 Yeah. Yeah. Well
39:15 yeah there's the path
39:16 to production is kind of long
39:18 It's not really production ready at
39:20 scale or at any trust level in my
39:23 opinion ; is that a fair
39:25 statement?
39:27 It depends. I mean we've done
39:29 mitigations on that. I mean for example
39:30 these encrypted salts are also in our
39:32 wallet
39:33 and we have our own backups of those
39:35 because
39:36 I mean okay the data is one thing like
39:38 if you lose all your ACDCs you can go
39:39 back to the issuer. Okay.
39:40 Right.
39:41 The main thing you need to keep is your
39:42 keys. You know,
39:43 it would be annoying to have to do that
39:45 and build it all back up, but
39:47 And of course, our deployments have
39:49 backups every few minutes.
39:51 And I know you're in on the same
39:53 channel, but just for everyone's ears,
39:55 it be nice to see road maps, you know,
39:58 from WebOfTrust to say, "Yeah, we're
40:01 intending on doing these things this
40:02 quarter or whatever."
40:04 I know. Yeah. The same.
40:07 Thank you.
40:13 three minutes.
40:13 Any more questions?
40:14 Maybe one thing to mention as well is
40:17 what we are working on with regards to
40:20 migration for the road map
40:22 discussion is how the Veridian wallet
40:25 can request the cloud agent to provide a
40:27 backup file. So then you can migrate to
40:30 your own KERIA or a different KERIA
40:32 provider. So you can actually trigger
40:34 that
40:36 exactly
40:37 export and then as long as a KERI
40:39 provider is able to accept that import.
40:42 I mean this is also an element of the
40:44 GLEIF ecosystem, right, you can move from
40:46 QVI to QVI. So there are ways to
40:48 migrate but it does require there to be
40:53 it's also not trivial because you have
40:54 to update all the OOBIs and everything
40:56 like that and so forth. There's
40:58 some work to be done.
41:01 But yeah, it's definitely something to
41:03 think about.
41:03 Cool. But this is why we put a lot of
41:05 cost and resources into
41:08 actually how we back up the KERI data.
41:11 So, we assume that there will be a catch
41:14 failure and we pay a lot of money to
41:16 have high availability of that data. So
41:19 for the production services that we use
41:21 in our own organization foundation and
41:24 for any clients a lot of cost goes into
41:27 high available to data center
41:33 (inaudible, red) .. disaster ..
41:34 But that is an implementation choice and
41:35 how you deploy. Are you describing
41:39 how your cloud provider and your
41:43 EC2 kind of things are set up from a
41:47 data storage
41:48 How we're making sure KERI does
41:50 get wiped
41:51 Frequent snapshots.
41:54 Yes
41:56 But that isn't really a protocol-based
41:57 thing.
41:58 Right
42:00 Yeah, there's no protocol issues with
42:02 KERIA, really, it's more of an operational
42:04 thing you know that's where the gap is
42:06 <i>immaturity</i>.
42:09 But yeah, snapshotting is not
42:11 necessarily the most elegant way to
42:12 provide that high availability
42:14 redundancy,
42:15 especially.
42:16 No, but that's disaster recovery.
42:17 That's not for high availability.
42:22 Yeah. So like horizontal scaling is a
42:24 different thing. (Aplause)