# paragonie/chronicle architecture

> Architecture diagram of the GitHub repository paragonie/chronicle, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/paragonie/chronicle
- Repository: https://github.com/paragonie/chronicle

## Overview

Chronicle is a self-hosted HTTP service for authorized clients to publish signed messages into an append-only cryptographic ledger, then query and export its records. The main path is HTTP request → route and signature validation → publish handler → hash-chain append → database. Administrators can register and revoke clients; public endpoints expose ledger lookups and replica information. The README also documents cross-signing and replication. The sampled source confirms the replication process; cross-signing and other handler internals were not sampled, so their wiring is shown only where supported.

Main entry points: [`src/routes.php`](https://github.com/paragonie/chronicle/blob/master/src/routes.php) (Routes), [`src/Chronicle/Chronicle.php`](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Chronicle.php) (Chronicle core), [`src/Chronicle/Process/Replicate.php`](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Process/Replicate.php) (Replication process), [`public/index.php`](https://github.com/paragonie/chronicle/blob/master/public/index.php) (HTTP entry)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_http["HTTP API"]
  node_entry["HTTP entry<br/>[index.php]"]
  node_routes["Routes<br/>[routes.php]"]
  node_publish["Publish<br/>[Publish.php]"]
  node_lookup["Lookup<br/>[Lookup.php]"]
  node_index["API index<br/>[Index.php]"]
  node_mirrors["Mirror list<br/>[Mirrors.php]"]
  node_replicaapi["Replica API<br/>[Replica.php]"]
end

subgraph group_security["Authorization"]
  node_clientauth["Client signature"]
  node_adminauth["Admin signature"]
  node_register["Register client<br/>[Register.php]"]
  node_revoke["Revoke client<br/>[Revoke.php]"]
end

subgraph group_ledger["Ledger"]
  node_chronicle["Chronicle core<br/>[Chronicle.php]"]
  node_database["Database setup<br/>[database.php]"]
  node_store[("Ledger database")]
end

subgraph group_federation["Federation"]
  node_crosssign["Cross-signing<br/>[CrossSign.php]"]
  node_attest["Attestation<br/>[Attest.php]"]
  node_replicate["Replication process<br/>[Replicate.php]"]
  node_scheduler["Scheduled tasks<br/>[Scheduled.php]"]
end

node_client(("API client"))
node_admin(("Administrator"))
node_upstream(("Upstream Chronicle"))

node_client -->|"sends request"| node_entry
node_admin -->|"sends request"| node_entry
node_entry -->|"runs routes"| node_routes
node_routes -->|"guards publish"| node_clientauth
node_routes -->|"guards admin"| node_adminauth
node_routes -->|"dispatches"| node_publish
node_routes -->|"dispatches"| node_register
node_routes -->|"dispatches"| node_revoke
node_routes -->|"dispatches"| node_lookup
node_routes -->|"dispatches"| node_index
node_routes -->|"dispatches"| node_mirrors
node_routes -->|"dispatches"| node_replicaapi
node_clientauth -->|"verifies client"| node_chronicle
node_adminauth -->|"verifies admin"| node_chronicle
node_publish -->|"appends entry"| node_chronicle
node_register -->|"manages clients"| node_chronicle
node_revoke -->|"manages clients"| node_chronicle
node_lookup -->|"queries ledger"| node_chronicle
node_replicaapi -->|"serves replica data"| node_chronicle
node_index -->|"reads client access"| node_chronicle
node_database -->|"sets database"| node_chronicle
node_chronicle -->|"reads and writes"| node_store
node_replicate -->|"reads and writes replica"| node_store
node_replicate -->|"fetches signed updates"| node_upstream
node_scheduler -->|"runs replication"| node_replicate
node_crosssign -.->|"cross-signs"| node_upstream
node_attest -.->|"attests replica"| node_replicate

click node_entry "https://github.com/paragonie/chronicle/blob/master/public/index.php"
click node_routes "https://github.com/paragonie/chronicle/blob/master/src/routes.php"
click node_publish "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Publish.php"
click node_lookup "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Lookup.php"
click node_index "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Index.php"
click node_mirrors "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Mirrors.php"
click node_replicaapi "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Replica.php"
click node_clientauth "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Middleware/CheckClientSignature.php"
click node_adminauth "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Middleware/CheckAdminSignature.php"
click node_register "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Register.php"
click node_revoke "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Revoke.php"
click node_chronicle "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Chronicle.php"
click node_database "https://github.com/paragonie/chronicle/blob/master/src/database.php"
click node_crosssign "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Process/CrossSign.php"
click node_attest "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Process/Attest.php"
click node_replicate "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Process/Replicate.php"
click node_scheduler "https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Scheduled.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_routes,node_publish,node_lookup,node_index,node_mirrors,node_replicaapi,node_client toneBlue
class node_clientauth,node_adminauth,node_register,node_revoke toneAmber
class node_chronicle,node_database,node_store toneMint
class node_crosssign,node_attest,node_replicate,node_scheduler toneRose
class node_admin,node_upstream toneIndigo
```

## Components

### HTTP API

- [HTTP entry](https://github.com/paragonie/chronicle/blob/master/public/index.php): `public/index.php`
- [Routes](https://github.com/paragonie/chronicle/blob/master/src/routes.php): `src/routes.php`
- [Publish](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Publish.php): `src/Chronicle/Handlers/Publish.php`
- [Lookup](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Lookup.php): `src/Chronicle/Handlers/Lookup.php`
- [API index](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Index.php): `src/Chronicle/Handlers/Index.php`
- [Mirror list](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Mirrors.php): `src/Chronicle/Handlers/Mirrors.php`
- [Replica API](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Replica.php): `src/Chronicle/Handlers/Replica.php`

### Authorization

- [Client signature](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Middleware/CheckClientSignature.php): `src/Chronicle/Middleware/CheckClientSignature.php`
- [Admin signature](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Middleware/CheckAdminSignature.php): `src/Chronicle/Middleware/CheckAdminSignature.php`
- [Register client](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Register.php): `src/Chronicle/Handlers/Register.php`
- [Revoke client](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Handlers/Revoke.php): `src/Chronicle/Handlers/Revoke.php`

### Ledger

- [Chronicle core](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Chronicle.php): `src/Chronicle/Chronicle.php`
- [Database setup](https://github.com/paragonie/chronicle/blob/master/src/database.php): `src/database.php`
- **Ledger database**

### Federation

- [Cross-signing](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Process/CrossSign.php): `src/Chronicle/Process/CrossSign.php`
- [Attestation](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Process/Attest.php): `src/Chronicle/Process/Attest.php`
- [Replication process](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Process/Replicate.php): `src/Chronicle/Process/Replicate.php`
- [Scheduled tasks](https://github.com/paragonie/chronicle/blob/master/src/Chronicle/Scheduled.php): `src/Chronicle/Scheduled.php`

### Other components

- **API client**
- **Administrator**
- **Upstream Chronicle**

## Connections

- API client → HTTP entry: sends request
- Administrator → HTTP entry: sends request
- HTTP entry → Routes: runs routes
- Routes → Client signature: guards publish
- Routes → Admin signature: guards admin
- Routes → Publish: dispatches
- Routes → Register client: dispatches
- Routes → Revoke client: dispatches
- Routes → Lookup: dispatches
- Routes → API index: dispatches
- Routes → Mirror list: dispatches
- Routes → Replica API: dispatches
- Client signature → Chronicle core: verifies client
- Admin signature → Chronicle core: verifies admin
- Publish → Chronicle core: appends entry
- Register client → Chronicle core: manages clients
- Revoke client → Chronicle core: manages clients
- Lookup → Chronicle core: queries ledger
- Replica API → Chronicle core: serves replica data
- API index → Chronicle core: reads client access
- Database setup → Chronicle core: sets database
- Chronicle core → Ledger database: reads and writes
- Replication process → Ledger database: reads and writes replica
- Replication process → Upstream Chronicle: fetches signed updates
- Scheduled tasks → Replication process: runs replication
- Cross-signing → Upstream Chronicle: cross-signs
- Attestation → Replication process: attests replica
