Federation & Witnessing¶
Diogenes supports federated transparency logs and independent witnesses to prevent any single operator from controlling the trust infrastructure.
Federation¶
Federation allows multiple log operators to maintain replicated copies of the transparency log. This ensures that no single organization controls the canonical record of attestations and endorsements.
Architecture¶
graph LR
subgraph Leader["Leader Operator"]
LL["Transparency Log
(canonical)"]
end
subgraph F1["Follower A"]
FL1["Replicated Log"]
end
subgraph F2["Follower B"]
FL2["Replicated Log"]
end
Leader -- "Replication API" --> F1
Leader -- "Replication API" --> F2
- Leader -- The primary log operator that accepts new entries (key registrations, attestations, endorsements).
- Followers -- Read-only replicas that pull entries from the leader and independently verify the hash chain.
Roles¶
| Role | Accepts writes | Replicates | Verifies chain |
|---|---|---|---|
| Leader | Yes | Serves data | Yes |
| Follower | No | Pulls from leader | Yes (independently) |
Replication Protocol¶
Followers use the replication API to synchronize:
GET /api/v1/log/replicate?after=<last_id>&limit=100-- Fetch batches of new entries- Follower independently verifies the hash chain (
previous_hashlinks) - Follower verifies signed tree heads against the operator's public key
- Follower reports status via
GET /api/v1/log/replication-status
Replication Status¶
| Status | Meaning |
|---|---|
SYNCED |
Follower is up to date with the leader |
SYNCING |
Follower is actively catching up |
BEHIND |
Follower is behind but not actively syncing |
ERROR |
Replication has encountered an error |
Setting Up Federation¶
1. Authorize a follower (on the leader)¶
The follower must first register a key on the leader's log, then the operator authorizes it:
This issues an x-diogenes:federation_operator endorsement.
2. Configure the follower¶
Set environment variables for the follower instance:
DIOGENES_FEDERATION_ROLE=follower
DIOGENES_FEDERATION_OPERATORS='[{"url": "https://leader.example.com", "fingerprint": "<leader-operator-fp>"}]'
3. Set a profile (optional)¶
diogenes operator set-profile --type federation \
--display-name "EU Mirror" \
--server http://follower.example.com:8000
4. Monitor federation¶
# List authorized followers
diogenes operator list-followers
# Check replication status (API)
curl https://leader.example.com/api/v1/log/replication-status
Security Properties¶
- Followers independently verify the hash chain -- a compromised leader cannot silently alter history without detection.
- Signed tree heads provide cryptographic proof of log state at a point in time.
- Federation does not use Byzantine fault tolerance in v1; it follows a simple leader-follower model.
Witnessing¶
Witnesses are independent third parties that monitor the transparency log for consistency. They provide external verification that the log operator is not tampering with the record.
How Witnessing Works¶
sequenceDiagram
participant W as Witness
participant S as Server (Leader)
W->>S: GET /api/v1/log/sth
S->>W: {tree_size, root_hash, signature, ...}
Note over W: Compare with previous observation
Note over W: Sign consistency proof (Ed25519)
W->>S: POST /api/v1/log/witness
{old_tree_size, old_root,
new_tree_size, new_root,
signature}
S->>W: {proof_id, recorded}
Note over S: Proof recorded on
transparency log
- The witness fetches the current tree head (Merkle root and tree size) from the server.
- It compares with its previous observation (stored locally in
~/.diogenes/witness/state.json). - It signs a consistency proof with its Ed25519 key, attesting that the log has only grown (no entries removed or rewritten).
- It submits the proof to the server, where it is recorded on the transparency log.
Witness Key Management¶
- Witnesses auto-generate an Ed25519 key at
~/.diogenes/witness/witness.pemon first use. - The key fingerprint is a 16-character SHA-256 prefix of the public key.
- The witness must be authorized by the operator before proofs are accepted.
Setting Up a Witness¶
1. Generate the witness key¶
2. Authorize the witness (on the operator)¶
3. Submit a proof¶
On first submission, the baseline is tree_size=0. Each subsequent submission chains from the previous observation.
4. Check status and history¶
# Check authorization
diogenes witness status --server http://localhost:8000
# View submitted proofs
diogenes witness history --server http://localhost:8000 --limit 10
5. Set a display profile (optional)¶
diogenes operator set-profile --type witness \
--display-name "Community Witness" \
--server http://localhost:8000
API Endpoints¶
| Endpoint | Method | Description |
|---|---|---|
/api/v1/log/sth |
GET | Latest signed tree head (tree size, root, signature) |
/api/v1/log/witness |
POST | Submit a signed consistency proof |
/api/v1/log/witnesses |
GET | List all witness proofs (paginated) |
Security Properties¶
- Witnesses are independent -- they run their own software and store their own keys.
- A witness proof attests that the log is append-only: no entries have been removed or altered since the last observation.
- Multiple independent witnesses increase confidence in log integrity.
- Witness proofs are themselves recorded on the transparency log, creating a verifiable audit trail.
Federation + Witnessing Together¶
In a production deployment, federation and witnessing complement each other:
graph TD
L["Leader Operator"] --> F1["Follower A"]
L --> F2["Follower B"]
W1["Witness 1"] -->|monitors| L
W2["Witness 2"] -->|monitors| L
W3["Witness 3"] -->|monitors| F1
- Federation ensures the log data is replicated and available even if the leader goes offline.
- Witnessing ensures no operator (leader or follower) has tampered with the log.
- Consumers can check witness proofs to verify log integrity before trusting verification results.