distributedtypescriptagentsinfrastructure

Memora

Encrypted memory infrastructure for AI agents with tamper-evident write/read workflows.

Status
Active · deployed
Role
Solo project
Stack
TypeScript · Node.js · Hedera HCS · Solidity · IPFS · Supabase · Express · pnpm workspaces
architecture diagramfig. 01

01Problem

Autonomous AI agents lose state between sessions. Existing approaches store memory in a relational database (fast and queryable, but not verifiable) or rely on the context window (fast, but ephemeral and expensive at scale).

Neither provides the property agent infrastructure actually needs: a tamper-evident, permissioned memory store where the write event, the payload hash, and the access permissions are independently verifiable — and where an agent can produce a proof that it wrote a specific memory at a specific time.

02Core idea

Encrypt memory payloads before they leave the agent. Record the write event in a consensus-ordered log. Commit a hash and permissions record on-chain. Keep a rebuildable query cache in a traditional database.

The authoritative record is on-chain and on IPFS. The Supabase index is a query cache — if it's dropped, it can be rebuilt from the on-chain log. The database is disposable infrastructure; the chain is not.

03Write path

The agent SDK or CLI submits a payload to the indexer. The indexer: (1) derives a canonical hash of the payload; (2) encrypts with AES-256-GCM, producing a ciphertext and symmetric key; (3) pins the ciphertext to IPFS, obtaining a content address; (4) sequences the event via Hedera HCS, obtaining a consensus timestamp and sequence number; (5) commits the payload hash, IPFS CID, and permission bitmap to the EVM registry contract; (6) releases the AES key to the key broker; (7) writes metadata to Supabase.

Ordering matters: IPFS pin first (data is durable before any record is made), then HCS (the ordering anchor), then EVM registry, then key broker, then cache. Failure at any stage is idempotent and re-runnable — the pipeline can resume from the last completed step without duplicating the on-chain record.

04Read path

The agent issues a read request with a challenge token. The indexer verifies the agent's identity against the on-chain permission bitmap (owner or delegate state). On success: retrieve the AES key from the key broker, fetch the ciphertext from IPFS, decrypt, recompute the canonical hash, compare against the on-chain record. A mismatch means the ciphertext was modified after write — the read is rejected.

The challenge-response design means key release is gated on on-chain permission state at read time, not at write time. Permissions can be updated or revoked after the memory is written.

05Canonical hashing

Payloads are canonically serialised before hashing: key ordering is normalised, whitespace stripped, and numeric values coerced to a canonical form. This ensures the same logical payload produces the same hash regardless of how it was serialised by the caller.

The canonical hash is what the EVM registry stores and what the read path verifies. It is the binding between the on-chain record and the IPFS ciphertext — any modification to the ciphertext breaks the hash check.

06SDK and CLI

TypeScript monorepo with pnpm workspaces. The SDK exposes typed `write`, `query`, `read`, and `verify` methods. The CLI wraps these for direct shell use. The indexer is an Express server deployed to Railway.

Agents interact with the SDK's typed API rather than raw cryptographic primitives. Serialisation, encryption, and proof verification are handled internally.

07Tradeoffs

The architecture is more complex than a database-backed memory store. The payoff is verifiability — the write event, payload hash, and access permissions are all independently inspectable without trusting the indexer.

Write atomicity across five storage targets without distributed transactions requires careful ordering and idempotent retry logic. A failed HCS step leaves an orphaned IPFS pin; a failed EVM step leaves an HCS record pointing to a pin that isn't registered. Both are recoverable but require explicit cleanup paths.

The Supabase index can be stale if an indexer write fails after the on-chain record is committed. Queries against a stale index may miss recent writes. The index is authoritative for query performance, not correctness.

08Known limitations

Raw key release. The key broker returns AES keys directly in the API response. There is no envelope encryption or client-side key derivation. A compromised transport or broker breach exposes the symmetric key. Envelope encryption is the correct fix.

Unauthenticated write endpoint. The write endpoint does not require agent authentication — any caller with access to the indexer endpoint can write a memory record. The on-chain permission model gates reads, not writes. Authenticated writes are a planned addition.

Async HCS backfill. Hedera HCS confirmation is asynchronous. The indexer marks writes as pending until HCS confirms, but the Supabase index may be queryable before the HCS timestamp is finalised. This window is short in practice but is not zero.

Single operator model. The key broker is a centrally operated service — a single point of failure for key retrieval. Threshold cryptography or distributed key generation would remove this assumption at significant operational cost.

09What I learned

Key insight

Treating Supabase as a rebuildable cache rather than the source of truth creates a clean separation between queryable state and verifiable state. No need to compromise on either.

Designing for verifiability surfaces a class of architectural decisions that don't appear in application-layer work: ordering, idempotency, and the operational difference between 'the data exists' and 'the data is provably unmodified'.