Architecture

Current status: the local/mock validator runtime is the strongest implemented and tested surface. Federation between enterprise clusters is merged into the validator runtime and has passed a local two-cluster harness in mock mode; it is not deployed. The SDK, chain-backed settlement, a deployed enterprise registry, and EDS delivery integration remain experimental or target-state unless a linked evidence record says otherwise; the AEM 6.5 LTS read-only mount has one on AEM 6.5 LTS Integration.

Oak Chain is a distributed content repository that bridges Ethereum's economic security with Oak's enterprise content model.

What Oak Chain Is

What Oak Chain Is Not

System View at a Glance

One diagram covering experience surface, consensus truth, settlement and addressing, and runtime control plane. Start here for the runtime topology; the rest of this page goes deeper into each plane.

/diagrams/oak-chain-system-map-v2.svg
Oak Chain system map v2 showing experience surface, consensus truth plane, settlement and addressing plane, and runtime control-plane components

Layers

Oak (storage)

Keeps the content tree as immutable segments in TAR files. Each validator applies every ordered write to its own store.

Aeron Cluster (consensus)

Elects a leader and orders every write within one cluster. Roles, the write path and failover timing: Consensus Model.

Ethereum (settlement)

Chain-backed modes (local and sepolia) verify payment events from the configured contract, after the validator checks the RPC's chain id and the contract's code. mainnet is refused. The default mock mode simulates payment. Chain-backed payments are not yet validated. Contract and pricing: Smart Contract.

IPFS (binaries)

The default store for binary bytes. Oak identifies a binary by the SHA-256 of its content, and IPFS addresses the stored bytes by CID. With encryption on, the CID is of the ciphertext. Consensus carries the blob ID and the CID (see Storage Architecture below).

Validator API

Each validator serves source routes for consensus and operations state, plus local diagnostic routes. Route list: API.

Edge API

oak-chain-edge-worker owns /ops/v1/*, the read contract for remote dashboards and clients, built from validator source routes.

Two Deployment Models

Oak Chain has two integration patterns because the constraints are actually different.

Why two models? We started with the hard constraints:

We do not force one path. The split is simple: SDK for net-new applications, Connector for entrenched AEM estates, one validator core underneath both.

two-models

Model 1: Blockchain-Native Applications (Top Flow)

For: New applications built from scratch or modern web/mobile apps

Integration Path: Application → Oak Chain SDK → Validators → Ethereum

How it works:

  • Applications use the Oak Chain SDK (JavaScript/TypeScript) to interact with validators
  • SDK source provides REST, SSE, and signing helpers; its write-side settlement contract is still being realigned
  • Content writes go directly to validators via HTTPS API
  • In a future chain-backed deployment, validators verify settlement evidence before Aeron/Raft admission
  • Example: EDS (aem.live), React apps, Next.js sites, mobile apps

Best for:

  • New projects without existing AEM infrastructure
  • Modern JavaScript/TypeScript applications
  • Edge Delivery Services (EDS) deployments
  • Headless CMS architectures

Model 2: AEM Integration (Bottom Flow)

For: Existing Adobe Experience Manager customers

Integration Path: Validators → HTTP segment transfer → read-only /oak-chain mount in AEM 6.5 LTS

How it works:

  • The Oak Chain Connector is one OSGi bundle and an opt-in tool (preflight, enable, verify, status, disable), applied with one restart; stock Oak, no fork
  • Uses Oak's composite mount pattern to mount /oak-chain read-only
  • Inside AEM, chain content is ordinary JCR, read by path through Sling and the JCR API
  • The connector is read-only: AEM reads chain content, and writes under /oak-chain are refused. Writes go through the validator API or the SDK
  • Validators serve Oak segments over HTTP (/segments/, /journal.log, /manifest) from oak-segment-consensus
  • Supported: AEM 6.5 LTS author (Java 17 or 21, Apache Oak 2.4.0), demonstrated on SP3. AEM as a Cloud Service and AEM 6.5 (non-LTS) are not supported

Best for:

  • Organizations already running AEM
  • Teams familiar with JCR/Sling APIs
  • Reading chain content inside an existing AEM 6.5 LTS author

Shared Architecture

Both models share the same validator cluster and storage layer:

  • Validators: Raft consensus cluster storing Oak segments
  • Ethereum: On-chain settlement in local or sepolia mode (not yet validated; mock mode is the default)
  • Binary storage: Consensus carries the blob ID and CID; the bytes stay in IPFS, on a validator's node or on an author's node referenced by CID
  • Availability: A binary's identity is the SHA-256 of its content, checked on every read. Without IPFS Cluster, a binary is available only while the node that stored it is. With IPFS Cluster configured, a write is acknowledged only after the configured minimum of peers hold it.
Key insight: Oak consensus keeps binary references out of segment payloads. Binary availability is supplied separately by the configured author- or validator-hosted storage path.

Understanding the Diagram

The diagram above shows both integration models side-by-side:

  • Top flow (Model 1): blockchain-native applications such as EDS connect directly to validators over HTTPS
  • Bottom flow (Model 2): existing AEM systems mount Oak Chain over HTTP segment transfer
  • "Model 1" and "Model 2" labels: visual labels only, not functional nodes in the data path
  • Shared binary storage: both models reference the same author- or validator-configured BlobStore

Both target paths converge on the same validator core. Chain-backed settlement and production integration remain deployment gates, not assumptions.

The Three Operational Planes

Oak Chain works best when you think of it as many sovereign validator clusters, not one giant consensus mesh.

Operationally, each validator cluster behaves like an AEM/Oak fiefdom:

Everything else is a separate plane.

┌─────────────────────────────────────────────────────────────┐
│  Plane 3: Federation Directory                              │
│  Charter, directory epochs, namespace owners, endpoints     │
├─────────────────────────────────────────────────────────────┤
│  Plane 2: Cross-Cluster Reads                               │
│  Lazy read-only mounts, HTTP segment transfer               │
├─────────────────────────────────────────────────────────────┤
│  Plane 1: Intra-Cluster Consensus                           │
│  Aeron cluster, local writes, authoritative repository      │
└─────────────────────────────────────────────────────────────┘

Visual companion: the three-plane model and the consensus sequence inside one cluster are explored end-to-end with code anchors in the Write Flow + Content Fabric visual. Open the write-flow plate for the consensus sequence; the content-fabric plate for the clusters-of-clusters model.

Plane 1: Intra-Cluster Consensus

Aeron consensus is local to one authoritative cluster.

Consensus never spans multiple clusters. A write must land on the cluster whose enterprise owns the namespace. Inside that cluster:

  • validators elect a leader
  • the leader verifies the write and payment
  • Aeron replicates the command to followers
  • the local authoritative repository commits the change

A write for another cluster's namespace is refused before it is queued. With a committed federation directory, the answer is 307 wrong_cluster with the owner's endpoints. On a cluster that uses static prefix routes, it is 307 wrong_shard. An unclaimed namespace answers 403 namespace_unclaimed (federated) or 503 shard_unclaimed (static routes). The full list is under Write routing and authority below.

Content Ownership

An Ethereum address is the namespace root.

/oak-chain/{L1}/{L2}/{L3}/0x{address}/...
  • {L1}/{L2}/{L3} - First 6 hex chars of the address (e.g., 74/2d/35)
  • 0x{address} - Full Ethereum address of the namespace
  • {organization} - Optional organization/brand scope below the namespace root
  • content/ - Standard AEM content root when used

Example:

/oak-chain/74/2d/35/0x742d35cc6634c0532925a3b844bc9e7595f0beb0/
    ├── PixelPirates/content/       ← Gaming brand
    ├── CryptoKitchenware/content/  ← eCommerce brand
    └── PersonalBlog/content/       ← Personal content

Path segments are lower-case. A namespace segment is 0x followed by 40 lower-case hex characters, and the three levels above it must match the address. The levels give every namespace one fixed root, and no single node lists every namespace as a direct child. Remote mounts attach at these roots.

Without a federation directory, the leader accepts a write only under the signer's own address root. With a directory, the validator that receives the request, the leader's queue and replicated apply make the same decision from the committed directory: the namespace's own wallet or one of its enterprise's listed writers may write, and only while the enterprise is ACTIVE. Cluster operation and membership remain operator-governed.

Plane 2: Cross-Cluster Reads

Other enterprises' namespaces are mounted lazily and read-only.

Each validator mounts the namespaces of every other ACTIVE enterprise in the committed directory over HTTP segment transfer. Without a directory, it mounts the clusters named in its static prefix routes. Those remote mounts are:

  • read-only
  • outside Aeron and off the local commit path
  • allowed to fail without making the local authoritative store unwritable

Reads under an unavailable mount answer 503 mount_unavailable, not empty content. This is how the network gets a shared read view without turning all clusters into one consensus system.

Plane 3: Federation Directory

The directory is replicated input to write authority. It is not a second consensus.

The federation directory answers:

  • which enterprises exist, and their status
  • which namespaces each enterprise owns, and which wallets may write them
  • where each enterprise's validators are reachable

Each cluster commits the directory through its own log and reports it at GET /v1/federation. Every write decision it drives can be traced to the committed directory and to the error codes above. Signed announcements and gossip are not implemented. Details: Federation directory, below.

Supporting Concerns

Payment, economics, and visual naming are separate from the three planes.

  • Cluster = economic unit
  • Internal node distribution is off-chain
  • A future chain-backed admission path verifies configured settlement evidence

Enterprise Federation

This section describes code merged into the validator runtime. It is not deployed: no registry runs on Sepolia or mainnet, and no federated production cluster runs. Configuration: oak-segment-consensus README.

Enterprise clusters

An enterprise runs one validator cluster. The registry design requires 3 or 5 validators. The validator runtime does not enforce the size; the harness ran 3 per cluster.

Each cluster commits a charter once, after genesis. The charter records the enterprise id, the blockchain mode, the chain id and the registry. The cluster id is keccak256(charter ‖ genesis integrity digest). A member configured for a different charter refuses writes with 503 charter_mismatch. GET /v1/federation and /health report the committed charter and whether this member's configuration matches it.

Status: merged, not deployed.

Namespaces

A namespace is an Ethereum address. Its content lives under /oak-chain/XX/YY/ZZ/0x<address>/, where XX/YY/ZZ are the first six hex characters of the address.

An enterprise holds one or more namespaces, usually one per business unit. A namespace may be written by its own wallet or by any wallet the enterprise lists as a writer. A listed writer may write into every namespace of its enterprise. A node created by a listed writer records the namespace, not the writer, as its owner. The zero address is reserved for genesis and cannot be claimed.

In the EnterpriseRegistry contract, an enterprise's admin wallet (a Safe) adds namespaces, sets writers and sets endpoints. Each namespace must sign its own claim (EIP-712 NamespaceClaim). An enterprise can hold at most 8 namespaces and 32 writers. Reference: the EnterpriseRegistry contract in oak-chain-smart-contracts.

Status: the contract is merged with tests. It is not deployed to Sepolia or mainnet.

Federation directory

The federation directory lists every enterprise: its status (PENDING, ACTIVE, SUSPENDED or RETIRED), signer set and threshold, member endpoints, namespaces and writers. Namespaces are disjoint across enterprises.

Each cluster's leader reads the directory and proposes it as a DIRECTORY_UPDATE command. Every member applies it to a hidden :directory node. A snapshot is accepted only if:

The directory comes from one of two sources:

Status: the static source has run in the live harness. The registry reader has unit tests and an opt-in test against a local Hardhat chain. No registry is deployed.

Write routing and authority

Once a directory is committed, three places make the same decision from it: the validator that receives the request, the leader's queue, and replicated apply on every member.

Data Table
Case
Answer
Namespace owned by this cluster's enterprise, signer allowed, enterprise ACTIVE
202, queued
Namespace owned by another enterprise
307 wrong_cluster, with that enterprise's endpoints
Owner lists no endpoints
503 owner_unreachable
No enterprise owns the namespace
403 namespace_unclaimed
Signer is not the namespace wallet or a listed writer
403 writer_not_authorized
This cluster's enterprise is not ACTIVE
503 enterprise_inactive
namespace parameter on a cluster without a directory
400 namespace_requires_federation

Apply rejects any mutation the committed directory does not allow, so every member skips it identically. This includes a write queued before a directory update that revoked the writer.

A cluster without a directory keeps the older rules: static prefix routes at ingress, and the own-address check in the leader's queue.

Status: unit tests, and the live harness smoke run (58 of 58 required assertions).

Reading another enterprise's content

Each validator mounts the namespaces of every other ACTIVE enterprise, read-only, at their address roots. Local and unclaimed paths stay on the local store. Each remote enterprise is one Oak mount.

A mount reads from the first listed endpoint that passes an identity check: GET {endpoint}/v1/federation must report the entry's enterpriseId, and its clusterId when the entry pins one. The check uses a 2 s connect timeout and a 5 s request timeout. A mount fails over in list order when an endpoint's circuit breaker opens. With no usable endpoint, reads under the mount answer 503 mount_unavailable instead of empty content. Remote reads stay off the local commit path. Mounts follow each new committed directory epoch.

Status: unit tests. The live harness failover run (30 of 30 required assertions) stopped the endpoint the other cluster was mounting from. Every mount failed over in about 3.3 s, and no read returned missing content.

Trust boundaries

Evidence and limits

The harness is the federation 3x2 smoke and failover tests in oak-chain-infra. Both runs used one host, mock mode, a static directory file and the validator built from the enterprise-federation change (06e6ca7925).

Data Table
Demonstrated
Not yet
Unit tests for charter, directory, authority, mounts, identity check and registry reader
A registry deployed on Sepolia or mainnet
Local harness, 2 clusters of 3 validators on one host, mock mode, static directory: smoke 58/58, one mount failover 30/30
Multi-host federation, chain-backed federation, and a pinned clusterId in a live run
Remote mount unavailability reported as 503
Validators signing head attestations; signatures that cover the namespace
A directory-aware SDK or connector. Only the infra oak-chain tx --namespace command sends namespace.
A harness run of the merged runtime (IPFS, federation and GC changes together): smoke 58/58, GC scenario 40/40
Federation and GC across several hosts
Segment and binary GC on one cluster while another cluster reads its content through a mount, with no missing read, 503 or 500
Garbage collection under sustained write load

Cluster Topology

The network adds enterprises by adding clusters. Each enterprise cluster owns the namespaces the federation directory lists for its enterprise: one local writable repository, plus lazy read-only views of other enterprises' namespaces. Two federated clusters have passed a local harness on one host in mock mode; no multi-host or chain-backed federation has run.

graph TB
    subgraph ClusterA["Cluster A"]
        direction LR
        LA["Leader +
Followers"]
        SA["owned
read-write"]
        MA["remote
read-only"]
        LA --> SA
        LA -.-> MA
    end
    subgraph ClusterB["Cluster B"]
        direction LR
        LB["Leader +
Followers"]
        SB["owned
read-write"]
        MB["remote
read-only"]
        LB --> SB
        LB -.-> MB
    end
    subgraph ClusterDots["..."]
        direction LR
        LD["Cluster 3..N-1"]
    end
    subgraph ClusterN["Cluster N"]
        direction LR
        LN["Leader +
Followers"]
        SN["owned
read-write"]
        MN["remote
read-only"]
        LN --> SN
        LN -.-> MN
    end
    SA <-->|"HTTP"| MB
    SA <-->|"HTTP"| MN
    SB <-->|"HTTP"| MA
    SB <-->|"HTTP"| MN
    SN <-->|"HTTP"| MA
    SN <-->|"HTTP"| MB
    style SA fill:#4ade80,color:#000
    style SB fill:#4ade80,color:#000
    style SN fill:#4ade80,color:#000
    style MA fill:#64748b,color:#fff
    style MB fill:#64748b,color:#fff
    style MN fill:#64748b,color:#fff
    style LA fill:#627EEA,color:#fff
    style LB fill:#627EEA,color:#fff
    style LN fill:#627EEA,color:#fff
    style LD fill:#1a1a2e,color:#888

Each cluster is sovereign over its own namespaces and mounts other enterprises' namespaces read-only. Consensus stays local.

Data Table
Cluster A (enterprise A)
Cluster B (enterprise B)
Writes
Namespaces the directory lists for enterprise A
Namespaces the directory lists for enterprise B
Reads
Own namespaces, plus B's through a read-only mount
Own namespaces, plus A's through a read-only mount

Clusters without a committed directory fall back to static prefix routes (oak.sharding.*), where each cluster owns a range of first address bytes, for example 00-7f. A first committed directory replaces those routes.

Scale limits

The directory lists namespaces explicitly. The registry allows at most 8 namespaces and 32 writers per enterprise. On the read side:

Current boundary: no scaling benchmark exists. Benchmark each deployment with its actual payloads, storage, and network topology. Cross-cluster reads today use:

Storage Architecture

Why Oak segments? Current evidence covers local/test validator stores. TB-scale operation remains an engineering target that requires deployment-specific validation.

Oak segments are immutable and the journal is append-only. Segment IDs are random UUIDs, not content hashes. The scale work is lazy segment fetching, member-local GC, and disciplined sync boundaries; no TB-scale public benchmark is currently claimed.

Oak Segments

Content stored in Oak's TAR segment format:

Binary References

Consensus stores the blob ID and the CID:

graph LR
    subgraph Oak["Oak Segment Store"]
        META[Metadata + blob ID + CID]
    end
    subgraph IPFS["IPFS nodes"]
        BIN[Binary Content]
    end
    META -->|CID| BIN
    style META fill:#627EEA,color:#fff
    style BIN fill:#4ade80,color:#000

Run validator IPFS nodes in a private swarm (IPFS_NETWORK_POLICY=private). The default policy only warns. Without encryption keys, anyone who reaches a node and knows a CID can read the bytes.

Cross-Cluster Mounts over HTTP

Oak Chain content is mounted read-only over HTTP segment transfer: validators serve /segments/, /journal.log and /manifest. AEM 6.5 LTS author mounts it with the Oak Chain Connector's mount bundle, which carries its own HTTP client and Apache Oak 2.4.0 Segment Tar. Federated validator clusters mount each other with the consensus/mount/http package in oak-segment-consensus. They have passed a local harness on one host in mock mode and are not deployed.

aem-integration

Platforms (the validator's own OSGi bundle is not a drop-in for stock AEM or Oak; AEM uses the connector instead):

The goal is horizontal read scaling without consensus overhead. See AEM 6.5 LTS Integration for setup instructions.

Next Steps