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
| Backend | Status | Use Case | Optional Dependency |
|---|---|---|---|
| AWS S3 | Production | Primary cloud storage | @aws-sdk/client-s3 |
| Google Cloud Storage | Production | GCP customers | @google-cloud/storage |
| Azure Blob Storage | Production | Azure customers | @azure/storage-blob |
| S3-Compatible | Production | MinIO, DigitalOcean Spaces | @aws-sdk/client-s3 |
| MeetLoyd Internal | Development | Testing, small tenants | Built-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.objectViewerroles/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)
| Data | Example |
|---|---|
| Storage paths | memories/team/T123/context.json |
| Content hashes | 7f83b166af0b7e9... (SHA-256) |
| Sizes | 1024 bytes |
| Sync status | synced, pending_write |
| Access logs | Who accessed what, when |
Your Storage (Actual Data)
| Data | Example |
|---|---|
| Conversation messages | Full message history |
| Agent memories | Learned facts, preferences |
| Team context | Shared team knowledge |
| Document embeddings | Vector representations |
| Decision logs | A2A decisions made |
Encryption Options
| Level | Description | Who Manages Keys |
|---|---|---|
| Platform Managed | AES-256-GCM | MeetLoyd |
| Customer KMS | AWS KMS, GCP KMS, Azure Key Vault | You |
| BYOK | Bring Your Own Key | You |
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
| Cloud | Supported Methods |
|---|---|
| AWS | IAM roles, access keys, instance profiles |
| GCP | Service accounts, application default credentials |
| Azure | Managed 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
- Configure external storage:
await client.storage.configure({
storageType: 's3',
connectionConfig: { bucket: 'my-bucket', region: 'us-east-1' },
status: 'active'
});
- Initiate migration:
const migration = await client.storage.migrate({
fromConfig: 'internal',
toConfig: 'sc_abc123',
mode: 'copy' // Keeps original until verified
});
- Monitor progress:
const status = await client.storage.migrationStatus(migration.id);
// { progress: 75, itemsMigrated: 1500, errors: [] }
- 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:
- Agent creates a report → stored in database
- Fire-and-forget: report rendered as Markdown → uploaded to R2/BYOS
- 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
| Content | Encrypted | Rationale |
|---|---|---|
| Report content & summary | Yes | May contain PII/PHI |
| Memory content | Yes | May contain PII/PHI |
| Memory embeddings | No | Lossy projections, can't reconstruct content |
| Context graph descriptions | Yes | May reference people/companies |
| Context graph embeddings | No | Same as memory embeddings |
| File parsed content | Yes | May contain sensitive data |
Key Rotation
POST /api/v1/storage-config/encryption/rotatetriggers rotation- All DEKs are re-wrapped immediately (fast — small payloads)
- Content is re-encrypted lazily on next read (version mismatch detection)
- Optional: batch rotation via
rotation-service.tsfor 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
- Use customer KMS - Never rely on platform-managed encryption for production
- Rotate credentials - Set up credential rotation schedules
- Restrict bucket access - Only allow MeetLoyd IPs or use VPC endpoints
- Enable bucket versioning - Protect against accidental deletion
Performance
- Choose regions wisely - Co-locate storage with your primary users
- Use appropriate storage classes - Standard for active, Glacier for archives
- Set up lifecycle policies - Automatically archive old data
Compliance
- Configure retention policies - Set appropriate retention for your industry
- Enable access logging - Track all data access
- Document data flows - Maintain data processing documentation
Troubleshooting
"Storage unavailable" error
- Check bucket exists and MeetLoyd has access
- Verify credentials are valid and not expired
- Check network connectivity (VPC, firewall rules)
"Hash mismatch" error
Data integrity check failed. This could indicate:
- Data was modified outside MeetLoyd
- Encryption key changed
- Storage corruption
"Credential reference not found"
- Verify credential is stored in secrets manager
- Check reference path matches exactly
- Ensure MeetLoyd has permission to read the secret
Next: Learn about Agent-to-Agent Communication to understand how agents collaborate autonomously.