Bring Your Own Storage
Swap the default Postgres + object store for your own backends.
Overview
sovseal is designed around a decoupled storage architecture. You can swap out the default Supabase/Postgres engine for your own database and object storage backends.
+--------------------------------------------------------+
| API Edge |
+--------------------------+-----------------------------+
|
v
+--------------------------+-----------------------------+
| Storage Driver Interface |
+------------+-------------+--------------+--------------+
| | |
v v v
[Postgres] [S3] [Cloudflare R2]The Blind-Ciphertext Contract
Regardless of the storage provider you configure, you must adhere to the blind-ciphertext contract:
[!IMPORTANT] Strict Storage Driver Contract
- The storage driver MUST NOT attempt to decrypt or examine the payload content.
- The storage driver processes only encrypted bytes, random initialization vectors (IVs), cryptographic tags, and metadata (hashed IDs, sequences, and timestamps).
- All encryption/decryption keys reside strictly on client devices.
The Storage Driver Interface
To build a custom storage driver, implement the following four primitive operations:
interface StorageDriver {
/** Upload an encrypted snapshot payload. */
put(
agentId: string,
sequenceNumber: number,
payload: EncryptedEnvelope
): Promise<void>;
/** Retrieve an encrypted snapshot by its sequence number. */
get(
agentId: string,
sequenceNumber: number
): Promise<EncryptedEnvelope | null>;
/** List snapshot metadata for an agent (paginated). */
list(
agentId: string,
options: { limit: number; offset: number }
): Promise<EnvelopeMetadata[]>;
/** Delete snapshot record(s) for an agent. */
delete(
agentId: string,
sequenceNumber?: number
): Promise<void>;
}Reference Adapters
1. Amazon S3 / Cloudflare R2 Adapter
You can store the encrypted payloads in any S3-compatible bucket. Since R2 and S3 share the same API schema, the configuration is identical:
vector_store:
provider: qdrant
storage_provider: s3
storage_config:
bucket: your-encrypted-snapshots
region: us-east-1
endpoint: https://<account-id>.r2.cloudflarestorage.com
access_key_id: ${S3_ACCESS_KEY}
secret_access_key: ${S3_SECRET_KEY}2. External Postgres + pgvector Adapter
If you prefer running a single database stack, you can store both the vector records and the encrypted historical snapshots directly in Postgres:
-- Schema for storing encrypted snapshots
CREATE TABLE public.agent_state_snapshots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id VARCHAR(64) NOT NULL,
sequence_number INT NOT NULL,
wallet_balances JSONB,
active_context BYTEA NOT NULL, -- Encrypted ciphertext stored as byte array
iv VARCHAR(32) NOT NULL,
tag VARCHAR(32) NOT NULL,
client_payload_hash VARCHAR(64) NOT NULL,
timestamp TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (agent_id, sequence_number)
);
CREATE INDEX idx_snapshots_agent_seq ON public.agent_state_snapshots (agent_id, sequence_number DESC);Configure your environment connection:
vector_store:
provider: pgvector
config:
connection_string: postgresql://postgres:password@localhost:5432/sovseal