Skip to main content

E2E encrypted portable AI memory — your context travels with you

Project description

vault-sync

End-to-end encrypted portable AI memory with CRDT sync

Quick StartInstallationAPI ReferenceArchitectureContributing


What is vault-sync?

vault-sync is a portable, encrypted memory layer for AI applications. It lets you store, retrieve, and sync conversations, facts, and context across devices and sessions—without ever exposing your data in plaintext.

Think of it as a personal brain for your AI: it remembers what matters, keeps it private, and stays in sync across all your devices.

Key Features

  • End-to-End Encryption – Your data is encrypted locally with NaCl before it ever leaves your machine
  • CRDT Sync – Conflict-free replicated data types enable seamless multi-device synchronization
  • Vector Clocks – Precise causality tracking for perfect merge semantics
  • SQLite Storage – Lightweight, zero-config, portable database
  • LangChain & Anthropic Ready – First-class integrations with popular AI frameworks
  • 22 Passing Tests – Battle-tested reliability

The Problem: AI Amnesia

Every time you start a new conversation with an AI, it forgets everything. Your preferences, your context, your history—gone.

Today: "I prefer dark mode and use Python 3.12"
Tomorrow: "What's my preference?" → "I don't know you"

vault-sync solves this by giving your AI a persistent, encrypted memory that travels with you.


How It Works

Encryption Flow

Your data is encrypted client-side before storage:

┌─────────────────────────────────────────────────────────────┐
│                     ENCRYPTION FLOW                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────┐    ┌──────────────┐    ┌──────────────────┐   │
│  │ plaintext│───▶│ VaultCrypto  │───▶│ encrypted_blob   │   │
│  │  (JSON)  │    │  (NaCl/box)  │    │  (stored in DB)  │   │
│  └──────────┘    └──────────────┘    └──────────────────┘   │
│       │                │                     │               │
│       │                ▼                     │               │
│       │         ┌──────────────┐             │               │
│       │         │  Per-device  │             │               │
│       │         │  key pairs   │             │               │
│       │         └──────────────┘             │               │
│       │                                      │               │
│       ▼                                      ▼               │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              Encrypted SQLite Store                   │   │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐              │   │
│  │  │ memory1 │  │ memory2 │  │ memory3 │  ...          │   │
│  │  └─────────┘  └─────────┘  └─────────┘              │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

CRDT Sync

Conflicts are resolved automatically using vector clocks:

┌─────────────────────────────────────────────────────────────┐
│                       CRDT SYNC                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Device A                    Device B                       │
│  ┌─────────────┐            ┌─────────────┐                │
│  │ VC: {A:3}   │            │ VC: {A:2,B:1}│                │
│  │ memories... │            │ memories... │                │
│  └──────┬──────┘            └──────┬──────┘                │
│         │                          │                        │
│         │    ┌────────────────┐    │                        │
│         └───▶│  Sync Manager  │◀───┘                        │
│              │                │                             │
│              │  1. Merge VCs  │                             │
│              │  2. Resolve    │                             │
│              │     conflicts  │                             │
│              │  3. Replicate  │                             │
│              └───────┬────────┘                             │
│                      │                                      │
│                      ▼                                      │
│              ┌──────────────┐                               │
│              │  Merged VC:  │                               │
│              │  {A:3, B:1}  │                               │
│              └──────────────┘                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Vector Clock Tracking

Every mutation is tracked with a vector clock for perfect causality:

┌─────────────────────────────────────────────────────────────┐
│                    VECTOR CLOCKS                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Timeline:                                                  │
│                                                             │
│  t1: {A:1}          → Device A writes                       │
│  t2: {A:1, B:1}     → Device B joins                        │
│  t3: {A:2, B:1}     → Device A writes again                 │
│  t4: {A:2, B:2}     → Device B writes                       │
│  t5: {A:3, B:2}     → Device A writes (concurrent?)         │
│                                                             │
│  Merge at t5:                                               │
│  ┌────────────────────────────────────────────────────┐     │
│  │  If VC(A) > VC(B): A wins                         │     │
│  │  If VC(B) > VC(A): B wins                         │     │
│  │  If concurrent:    last-write-wins by timestamp    │     │
│  └────────────────────────────────────────────────────┘     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Installation

# From PyPI (when published)
pip install vault-sync

# From source
git clone https://github.com/your-org/vault-sync.git
cd vault-sync
pip install -e ".[dev]"

Requirements

  • Python 3.10+
  • SQLite 3.35+
  • pynacl
  • langchain (optional)
  • anthropic (optional)

Quick Start

from vault_sync import VaultStore, VaultCrypto

# Initialize with encryption
crypto = VaultCrypto.generate_keypair()
store = VaultStore(crypto=crypto)

# Store a memory
store.put(
    key="user_preferences",
    value={"theme": "dark", "language": "en", "timezone": "UTC-5"},
    tags=["preferences", "ui"]
)

# Retrieve it
prefs = store.get("user_preferences")
print(prefs)  # {'theme': 'dark', 'language': 'en', 'timezone': 'UTC-5'}

# Search memories
results = store.search(query="dark mode")

Python API Reference

VaultStore

class VaultStore:
    def __init__(self, crypto: VaultCrypto, db_path: str = "vault.db"):
        """Initialize the vault store with encryption keys."""

    def put(self, key: str, value: dict, tags: List[str] = None) -> str:
        """Store an encrypted memory. Returns the memory ID."""

    def get(self, key: str) -> Optional[dict]:
        """Retrieve and decrypt a memory by key."""

    def search(self, query: str = None, tags: List[str] = None) -> List[dict]:
        """Search memories by query or tags."""

    def delete(self, key: str) -> bool:
        """Delete a memory by key."""

    def list_all(self) -> List[dict]:
        """List all stored memories."""

    def sync(self, remote: 'VaultStore') -> SyncResult:
        """Sync with another vault store using CRDT merge."""

VaultCrypto

class VaultCrypto:
    @classmethod
    def generate_keypair(cls) -> 'VaultCrypto':
        """Generate a new NaCl keypair for encryption."""

    def encrypt(self, plaintext: bytes) -> bytes:
        """Encrypt data with the public key."""

    def decrypt(self, ciphertext: bytes) -> bytes:
        """Decrypt data with the private key."""

    def export_public_key(self) -> str:
        """Export the public key (safe to share)."""

VectorClock

class VectorClock:
    def __init__(self, node_id: str):
        """Initialize a vector clock for a specific node."""

    def increment(self) -> None:
        """Increment the local counter."""

    def merge(self, other: 'VectorClock') -> 'VectorClock':
        """Merge with another vector clock (takes element-wise max)."""

    def happens_before(self, other: 'VectorClock') -> bool:
        """Check if this event happened before another."""

    def concurrent_with(self, other: 'VectorClock') -> bool:
        """Check if events are concurrent."""

LangChain Integration

Use vault-sync as a memory backend for LangChain:

from langchain.memory import ConversationBufferMemory
from vault_sync.integrations.langchain import VaultSyncMemory

# Initialize with vault-sync backend
vault = VaultStore(crypto=crypto)
memory = VaultSyncMemory(vault=vault, return_messages=True)

# Use in a chain
from langchain.chains import ConversationChain
from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(model="claude-sonnet-4-20250514")
chain = ConversationChain(llm=llm, memory=memory)

# Conversations are automatically encrypted and stored
response = chain.predict(input="My name is Alice")
response = chain.predict(input="What's my name?")  # Remembers!

Anthropic Integration

Direct integration with Anthropic's API:

from vault_sync.integrations.anthropic import AnthropicMemory

# Initialize
memory = AnthropicMemory(vault=vault)

# Store facts
memory.store_fact("User prefers concise responses", importance="high")
memory.store_fact("User is working on a Python project", importance="medium")

# Retrieve context for a prompt
context = memory.get_context(limit=10)
system_prompt = f"Previous context:\n{context}\n\nRespond to the user."

# Use with Anthropic API
import anthropic
client = anthropic.Anthropic()
message = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    system=system_prompt,
    messages=[{"role": "user", "content": "Continue where we left off"}]
)

Cross-Device Sync

vault-sync uses CRDTs to sync across devices without conflicts:

from vault_sync import VaultStore, VaultCrypto, SyncManager

# Device A (laptop)
crypto_a = VaultCrypto.generate_keypair()
store_a = VaultStore(crypto=crypto_a, db_path="vault_a.db")
store_a.put("note", {"content": "Meeting at 3pm"})

# Device B (phone) - shares the same public key
crypto_b = VaultCrypto.from_public_key(crypto_a.export_public_key())
store_b = VaultStore(crypto=crypto_b, db_path="vault_b.db")

# Sync
sync_manager = SyncManager()
result = sync_manager.sync(store_a, store_b)

print(result.merged)      # 1
print(result.conflicts)   # 0 (CRDTs resolve automatically)
print(result.clock)       # {'A': 1, 'B': 0}

Sync Modes

Mode Description Use Case
push Send local changes to remote Upload from device
pull Fetch remote changes Download to device
bidirectional Full two-way sync Default sync

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    ARCHITECTURE                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │                   Application Layer                   │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │   │
│  │  │   LangChain │  │  Anthropic  │  │   Custom    │   │   │
│  │  │ Integration │  │ Integration │  │     App     │   │   │
│  │  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘   │   │
│  └─────────┼────────────────┼────────────────┼───────────┘   │
│            │                │                │               │
│            ▼                ▼                ▼               │
│  ┌──────────────────────────────────────────────────────┐   │
│  │                   Core Layer                          │   │
│  │  ┌──────────────────────────────────────────────┐    │   │
│  │  │              VaultStore                       │    │   │
│  │  │  • put / get / delete / search / list_all    │    │   │
│  │  │  • sync (CRDT merge)                         │    │   │
│  │  └──────────────────────────────────────────────┘    │   │
│  └──────────────────────────────────────────────────────┘   │
│                           │                                 │
│            ┌──────────────┼──────────────┐                  │
│            ▼              ▼              ▼                  │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │ VaultCrypto │  │ VectorClock │  │  SyncManager│         │
│  │             │  │             │  │             │         │
│  │ • encrypt   │  │ • merge     │  │ • push      │         │
│  │ • decrypt   │  │ • compare   │  │ • pull      │         │
│  │ • keypairs  │  │ • track     │  │ • bidir     │         │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘         │
│         │                │                │                 │
│         ▼                ▼                ▼                 │
│  ┌──────────────────────────────────────────────────────┐   │
│  │                  Storage Layer                        │   │
│  │  ┌──────────────────────────────────────────────┐    │   │
│  │  │              SQLite Database                  │    │   │
│  │  │  • memories table (encrypted blobs)          │    │   │
│  │  │  • vector_clocks table (causality tracking)  │    │   │
│  │  │  • sync_metadata table (sync state)          │    │   │
│  │  └──────────────────────────────────────────────┘    │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Contributing

We welcome contributions! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone your fork
git clone https://github.com/your-username/vault-sync.git
cd vault-sync

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linter
ruff check .

# Run type checker
mypy .

Code Style

  • Follow PEP 8
  • Use type hints everywhere
  • Write docstrings for all public APIs
  • Keep functions focused and small

Roadmap

v1.0 (Current)

  • Core VaultStore with encryption
  • VectorClock causality tracking
  • CRDT sync between devices
  • LangChain integration
  • Anthropic integration
  • 22 passing tests

v1.1 (Planned)

  • SQLite WAL mode for concurrent access
  • Export/import vault as encrypted JSON
  • Webhook notifications on sync
  • CLI tool for vault management

v2.0 (Future)

  • Distributed sync via libp2p
  • Zero-knowledge proofs for search
  • Mobile SDKs (iOS/Android)
  • Browser extension for web apps

License

MIT License - see LICENSE for details.


Built with ❤️ for the AI community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vault_sync_ai-0.1.0.tar.gz (25.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vault_sync_ai-0.1.0-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file vault_sync_ai-0.1.0.tar.gz.

File metadata

  • Download URL: vault_sync_ai-0.1.0.tar.gz
  • Upload date:
  • Size: 25.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for vault_sync_ai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2f92782a9ddaf7fc093c11e4a106d04001ccaed3d516236b73e9ce9b81f486c9
MD5 6aa93eef18168dd6ede2a2006bf5e23b
BLAKE2b-256 420c7849d02609a4568e1df6ed6857c0ebd633d0d4aaf3cbf3f81f305a59fbdc

See more details on using hashes here.

File details

Details for the file vault_sync_ai-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vault_sync_ai-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for vault_sync_ai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 34eea6c3b13b021e16b537e9c97035acf834cad416083f4e45c9258e145b97a9
MD5 5c071186a7067f39c60f1bcb48dd42ad
BLAKE2b-256 bccef733ff63b4c9dded0638e06ba1f17b74a26a2f45dd2bb9c257e6ac624e41

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page