Signify Security Architecture - Fergal O'Conner

KERICONF26 Day 1 · 37:45

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)