Trust in the system originates here. Everything downstream, like mailboxes, messaging, and MLS groups, depends on having an identity.
This chapter explains where and how trust is rooted before anything else built on top of it will make sense.
Chains
Unlike a traditional app that relies on central servers and cloud-hosted databases to store data and act as an authority for trust, Rhizo users hold and control their own cryptographic keys locally and verify everyone else’s identity through a chain.
The root of trust is a chain: a self-verifying, append-only structure. Trusting the system means trusting a chain’s root link; everything else follows from following and replaying the chain.
Chain types
Every identity in the system is backed by a combination of three separate chains:
- Identity chain — Holds your personal identity and performs key management
- Profile chain — Holds profile data (display name, full name, avatar, etc.)
- Space chain — Space, short for the workspace or organization you join, this contains organisation details and member management information.
The identity chain is the anchor that vouches for the other two. It manages your keys, commits to links on your other chains, and links all your other devices together.
Why trust a chain?
Because each link hashes the one before it, they are tamper proof. A chain can be replayed at any time and independently verified as correct: you don’t have to trust anyone’s account of history, only the chain itself.
Chain structure
A chain is an append-only data structure. It’s an ordered list of ApprovedChainLinks. There are two link types: Root at the head followed by many Links.
Root link contains:
sequence_number- set to 0 indicating it’s a first link in the chain,timestamp- date of link creation,nonce- array of 32 random bytes,payload- root payload of the chain.
In code they are represented as follows:
pub struct Root<Payload> {
sequence_number: u64,
timestamp: jiff::Timestamp,
nonce: [u8; 32],
payload: Payload,
}
Each Link contains:
chain_id- id of the chain this link belongs to which is equal to a hash of the root link,sequence_number- counter representing position of the link in the chain,previous_hash- hash of the previous ApprovedChainLink,timestamp- date of link creation,payload- root payload of the chain.
pub struct Link<Payload> {
chain_id: ChainId,
sequence_number: u64,
previous_hash: FullChainLinkHash,
timestamp: jiff::Timestamp,
payload: Payload,
}
After constructing the link, next step is “approving” it, this can happen in two ways depending on the chain.
For Identity chain the links are signed using an appropriate secret key associated with the chain, the signature is then concatenated with the link to create resulting ApprovedChainLink.
In case of non-identity chains hash of the link is embedded in a CommitmentPayload, which is then added as a link to the identity chain, signed with Committing Key. The pointer to this commitment link is then concatenated with the original link in order to create ApprovedChainLink.
Given how the chains are constructed, the second link of the chain with sequence_number 1, will have chain_id and previous_hash fields equal to each other.
Why commit and not just signature?
A signature alone can’t prove when a key was valid. If a device key leaks and is later rotated, a replay years afterward can’t distinguish that something was “signed before the leak” as opposed to “signed by the leaked key after rotation”. The signature looks the same either way.
Commits solve this by making authorization itself sequential.
To sign a link on your profile chain or space chain, you first commit to it on your identity chain — a commitment link that points to the corresponding link on the other chain. Because the identity chain is strictly ordered, that commitment proves the signing key was valid at that sequence position, independent of when someone replays the history later. We “detemporalize” authorization, anchoring validity to sequence, not to blanket trust in a key.
Identity
Your identity is defined by two things:
- Identity Chain ID — the hash of your Identity Chain’s root link. This identifies you as a person across the organization.
- Identity key — identifies a specific device, registered on the identity chain. The Identity Chain’s root link contains the identity key of the that signs your identity chain links, which is how peers verify those links are legitimately yours.
Across the ecosystem, you’re identified as the combination of both, meaning this person’s identity, acting from this specific device.
As the identity system is designed today, the identity key is non-rotatable. To rotate an identity key would mean to recognize your device as a different one. That’s why the key is used almost nowhere except to sign identity chain links related to the key management, to minimize key exposure to potential attacks.
Adding more devices
Adding a new device requires vouching from an existing device.
A new identity key can only be added to the chain by a device which Identity Key is already on the chain. This makes device addition visible: peers see the new key appear as a chain link, the same way they’d see any other identity chain event, rather than a silent addition.
From that point onward, the new device will be able to act in the same way as the one that added it, as its Identity Key will be recognized as authorized to perform Identity Chain operations.
Key types and rotation
Besides the Identity Key, the Identity Chain manages several other keys, each generated randomly and committed to the chain — and each designed to be rotatable, unlike the identity key:
- Committing key — signs commitments to your other chains (profile, space) and other identities,
- Mailbox key — is used to authenticate you with your personal mailboxes,
- MLS credential key — is used to sign MLS key packages which bind the credentials to the keys used in MLS group,
Rotation follows the same mechanism as issuance: pushing a new chain link that rotates the key out, from that point onwards.
What happens in case of device compromise?
If a device is compromised, another device on your Identity Chain can revoke that device’s Identity Key, which propagates the revocation to the rest of the keys (commiting, mailbox, MLS credential) that were signed using the revoked Identity Key. If no other device is available, an admin must remove the user from the space and its chain of trust directly.
Root of trust
Every client must trust the admin who is adding them to space.
During the process of being admitted to a space, the invitee and the admin mutually exchange information mutually (using QR codes). This enables the joining client to establish trust in the Identity key presented by the admin, and consequently, all the associated chains.
The client also relies on the admin to provide all chain links relevant to the space they are entering; any failure to do so by the admin would eventually be uncovered or could prevent the client from properly verifying the identities of other members within the space.
Ultimately, the root of trust for all clients who are part of a space lies in the root link of the identity chain of the admin who established that space. By placing confidence in that chain link, any client can reconstruct the complete state of the space, provided they have all member-published liks.