home / kskb-text

document_text

9 rows where source_id = "weboftrust-keria-main"

✎ View and edit SQL

This data as json, CSV (advanced)

source_id 1

  • weboftrust-keria-main · 9 ✖

license 1

  • Apache-2.0 9

kind 1

  • repository prose file 9
id ▼ source_id kind license title url credit chars text
weboftrust-keria-main/10 weboftrust-keria-main repository prose file Apache-2.0 docs/README.rst https://github.com/WebOfTrust/keria/blob/main/docs/README.rst WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/docs/README.rst. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 1234

KERIA

|GitHub Actions| |codecov|

KERI Agent in the cloud

Split from KERI Core

Development

Setup ~~~~~

  • Ensure Python <https://www.python.org/downloads/>__ version 3.12.1+ is installed
  • Install Keripy dependency <https://github.com/WebOfTrust/keripy#dependencies>__ (libsodium 1.0.18+)

Build from source ^^^^^^^^^^^^^^^^^

  • Setup virtual environment: bash python3 -m venv venv
  • Activate virtual environment: bash source venv/bin/activate
  • Install dependencies: bash pip install -r requirements.txt
  • Run agent: bash keria start --config-dir scripts --config-file demo-witness-oobis

Build with docker ^^^^^^^^^^^^^^^^^

  • Build KERIA docker image: bash make build-keria

Running Tests ~~~~~~~~~~~~~

  • Install pytest: bash pip install pytest

  • Run the test suites: bash pytest tests/

.. |GitHub Actions| image:: https://github.com/webOfTrust/keria/actions/workflows/python-app-ci.yml/badge.svg :target: https://github.com/WebOfTrust/keria/actions .. |codecov| image:: https://codecov.io/gh/WebOfTrust/keria/branch/main/graph/badge.svg?token=FR5CB2TPYG :target: https://codecov.io/gh/WebOfTrust/keria

weboftrust-keria-main/11 weboftrust-keria-main repository prose file Apache-2.0 docs/keria_app.rst https://github.com/WebOfTrust/keria/blob/main/docs/keria_app.rst WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/docs/keria_app.rst. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 3743

KERIA App API

keria.app.agenting

.. automodule:: keria.app.agenting :members:

Agency and Agent Configuration

A KERIA Agency can be configured with either environment variables or a configuration file. The configuration file is a JSON file. Both alternatives are shown here.

Environment Variables

.. code-block:: bash

# Service Endpoint Location URLs creating Endpoint Role Authorizations and Location Scheme records on startup
export KERIA_CURLS="https://url1,https://url2"
# Introduction URLs resolved on startup (OOBIs)
export KERIA_IURLS="https://url3,https://url4"
# Data OOBI URLs resolved on startup
export KERIA_DURLS="https://url5,https://url6"
# how long before an agent can be idle before shutting down; defaults to 1 day
export KERIA_RELEASER_TIMEOUT=86400

JSON Configuration File

To use the JSON configuration file option make sure to mount the JSON file to the directory you specify with the --config-dir option and name the JSON file the name specified by the --config-dir option to the keria start command like so.

With the absolute path version the --config-dir argument does not have an affect since the --config-file argument specifies the absolute path to the JSON file.

.. code-block:: bash

# Relative path version, interpreted relative to directory executing keria binary from.
# This means the file "keria.json" must exist in the "scripts/keri/cf" folder
keria start \
    --config-dir scripts \
    --config-file keria

# Absolute path version
keria start \
    --config-dir /path/to/config-dir/keria.json \
    --config-file /path/to/config-dir/keria.json

The JSON file must have an object with the same name that you sent to the keria start command via the --name argument. The default is "keria" which is why the JSON file below shows a sub-object named "keria". Make sure to include the "dt" date timestamp field or the configuration will not be loaded.

You can configure the cycle time, or tocks, of the escrower as well as the agent initializer.

You can also configure the CURLs, IURLs, and DURLs of the agent. CURLs are Service Endpoint Location URLs creating Endpoint Role Authorizations and Location Scheme records on startup. IURLS are Introduction URLs resolved on startup (OOBIs). DURLS are Data OOBI URLs resolved on startup usually of things like ACDC credential schemas or ACDC credential CESR streams.

.. code-block:: json

{
  "dt": "2025-01-13T16:08:30.123456+00:00",
  "keria": {
    "dt": "2025-01-13T16:08:30.123457+00:00",
    "curls": ["http://127.0.0.1:3902/"]
  },
  "iurls": [
    "http://127.0.0.1:5642/oobi/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha/controller?name=Wan&tag=witness",
    "http://127.0.0.1:5643/oobi/BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM/controller?name=Wil&tag=witness",
    "http://127.0.0.1:5644/oobi/BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX/controller?name=Wes&tag=witness"
  ],
  "tocks": {
    "initer": 0.0,
    "escrower": 1.0
  }
}

keria.app.aiding

.. automodule:: keria.app.aiding :members:

keria.app.credentialing

.. automodule:: keria.app.credentialing :members:

keria.app.indirecting

.. automodule:: keria.app.indirecting :members:

keria.app.notifying

.. automodule:: keria.app.notifying :members:

keria.app.presenting

.. automodule:: keria.app.presenting :members:

keria.app.specing

.. automodule:: keria.app.specing :members:

weboftrust-keria-main/12 weboftrust-keria-main repository prose file Apache-2.0 docs/keria_core.rst https://github.com/WebOfTrust/keria/blob/main/docs/keria_core.rst WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/docs/keria_core.rst. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 398

KERIA Core API

keria.core.authing

.. automodule:: keria.core.authing :members:

keria.core.httping

.. automodule:: keria.core.httping :members:

keria.core.keeping

.. automodule:: keria.core.keeping :members:

keria.core.longrunning

.. automodule:: keria.core.longrunning :members:

weboftrust-keria-main/13 weboftrust-keria-main repository prose file Apache-2.0 docs/keria_db.rst https://github.com/WebOfTrust/keria/blob/main/docs/keria_db.rst WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/docs/keria_db.rst. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 106

KERIA DB API

keria.db.basing

.. automodule:: keria.db.basing :members:

weboftrust-keria-main/14 weboftrust-keria-main repository prose file Apache-2.0 docs/keria_end.rst https://github.com/WebOfTrust/keria/blob/main/docs/keria_end.rst WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/docs/keria_end.rst. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 121

KERIA Endpoint API

keria.end.ending

.. automodule:: keria.end.ending :members:

weboftrust-keria-main/15 weboftrust-keria-main repository prose file Apache-2.0 docs/keria_notifications.md https://github.com/WebOfTrust/keria/blob/main/docs/keria_notifications.md WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/docs/keria_notifications.md. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 9825

KERIA Notifications

Simple end user interaction with a KERIA server agent through notifications.

Notifications allow good UX for event driven workflows in complicated, multi-step activities such as multi-signature identity management or credential issuance and presentation. SignifyTS and SignifyPy-based client applications may use the KERIA notifications API to draw user attention to tasks for the user to complete in these workflows whether single or multi-step.

Notifications can be polled for and, in the future, will be sent via a server sent events (SSE) stream.

Overview

Notifications are durable in that they are stored in an Agent's database in the KERIA server. An edge controller may read the notification database to list notifications, mark notifications as read, or delete notifications.

Modules Using Notifications

Modules leveraging notifications include: - multisig identifier operations - creation - rotation - signing (interaction) - identifier delegation, single sig or multisig - credential issuance and presentation (IPEX), single sig or multisig - challenge response and verification - out-of-band identifier (OOBI) resolution

Example notification

A notification payload looks like this:

jsonc { "i": "0AC-ghYFcCJBa045nPFTW1hh", "dt": "2026-06-26T21:12:11.266531+00:00", "r": false, "a": { "r": "/multisig/icp", "d": "EKm4OYRrUwo9nwik406n34ckWViDl6pLCeyGf75zpIyi" } }

This is a notification for a multisig inception event.

Example Exchange Message for Notification

The operations in the modules listed above use KERI Exchange ("exn" / "EXN") messages to drive notifications in KERIA and are categorized by their route, the "r" field in an exchange message. When the exchange message processor, the Exchanger component from KERIpy, processes an exchange message then it delegates message processing to an exchange message handler based on the route field, the "r" attribute. This means the route is effectively a category field or secondary type field for an exchange message.

Some exchange messages generate notifications and some do not.

Route types

Here's the breakdown for each of the exn route types:

  • /multisig/*: Multisig coordination exn messages.
  • Handled by Multiplexor - creates a notification for receivers, not senders.
  • Event types:
    • icp: route /multisig/icp - multisig inception
    • rot: route /multisig/rot - multisig key rotation
    • ixn: route /multisig/ixn - multisig interaction (signing)
    • vcp: route /multisig/vcp - multisig registry creation
    • iss: route /multisig/iss - multisig credential issuance
    • rev: route /multisig/rev - multisig credential revocation
    • exn: route /multisig/exn - multisig exchange message
    • rpy: route /multisig/rpy - multisig reply message (like location scheme, endpoint role authorization)
  • /ipex/*:
  • Handled by IpexHandler - creates a notification for each sender and receivers.
  • Event types:
    • apply: route /ipex/apply - Request a credential disclosure
    • offer: route /ipex/offer - Offer a specific credential disclosure by schema, either fully expanded, partially compact, or fully compact.
    • agree: route /ipex/agree - Agree to a specific credential disclosure
    • grant: route /ipex/grant - Grant the agreed upon credential disclosure
    • admit: route /ipex/admit - Admit the disclosed credential
    • spurn: route /ipex/spurn - Reject either an apply, offer, or agree event.
  • /challenge/response:
  • Handled by ChallengeHandler - does not create a notification, does not need one.
  • Sends add a signal to Signaler.
  • /delegate/request:
  • Handled by DelegateRequestHandler - creates a notification for the delegator only.
  • Only one event type, the delegation request.
  • /oobis:
  • Handled by OobiRequestHandler, though is not currently registered. No notification needed for OOBI resolution.

Route attribute for exchange message routing

The "r" attribute of an exchange message corresponds to the same field in the notification attribute "a" section, meaning the "notification.a.r" property is a route field. The route field of a notification and its corresponding exchange message will match.

Typical Exchange Message Example - /multisig/icp

A typical exchange message looks like the following /multisig/icp message containing similar fields:

jsonc { "v": "KERI10JSON0003af_", // version "t": "exn", // type - always exn for Exchange message "d": "EL0z30RTfX7Hj6V7tbcwQsbadXzykG5YBLsWYzZOiZEt", // digest (SAID) of message "i": "EA93JVUXysuNV4ZgjnHrrgG0FGVU8717IoG6oWg_J3fW", // sender (AID identifier of sender) "rp": "", // recipient AID of receiver - (optional) "p": "", // previous event SAID - (optional) "dt": "2026-06-26T21:40:36.189723+00:00", // ISO 8061 date & timestamp string "r": "/multisig/icp", // route "q": {}, // modifiers - (optional) like query string of URI "a": { // attributes - message payload "gid": "EMstJkrXzZ9TEfWRX3tzKZy-wVPyvSwa22TREIeJLo5g", "smids": ["..."], "rmids": ["..."] }, "e": { // embeds - (optional) embedded data "icp": { "v": "KERI10JSON000189_", "t": "icp", "...": "..." }, "d": "ENT1TlQmyHygC487HUex-88hoTUM9ORggV-tUsYT1Xw5" } }

Multisig Identifier Operations

Each multisig operation, like those listed in route types, require participation by a threshold satisfying number of multisig group members. An exchange message for the given route type is sent to each multisig group member and creates a notification for each multisig message recipient.

The author, or initiator, of a multisig event does not get a notification because the KERIpy Multiplexor implementation suppresses self-notification, which makes sense because the initiator is assumed to know about the event it submits, thus a self-notification is not needed.

Delegated Identifier Inception or Rotation Request Approval Notifications

Both inception and rotation must be approved by the delegator when a delegate wants to either set up a new identifier, inception, or rotate keys on an existing identifier. this means each inception or rotation event must trigger a notification for the delegator to see the approval request. The approval request is sent from the delegate as an exchange message to the delegator. The delegator's KERIA agent then sees that exchange message and generates a notification from it.

In Signify this is exposed as delegations().approve(...), which posts to /identifiers/{name}/delegation.

Inception or Rotation Approval Request EXN

KERIA sends a peer-to-peer EXN on route /delegate/request containing the delegator AID and embeds the delegated event as e.evt. On receipt, KERIA converts the verified EXN into a notification with these attributes:

json { "src": "verified EXN sender AID", "r": "/delegate/request", "delpre": "local delegator qb64 AID", "ked": "embedded delegated event", "aids": ["optional multisig participant AIDs"] }

Wallets can derive the seal to review and approve from the embedded event:

json { "i": "delegate event prefix", "s": "delegate event sequence number", "d": "delegate event SAID" }

Wallets should derive the seal from the event instead of hard-coding the inception case.

Inception

For delegated inception, s is "0" and d is always the delegate prefix.

Rotation

For delegated rotation, s is the rotation sequence number and d is always the rotation event SAID.

KERA Agent Signs Delegation Requests - delegation communication proxy

The /delegate/request exchange message is used as a signed request for delegation approval of either inception or rotation. KERI uses signed requests for everything, which means a delegation request must be signed. This implies that a pre-existing AID, whose KEL is known by the delegator, signs the delegated inception (dip) event because a delegatee cannot sign its own delegated inception event since the dip is not valid until the delegator approves it.

A delegation communication proxy is used as this pre-existing AID. In KERIA the Agent Hab AID that the edge Signify client delegates to is used as this delegation communication proxy. This allows the /delegate/request EXN message to be signed by a valid KERI AID, the sender's Agent habitat (Hab) AID, selected by KERIA's delegation Anchorer.

Single Sig Delegates

For a Signify managed single-sig AID, that sender is the delegatee's Agent AID, which acts as a delegation communication proxy because edge Signify identities rely on their KERIA Agent to sign delegation requests.

Multi Sig Delegates

For a group delegated AID, the sender is the Agent Hab for the local single sig member of the group AID. This Agent Hab for the single sig member acts as the delegation communication proxy.

Delegator must know delegation communication proxy

The delegator must already know (have OOBI resolved) the EXN sender's KEL before its Exchanger can validate the request and create a notification. This means the delegator must have OOBI resolved the Agent OOBI for the Signify AID. If the sender is unknown, the inbound EXN will not produce a /delegate/request notification and will stay in escrow until it expires even though the raw delegated event may still be sent separately.

weboftrust-keria-main/16 weboftrust-keria-main repository prose file Apache-2.0 docs/protocol.md https://github.com/WebOfTrust/keria/blob/main/docs/protocol.md WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/docs/protocol.md. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 15911

Signify/KERIA Request Authentication Protocol (SKRAP)

KERIA Service Endpoint Interfaces

The KERIA service will expose 3 separate HTTP endpoints on 3 separate network interfaces.

  1. Boot Interface - Exposes one endpoint for Agent Worker initialization.
  2. Admin Interface - The REST API for command and control operations from the Signify Client.
  3. KERI Protocol Interface - CESR over HTTP endpoint for KERI protocol interactions with the rest of the world.

This separation allows for the Boot interface to be expose to internal infrastructure only (or disabled all together) while exposing the other two interfaces externally. If a KERIA instance is launched in static worker mode, meaning all agent workers are configured at start up only the Boot interface can be disabled completely.

Agent Worker Initialization

To initiate a connection between a Signify Client and a KERIA agent, the two sides will exchange KERI AIDs with the Signify Client AID (called the "Client AID") being the delegator for the KERIA agent worker AID (called the "Agent AID"). To establish the connection the following steps are performed:

Step One: Generate Client AID

The Signify Client generates the client AID as a transferable AID with a single signing key and single rotation key and provides the signed inception event out-of-bands to the KERIA service through the Boot interface. The HTTP request must be signed by the client AID using Signify Request Authentication described below. The algorithm for generating the signing and rotation key pairs for Client AID is as follows:

  1. Prepend the 128 bit random salt derivation code ('0A') plus the blank qualified base 64 character ('A') to the provided 21 character passcode
  2. Stretch the passcode derivation using Argon2 to generate an Ed25519 private key from the provided "tier" and paths of signify:controller00 and signify:controller01 for the signing key and rotation key respectively.
  3. Use the qualified base64 of the signing public key and the qualified base64 of the Blake3 digest of the rotation public key in the inception event.

The follow is an example of a Client AID generated by the SignifyPy (Python implementation) Signify Client with a passcode of 0123456789abcdefghijk

json { "v": "KERI10JSON00012b_", "t": "icp", "d": "ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose", "i": "ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose", // Client AID "s": "0", "kt": "1", "k": [ "DAbWjobbaLqRB94KiAutAHb_qzPpOHm3LURA_ksxetVc" // Derived from passcode as salt, kidx = 0 ], "nt": "1", "n": [ "EIFG_uqfr1yN560LoHYHfvPAhxQ5sN6xZZT_E3h7d2tL" // Derived from passcode as salt, kidx = 1, Blake3 Hashed ], "bt": "0", "b": [], "c": [], "a": [] }

Step Two: Agent Worker Creation

The KERIA service will create an Agent Worker on behalf of the new client and create the delegated, transferable Agent AID with a single signing key and single rotation key specifying the Client AID as its delegator in its inception event.<br> The KERIA service will return the Agent AID inception event in a signed HTTP response, signed by the Agent AID. Agent AID keys can be generated using a salt or truly random depending on the requirements of the service hosting the KERIA service.

json { "v": "KERI10JSON00015f_", "t": "dip", // Delegated AID "d": "EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei", "i": "EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei", // Agent AID "s": "0", "kt": "1", "k": [ "DMZh_y-H5C3cSbZZST-fqnsmdNTReZxIh0t2xSTOJQ8a" ], "nt": "1", "n": [ "EM9M2EQNCBK0MyAhVYBvR98Q0tefpvHgE-lHLs82XgqC" ], "bt": "0", "b": [], "c": [], "a": [], "di": "ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose" // Delegated signing authority from Client AID }

Step Three: Signify Client Delegation Approval

Note that all HTTP requests against the Admin Interface must be signed by the Client AID and expect all responses to be signed by the Agent AID.

The Signify Client will approve the delegation of the client AID with an interaction event that it sends back to the KERIA service over the Admin interface.

Once these steps are complete the Signify Client can begin using the rest of the Admin interface to create AIDs, issue credentials, etc.

Reconnecting to Existing Agent Worker

Document the steps for retrieving state from the Admin interface and updating.

Key Generate Methods

The KERIA service supports the following key generation methods where the Signify Client generates the keys and only ever sends encrypted key material (if any) to the server. 1. Salty Keys - HDK key chain generated from a salt per aid that is encrypted and stored server. 2. Randy Keys - Randomly generated keys (signing and rotation) that are encrypted and store on the server. 3. Sandy Keys - Keys generated from a different salt for inception and each rotation.<br> 4. Group Keys - Signify Client/KERIA Service AIDs participating in a distributed group multisig AID. 5. HSM Keys - Signify Client uses a Signify HSM Integration Module (SHIM) to manage keys and signatures.

For all key generation methods, the Signify Client creates and signs all KERI events, credentials, etc. ensuring that unencrypted private key material never leaves the client. The key generate methods are descrive in more detail in the following sections.

Salty Keys

The Salty Key algorithm is used to create a hierarchical deterministic key chain for each AID by generating a unique random salt for each AID and stretching the salt using Argon2 with a path that is calculated from the AIDs index relative to all other AIDs and the key index calculated by the total number of signing and rotation keys over the lifetime of the AID.

The salt for each AID is encrypted with the X25519 encryption key generated from the passcode and stored on the server with other AID metadata, including the AID index and current key index.

The Signify Client API must accept the AID salt as an optional parameter to creating Salty Key AIDs allowing users to manage AID salts externally or to share Salts across AIDs if required.

The following Python data class represents the metadata storage for Salty Key AIDs:

```python class SaltyPrm: """ Salty prefix's parameters for creating new key pairs """ sxlt: str = '' # qualified b64 encoded AID salt pidx: int = 0 # prefix index for this keypair sequence kidx: int = 0 # key index for this keypair sequence stem: str = '' # default unique path stem for salty algo tier: str = '' # security tier for stretch index salty algo dcode: str = '' # next digest hasing code icodes: list = field(default_factory=list) # current signing key seed codes ncodes: list = field(default_factory=list) # next key seed codes transferable: bool = False

```

Salty Key Salt Rotations

Document the procedure for rotating a new Salt in for a Salty Key AID.

Randy Keys

The Randy Key algorithm allows for all signing and rotation private keys to be generated solely from entropy and encrypted with the X25519 encryption key generated from the passcode and stored on the server alongside other AID metadata.

The server stores the encrypted private key material for signing and rotation keys in separate LMBD sub-databases as indexed qualified base 64 CESR encoded Cipher representations.

Sandy Keys

Group Keys

The Group Key algorithm is a special key generation algorith for distributed group multisig AIDs that does not manage and keys at all. Instead this algoritm allows for the specification of an AID of one of the other three types to be the "local" participant in a distributed group multisig AID.

All signing operations must be performed on the Signify Client on behalf of the "local" AID for this Signify Client indexed based on the local AID's location in both the signing key list and the rotation key list.

HSM Keys (Experimental)

The SignifyPy Signify Client defines an experimental interface for declaring external modules that can be used as Signify HSM Integration Modules to allow all key generation and event signing to occur in an external Hardware Security Module (HSM).

Two sample implementations have been defined to date, one using the Google KSM and one using a Trezure One external HSM.

The following psuedo Python class represents the current, experimental interface a SHIM has to implememnt to work with SignifyPy. It is anticipated that each Signify Client implementation defines a similar interface.

```python class Shim: def incept(self, transferable=True): """ Create an AID using the Google KSM for key generation and event signing.

    Parameters:
        transferable (bool):  True means create a transferable AID which allows for key rotation

    Returns:
        keys (list): list of qualified base64 public signing key deriviations based on the codes passed into init
        ndigs (list): list of qualified base64 digests of public rotation key derivations based on the codes
                      passed into init

    """

def rotate(self, ncount, transferable):
    """  Rotate an AID using the Google KSM for key generation and event signing.

    Parameters:
        ncount (int): number of new rotation keys to generate
        transferable (bool):  True means create a transferable AID which allows for key rotation

    Returns:
        keys (list): list of qualified base64 public signing key deriviations based on the codes passed into init
        ndigs (list): list of qualified base64 digests of public rotation key derivations based on the codes
                      passed into init

    """

def sign(self, ser, indexed=True, indices=None, ondices=None, **_):
    """

    Parameters:
        ser (bytes): content to be signed
        indexed (bool): True means generated indexed signatures
        indices (list): Optional list of indices to use when generating indexed signatures
        ondices (list): Optional list of rotation indices to use when generating dual indexed signatures
        **_: Placeholder

    Returns:
        sigs (list): list of qualified base64 signatures over the based in ser
    """

```

Passcode Rotation

To perform a passcode rotation, the Signify Client requires both old and new passcodes and must perform the following steps:

  1. Encrypted the old passcode with X25519 key generated from the new passcode.
  2. Perform a partial rotation of the Client AID as described below.
  3. Decrypt all salts with X25519 key from old passcode for Salty Keys, validate them against current public keys, encrypt with X25519 key from new passcode
  4. Decrypt all keys with X25519 key from old passcode for Randy Keys, validate them against current public keys, encrypt with X25519 key from new passcode
  5. Send all rotation event and all recrypted material in a POST request to the agent on /agent/<Client AID>

Partial Client AID Rotaion in Support of Passcode Rotation

To provide post-quantum secure passcode recovery, a passcode recovery must be accompanied by partial rotation of the Client AID. This partial rotation is possible because the user will have to provide both old and new passcodes to initiate the process.

The partial rotation of the Client AID is accomplished by using the old passcode to regenerate the the prior rotation key pair called R0 from the latest establishment event. In addition, two new key pairs are generated from the new passocde, one used for signing authority (S0) and one used for rotation authority (R1) in the new rotation event.

The public key for S0 is used as the first signing key in the new rotation event; it is giving a fractionally weighted threshold of "1". The public key for R0 is used as the second signing key in the new rotation event; it is giving a fractionally weighted threshold of "0". A Blake3 has is created of the public key for R1 and is used as the next rotation key commitment.

The rotation event is signed with the private keys of both S0 and R0. An example of a partial rotation event of the Client AID from above follows with its signatures:

json { "v": "KERI10JSON000195_", "t": "rot", "d": "EGTAY6x1tTbOO27LCy3poh5iW0Oa2Cq1s7wsVnj152Zi", "i": "ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose", "s": "1", "p": "ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose", "kt": [ "1", // Threshold for key derived from NEW passcode, has full signing authority "0" // Threshold for key derived from OLD passcode, no signing authority ], "k": [ "DAbWjobbaLqRB94KiAutAHb_qzPpOHm3LURA_ksxetVc", // Derived from NEW passcode as salt, kidx = 0 "DHMAZEksiqGxlNKnm0pSAyMRPK1ZKyBfGV8q_B9r6pLs" // Derived from OLD passcode as salt, kidx = 1 (matches previous rotation key) ], "nt": "1", "n": [ "EIFG_uqfr1yN560LoHYHfvPAhxQ5sN6xZZT_E3h7d2tL" // Derived from NEW passcode as salt, kidx = 1, Blake3 Hashed ], "bt": "0", "br": [], "ba": [], "a": [] }

With the following attached signatures: json [ "AADuzJ4zU8MkLBPP8Os9UPbTvNqoQ4YDImNkTjfknWgJW25V6EmwZ59PXas0zKhxtp_dOhvkPqtqIhgarOFwt7sC", "2AABAACRZGDB7s4hmYnt7vTYGWCawhnqHndWUy_rtR_L8mfNmrJ4N5S05wAZ6w5RoL68h1HjIzO7ZuiF30XBz1cC6eUA" ]

The first signature satisfies the current signing threshold and has only one index, 0 for signing key index. The second signature satifies the prior rotation threshold and thus uses dual index code to specify a current signing index of 1 and a prior signing index of 0.

The following steps are followed to accept the passcode rotation:

  1. Verify and accept the Client AID rotation
  2. Verify the signature on the request against the NEW signing key of the Client AID
  3. Save encrypted old passcode
  4. Update all Salty Key encrypted salts
  5. Update all Randy Key encrypted keys
  6. Delete encrypted old passcode

Passcode Rotation Recovery

When each Agent Worker is loaded it will check for a saved old passcode to detect an aborted passcode rotation. If a saved encrypted old passcode is found the Agent Worker will notify the client in the response to the state call that a passcode rotation recovery is needed and lock out all other operations until it is completed successfully.

To perform a passcode rotation recovery, the Signify Client requires only the new passcode and must perform the following steps:

  1. Retrieve the encrypted old passcode and decrypt it with X25519 key generated from the new passcode.
  2. Perform a revised partial rotation of the Client AID where you rotate out to a new next key not new signing key.
  3. Attempt to decrypt all salts with the X25519 keys from both the old and new passcode for Salty Keys
  4. For any salt still encrypted with the old passcode, encrypt with X25519 key from new passcode
  5. Attempt to decrypt all keys with the X25519 keys from both the old and new passcode for Randy Keys
  6. Validate them against current public keys and for any key still encrypted with the old passcode, encrypt with X25519 key from new passcode
  7. Send all rotation event and all recrypted material in a POST request to the agent on /agent/<Client AID>

Signify Request/Response Authentication

Signify clients must sign all requests to the KERIA Admin Interface using the latest signing key of the Client AID and must expect all responses from the KERIA service be signed by the latest signing key of the Agent AID. Both request and response signing rely on the same set of HTTP headers to accomplish request/response signing.

Metadata Headers

Document Signify-Resource and Signify-Timestamp headers here.

Signature Input Header

Document the Signature-Input header here with link to https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html

Signature Header

Document the signing method and Signature header.

weboftrust-keria-main/6 weboftrust-keria-main repository prose file Apache-2.0 MAINTAINERS.md https://github.com/WebOfTrust/keria/blob/main/MAINTAINERS.md WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/MAINTAINERS.md. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 1934

Maintainers

This document lists the maintainers of this project.

Current Maintainers

| Name | GitHub | Discord | email | | --------------- | ----------------------------------------------------- | --------------- | -------------------------- | | Fergal O'Connor | iFergal | djlandlord | | | Daniel Lenksjö | lenkan | lenksjo_82594 | | | Kent Bull | kentbull | kentbull | |

Responsibilities

Maintainers are responsible for:

  • Reviewing and approving pull requests
  • Managing releases
  • Maintaining code quality standards
  • Responding to issues and community questions

Review Process

All pull requests require approval from at least 2 out of 3 maintainers before merging.

Retired Maintainers

| Name | GitHub | Discord | email | | ----------------------- | ------------------------------------------------------- | --------------------- | ------------------------------------- | | Phil Feairheller | pfeairheller | philfeairheller_95942 | | | Lance Byrd | 2byrds | megrimlance | | | Rodolfo Miranda | rodolfomiranda | rodo5833 | | | Kevin Griffin | m00sey | m00sey | |

weboftrust-keria-main/7 weboftrust-keria-main repository prose file Apache-2.0 changelog.md https://github.com/WebOfTrust/keria/blob/main/changelog.md WebOfTrust / keria-main, https://github.com/WebOfTrust/keria/blob/main/changelog.md. Licensed under the Apache License 2.0; the license and any notices are in the repository. Found through KERISSE. 8884

Changelog

0.4.0 - 2026-03-23

Changes in this draft cover the delta from 0.2.0-rc2 (6ad36d5e171c599b078624c9ed4cd1c54e3c1b4a) through aba457cab3813078bfedb65a7d819f48d86974b8.

Summary

  • Hardened credential, IPEX, and exchange flows by fixing deletion/index cleanup, first-grant artifact delivery, admit/grant parsing, escrowed credential reads, and outbound EXN indexing.
  • Improved runtime behavior with cleaner shutdown semantics, better logging, optional request tracing, and log-level propagation into the underlying KERI stack.
  • Refactored startup and configuration handling to improve testability, temp-mode correctness, and agency/agent config injection.
  • Expanded and tightened the OpenAPI contract with generated schemas, typed operation models, and more accurate endpoint response definitions.
  • Improved response-shape compatibility for identifiers, key-state records, multisig EXN payloads, and mixed client request formats.
  • Modernized packaging and delivery by moving to uv, refreshing CI and Docker workflows, and upgrading KERI/KERIA runtime dependencies.

Agent, credential, and exchange behavior

  • Deleted credentials now also remove KERIA-specific search indexes, so filtered queries no longer return stale deleted records.
  • IPEX grant delivery now includes the agent and controller KELs required to validate the first presented credential, fixing the long-standing first/double-present failure mode.
  • Refactored IPEX grant processing around a dedicated GrantDoer that gathers dependent KEL, TEL, and chained-credential artifacts into one debuggable flow.
  • IPEX admit/grant/apply/offer/agree handling now uses the agent parser consistently, preventing crashes such as the NoneType ... ked admit failure.
  • Peer exchange parsing now indexes outbound EXN messages so sent exchanges are visible through local exchange indexes.
  • GET /credentials/{said} now returns 404 Not Found for escrowed or unsaved credentials instead of surfacing as 500, including on the CESR path.
  • Credential issuance now accepts either ri or legacy ii registry references and returns a clear 400 when neither is present.
  • Identifier rename validation now rejects duplicate target names instead of allowing one AID rename to overwrite another.

Runtime, logging, and operability

  • Reworked shutdown handling so agency shutdown follows the HIO doer lifecycle, using shutdown flags and KeyboardInterrupt instead of forcing Doist.exit().
  • Improved logs with a truncated formatter, clearer habitat context, and full identifier logging for multi-agent runs.
  • Disabled HTTP request logging by default and added a --logrequests CLI switch for opt-in tracing.
  • Propagated the configured KERIA log level into the underlying KERI logger so verbosity stays aligned across both layers.
  • Added a maintainer-facing scripts/keria.json config and a MAINTAINERS.md file.

Configuration, startup, and testability

  • Refactored server startup so agency creation and HTTP server wiring are split into smaller reusable functions.
  • Made agency configuration more testable by allowing an external Configer to be injected and by merging per-agent config with configured controller, introduction, and data OOBI lists.
  • Fixed temporary-mode handling so config files and LMDB state respect temp instead of partially writing persistent test data.

API descriptions and generated schemas

  • Added reusable OpenAPI-generation utilities and shifted more schema definitions to generated type-hint-driven models.
  • Expanded OpenAPI coverage for credentialing endpoints, including credential, registry, credential-state, anchoring-event, and cloned-credential response shapes.
  • Expanded OpenAPI coverage for identifier and agent endpoints, including typed responses for agent state, identifier listings, identifier details, key state, key event logs, OOBIs, and agent config.
  • Expanded OpenAPI coverage for delegation, grouping, IPEX, notification, and peer exchange endpoints, including typed multisig EXN payloads and long-running operation responses.
  • Reworked long-running operation schemas so OpenAPI distinguishes operation families such as OOBI, query, witness, delegation, end-role, and registry instead of exposing one loose generic object.
  • Added and refined operation IDs, response payload schemas, and component references across the REST surface to support client generation and stricter schema validation.

Type and response-shape compatibility

  • Fixed KeyStateRecord typing and OpenAPI shape for kt and nt, allowing threshold fields to be represented as either strings or arrays.
  • Split identifier response modeling into base and full HabState variants so list and detail endpoints can describe different field guarantees accurately.
  • Relaxed HabState optionality for state, transferable, and windexes where those fields are not always present.
  • Made ExnMultisig helper fields such as groupName, memberName, and sender optional in generated schemas instead of incorrectly requiring them.

Dependency, packaging, and CI updates

  • Upgraded KERI from 1.2.6 to 1.2.7, including the HIO-compatible doer signature updates required by the newer runtime.
  • Upgraded again to KERI 1.2.12 and bumped KERIA to 0.4.0.
  • Removed the explicit setuptools dependency and then migrated packaging from setup.py and requirements.txt to pyproject.toml, uv, and a checked-in uv.lock.
  • Added ruff linting and formatting checks to the repo and CI workflow.
  • Updated the Makefile with uv-based install, test, coverage, lint, and format targets.
  • Updated the Docker build to run from the uv-managed environment and added a Docker validation step to CI.
  • Adjusted CI/runtime dependencies to pin uv, downgrade lmdb for Docker compatibility, and move GitHub Actions macOS testing to macos-15.

0.3.0 - 2025-05-28

  • Improved runtime logging with clearer formatting plus habitat name and prefix context in log messages.
  • Simplified graceful shutdown behavior and related runtime lifecycle handling.
  • Upgraded KERI to 1.2.6 and finalized the 0.3.0 version bump.

0.2.0-rc4 - 2025-05-28

  • Fixed first-time IPEX grant/present flows by sending the agent and controller KELs needed by recipients to validate the credential chain.
  • Fixed credential deletion cleanup so KERIA-specific search indexes are removed with the credential record.
  • Removed the explicit setuptools dependency.

0.2.0-rc2 and Older Releases

0.2.0-rc2 - 2025-01-24

  • Added an API for creating new location schemes.
  • Fixed basic boot passwords to allow colon characters.
  • Fixed delegated multisig rotation by always routing Signify group messages through the agent proxy.
  • Upgraded KERI to 1.2.4.

0.2.0-rc1 - 2025-01-13

  • Added graceful shutdown handling for agents and the KERIA process, including SIGTERM support and the new serving/shutdown path.
  • Returned 400 for invalid end-role signatures while preserving the multisig-required UnverifiedReplyError behavior.
  • Refreshed release docs, Docker, CI, and keria.json documentation for the 0.2.0 release candidates.

0.2.0 / 0.2.0-dev6 - 2024-12-12

  • Added experimental basic-auth protection for the boot endpoint.
  • Added environment-variable-based server configuration.
  • Exposed inception timestamps in identifier/hab info.
  • Added credential deletion support and explicit 404 behavior after deletion.
  • Added multi-arch Docker publishing support.

0.2.0-dev5 through 0.2.0-dev0 - 2024

  • Expanded multisig and delegation support with delegation approval, delegated rotation fixes, multisig join/rotation fixes, submit/witness-receipt improvements, and better SignifyTS compatibility.
  • Expanded IPEX and credential flows with apply/offer/agree endpoints, multisig IPEX support, direct credential verification from (acdc, iss), registry read endpoints, and better recipient routing.
  • Improved API usability with prefix-based identifier/addressing support, agent-config retrieval, 409 on already-booted agents, idle-agent release, and clearer long-running operation IDs and status handling.
  • Added more REST and OpenAPI documentation, plus broader test coverage around delegation, multisig, witness receipts, revocation, and credential workflows.
  • Kept pace with KERI/KERIpy, Falcon, Docker, and CI changes as the stack moved through the 1.2.x transition.

0.1.3 and Earlier - 2024

  • Established the early credential-registry lifecycle, including registry rename/join support, duplicate-name protection, and fixes for partially committed registry visibility.
  • Added the first IPEX apply/offer/agree support and tightened early long-running-operation handling.
  • Continued aligning with upstream KERI/KERIpy and Python runtime changes while filling in foundational tests and release automation.

Advanced export

JSON shape: default, array, newline-delimited, object

CSV options:

CREATE TABLE document_text (id TEXT PRIMARY KEY, source_id TEXT, kind TEXT, license TEXT, title TEXT, url TEXT,
        credit TEXT, chars INTEGER, text TEXT);
Powered by Datasette · Queries took 1435.405ms