Skip to main content

Storage Adapters

MeetLoyd's Memory Pointer Architecture enables enterprise customers to store their data in their own infrastructure while MeetLoyd manages orchestration.

Core Principle

MeetLoyd stores pointers to memory, not the memory itself.

This separation of control plane (MeetLoyd) and data plane (your infrastructure) provides:

  • Data Sovereignty - Your data never leaves your infrastructure
  • Compliance - Meet GDPR, HIPAA, SOX data residency requirements
  • Security - Zero-trust architecture; MeetLoyd can't access data without your authorization
  • Flexibility - Use AWS, GCP, Azure, or any S3-compatible storage

Architecture Overview

┌──────────────────────────────────────────────────────────────────┐
│ MEETLOYD CONTROL PLANE │
│ │
│ ┌────────────────┐ ┌────────────────┐ ┌──────────────┐ │
│ │ Memory Service │───►│ Pointer Store │ │ Audit Logs │ │
│ └───────┬────────┘ │ (paths, hashes)│ └──────────────┘ │
│ │ └────────────────┘ │
│ ▼ │
│ ┌────────────────┐ │
│ │ Storage Adapter│ │
│ │ Registry │ │
│ └───────┬────────┘ │
└───────────┼───────────────────────────────────────────────────────┘


┌───────────────────────────────────────────────────────────────────┐
│ YOUR DATA PLANE │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ │ AWS S3 │ │ GCS │ │ Azure │ │ S3-Compat │ │
│ │ │ │ │ │ Blob │ │ (MinIO) │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────────┘ │
│ │
│ Your keys, your buckets, your compliance │
└───────────────────────────────────────────────────────────────────┘

Supported Storage Backends

BackendStatusUse CaseOptional Dependency
AWS S3ProductionPrimary cloud storage@aws-sdk/client-s3
Google Cloud StorageProductionGCP customers@google-cloud/storage
Azure Blob StorageProductionAzure customers@azure/storage-blob
S3-CompatibleProductionMinIO, DigitalOcean Spaces@aws-sdk/client-s3
MeetLoyd InternalDevelopmentTesting, small tenantsBuilt-in

Configuration

AWS S3

// Configure S3 storage
await client.storage.configure({
storageType: 's3',
connectionConfig: {
region: 'us-east-1',
bucket: 'my-company-meetloyd',
prefix: 'memories' // Optional: organize by prefix
},
encryptionType: 'customer-kms',
encryptionKeyRef: 'arn:aws:kms:us-east-1:123456789:key/abc-123'
});

Required IAM permissions:

{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket",
"s3:HeadObject",
"s3:HeadBucket"
],
"Resource": [
"arn:aws:s3:::my-company-meetloyd",
"arn:aws:s3:::my-company-meetloyd/*"
]
}

Google Cloud Storage

await client.storage.configure({
storageType: 'gcs',
connectionConfig: {
project: 'my-gcp-project',
bucket: 'my-company-meetloyd',
prefix: 'memories'
},
encryptionType: 'customer-kms',
encryptionKeyRef: 'projects/my-project/locations/global/keyRings/meetloyd/cryptoKeys/memory-key'
});

Required GCP roles:

  • roles/storage.objectViewer
  • roles/storage.objectCreator

Azure Blob Storage

await client.storage.configure({
storageType: 'azure-blob',
connectionConfig: {
storageAccount: 'mycompanymeetloyd',
container: 'memories',
prefix: 'prod'
},
encryptionType: 'customer-kms',
encryptionKeyRef: 'https://my-vault.vault.azure.net/keys/meetloyd-key/abc123'
});

S3-Compatible (MinIO, DigitalOcean Spaces)

await client.storage.configure({
storageType: 's3',
connectionConfig: {
region: 'us-east-1',
bucket: 'meetloyd-memory',
endpoint: 'https://minio.mycompany.com:9000'
}
});

What Gets Stored Where

MeetLoyd Stores (Pointers Only)

DataExample
Storage pathsmemories/team/T123/context.json
Content hashes7f83b166af0b7e9... (SHA-256)
Sizes1024 bytes
Sync statussynced, pending_write
Access logsWho accessed what, when

Your Storage (Actual Data)

DataExample
Conversation messagesFull message history
Agent memoriesLearned facts, preferences
Team contextShared team knowledge
Document embeddingsVector representations
Decision logsA2A decisions made

Encryption Options

LevelDescriptionWho Manages Keys
Platform ManagedAES-256-GCMMeetLoyd
Customer KMSAWS KMS, GCP KMS, Azure Key VaultYou
BYOKBring Your Own KeyYou

Using Customer KMS

// AWS KMS
{
encryptionType: 'customer-kms',
encryptionKeyRef: 'arn:aws:kms:us-east-1:123456789:key/abc-123'
}

// GCP KMS
{
encryptionType: 'customer-kms',
encryptionKeyRef: 'projects/my-project/locations/global/keyRings/ring/cryptoKeys/key'
}

// Azure Key Vault
{
encryptionType: 'customer-kms',
encryptionKeyRef: 'https://my-vault.vault.azure.net/keys/key-name/version'
}

Credential Management

MeetLoyd never stores your credentials - only references:

// You store credentials in your secrets manager
// MeetLoyd only stores the reference
await client.storage.configure({
storageType: 's3',
connectionConfig: { bucket: 'my-bucket', region: 'us-east-1' },
credentialRef: 'aws-secrets-manager/meetloyd-access' // Reference only
});

Authentication Methods

CloudSupported Methods
AWSIAM roles, access keys, instance profiles
GCPService accounts, application default credentials
AzureManaged identity, connection strings, service principals

Health Monitoring

Check storage health programmatically:

const health = await client.storage.healthCheck();
// Returns: 'healthy' | 'degraded' | 'unavailable'

// Get detailed status
const status = await client.storage.status();
/*
{
type: 's3',
bucket: 'my-bucket',
healthStatus: 'healthy',
lastCheck: '2026-01-12T10:00:00Z',
latencyMs: 45
}
*/

Migration Guide

From MeetLoyd Internal to External Storage

  1. Configure external storage:
await client.storage.configure({
storageType: 's3',
connectionConfig: { bucket: 'my-bucket', region: 'us-east-1' },
status: 'active'
});
  1. Initiate migration:
const migration = await client.storage.migrate({
fromConfig: 'internal',
toConfig: 'sc_abc123',
mode: 'copy' // Keeps original until verified
});
  1. Monitor progress:
const status = await client.storage.migrationStatus(migration.id);
// { progress: 75, itemsMigrated: 1500, errors: [] }
  1. Verify and cutover:
await client.storage.migrationCutover(migration.id);

Report Materialization

Agent reports are automatically materialized from the database to storage as .md files, then optionally synced to your team's provisioned Google Shared Drive.

Flow:

  1. Agent creates a report → stored in database
  2. Fire-and-forget: report rendered as Markdown → uploaded to R2/BYOS
  3. Fire-and-forget: Markdown file synced to Google Drive Reports folder

Storage path convention: {tenantId}/{appId}/{teamId}/reports/{YYYY-MM}/{reportId}.md

Custom paths can be configured per-tenant or per-team via the Storage Config API.

Report Storage in Dashboard

When a report has been materialized:

  • "Open in Drive" button links to the Google Drive file
  • "Download .md" button downloads from storage
  • Inline markdown rendering is always available as fallback

Content Encryption at Rest

Content encryption uses envelope encryption and is auto-triggered by HIPAA/GDPR governance packs.

What Gets Encrypted

ContentEncryptedRationale
Report content & summaryYesMay contain PII/PHI
Memory contentYesMay contain PII/PHI
Memory embeddingsNoLossy projections, can't reconstruct content
Context graph descriptionsYesMay reference people/companies
Context graph embeddingsNoSame as memory embeddings
File parsed contentYesMay contain sensitive data

Key Rotation

  1. POST /api/v1/storage-config/encryption/rotate triggers rotation
  2. All DEKs are re-wrapped immediately (fast — small payloads)
  3. Content is re-encrypted lazily on next read (version mismatch detection)
  4. Optional: batch rotation via rotation-service.ts for proactive re-encryption

API Reference

Storage Configuration

# Get tenant storage configuration
GET /api/v1/storage-config

# Update tenant storage defaults
PATCH /api/v1/storage-config

# Get team storage config (with inheritance)
GET /api/v1/storage-config/teams/:teamId

# Override team storage paths
PATCH /api/v1/storage-config/teams/:teamId

# Manual report materialization
POST /api/v1/storage-config/reports/:id/materialize

# Encryption key rotation (Enterprise)
POST /api/v1/storage-config/encryption/rotate

# Encryption coverage stats
GET /api/v1/storage-config/encryption/status

# BYOS setup (Enterprise)
POST /api/v1/storage-config/byos/setup
POST /api/v1/storage-config/byos/test
POST /api/v1/storage-config/byos/migrate
GET /api/v1/storage-config/byos/migration-status

Legacy Memory Storage API

# Get current storage configuration
GET /api/memory/storage/config

# Response:
{
"tenantId": "tenant_123",
"storageType": "s3",
"connectionConfig": { "bucket": "...", "region": "..." },
"encryptionType": "customer-kms"
}

# Set storage configuration
POST /api/memory/storage/config
Content-Type: application/json

{
"storageType": "s3" | "gcs" | "azure-blob" | "meetloyd",
"connectionConfig": { ... },
"credentialRef": "string (optional)",
"encryptionType": "none" | "aes-256-gcm" | "customer-kms" | "byok",
"scope": "all" | "app-specific (optional)",
"appId": "string (optional, for app-specific config)"
}

Memory Pointers

# Memory pointers are automatically managed
# You typically don't need to interact with them directly

# List pointers (for debugging)
GET /api/memory/pointers?scopeType=team&teamId=team_123

# Get pointer details
GET /api/memory/pointers/:id

# Pointer types available via API
GET /api/memory/pointer-types

Best Practices

Security

  1. Use customer KMS - Never rely on platform-managed encryption for production
  2. Rotate credentials - Set up credential rotation schedules
  3. Restrict bucket access - Only allow MeetLoyd IPs or use VPC endpoints
  4. Enable bucket versioning - Protect against accidental deletion

Performance

  1. Choose regions wisely - Co-locate storage with your primary users
  2. Use appropriate storage classes - Standard for active, Glacier for archives
  3. Set up lifecycle policies - Automatically archive old data

Compliance

  1. Configure retention policies - Set appropriate retention for your industry
  2. Enable access logging - Track all data access
  3. Document data flows - Maintain data processing documentation

Troubleshooting

"Storage unavailable" error

  1. Check bucket exists and MeetLoyd has access
  2. Verify credentials are valid and not expired
  3. Check network connectivity (VPC, firewall rules)

"Hash mismatch" error

Data integrity check failed. This could indicate:

  1. Data was modified outside MeetLoyd
  2. Encryption key changed
  3. Storage corruption

"Credential reference not found"

  1. Verify credential is stored in secrets manager
  2. Check reference path matches exactly
  3. Ensure MeetLoyd has permission to read the secret

Next: Learn about Agent-to-Agent Communication to understand how agents collaborate autonomously.