Multi-Tenancy
Data isolation architecture and tenant scoping
Phoenix Wallet is built as a multi-tenant platform, allowing multiple independent applications to share the same infrastructure while maintaining complete data isolation. Each tenant operates in its own isolated environment with separate wallets, assets, policies, and ledger entries.
Tenant Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Phoenix Wallet Platform │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────┐ ┌───────────────────┐ ┌─────────────┐ │
│ │ Tenant A │ │ Tenant B │ │ Tenant C │ │
│ │ (Gaming App) │ │ (Loyalty App) │ │ (Fintech) │ │
│ │ │ │ │ │ │ │
│ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌───────┐ │ │
│ │ │ Wallets │ │ │ │ Wallets │ │ │ │Wallets│ │ │
│ │ │ Assets │ │ │ │ Assets │ │ │ │Assets │ │ │
│ │ │ Policies │ │ │ │ Policies │ │ │ │Policie│ │ │
│ │ │ Ledger │ │ │ │ Ledger │ │ │ │Ledger │ │ │
│ │ └─────────────┘ │ │ └─────────────┘ │ │ └───────┘ │ │
│ │ │ │ │ │ │ │
│ │ Isolated Data │ │ Isolated Data │ │ Isolated │ │
│ └───────────────────┘ └───────────────────┘ └─────────────┘ │
│ │
│ Shared Infrastructure │
│ (Compute, Storage, Networking) │
└─────────────────────────────────────────────────────────────────┘Tenant Structure
| Field | Type | Description |
|---|---|---|
id | string | Unique tenant identifier |
name | string | Human-readable name |
status | enum | ACTIVE, SUSPENDED, CLOSED |
settings | object | Tenant-specific configuration |
metadata | object | Custom key-value pairs |
created_at | timestamp | Creation timestamp |
Data Isolation
Phoenix Wallet enforces strict data isolation at multiple levels:
Database-Level Isolation
Every database query is automatically scoped to the current tenant:
-- All queries include tenant_id filtering
SELECT * FROM wallets
WHERE tenant_id = 'ten_01HV8X...'
AND id = 'wal_01HV8X...';Tenant isolation is enforced at the database level using Row-Level Security (RLS) policies. This means even if application code has a bug, data from other tenants cannot be accessed.
API-Level Isolation
API keys are scoped to a specific tenant. Each request is authenticated and authorized within tenant boundaries:
# API key for Tenant A can only access Tenant A's data
curl https://api.phoenixwallet.io/v1/wallets \
-H "Authorization: Bearer sk_tenant_a_xxxxx"
# Returns only Tenant A's walletsResource Scoping
All resources are scoped to their parent tenant:
| Resource | Scoped By |
|---|---|
| Wallets | tenant_id |
| Assets | tenant_id |
| Policies | tenant_id |
| Lots | tenant_id (via wallet) |
| Reservations | tenant_id (via wallet) |
| Ledger Entries | tenant_id (via wallet) |
Tenant Configuration
Each tenant can customize their environment:
{
"id": "ten_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"name": "Acme Gaming",
"status": "ACTIVE",
"settings": {
"default_policy_id": "pol_standard",
"webhook_url": "https://acme.com/webhooks/phoenix",
"webhook_secret": "whsec_xxxxx",
"lot_depletion_order": "FEFO",
"reservation_default_ttl": "PT24H",
"timezone": "America/New_York"
},
"metadata": {
"plan": "enterprise",
"industry": "gaming"
},
"created_at": "2024-01-15T10:30:00Z"
}Configurable Settings
| Setting | Description | Default |
|---|---|---|
default_policy_id | Default policy for new lots | pol_standard |
webhook_url | Endpoint for event delivery | None |
lot_depletion_order | FIFO, FEFO, or custom | FIFO |
reservation_default_ttl | Default reservation expiry | PT1H (1 hour) |
timezone | Timezone for date calculations | UTC |
Cross-Tenant Operations
Cross-tenant operations are not permitted. Wallets, transfers, and queries are always isolated within a single tenant. There is no mechanism to move funds between tenants.
If you need to model relationships between separate applications:
- Create separate tenants for each application
- Use external systems to coordinate between them
- Each tenant maintains its own source of truth
Tenant Lifecycle
Creating a Tenant
Tenants are typically created through the admin API or dashboard:
curl -X POST https://api.phoenixwallet.io/admin/v1/tenants \
-H "Authorization: Bearer $ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "New Application",
"settings": {
"webhook_url": "https://newapp.com/webhooks"
},
"metadata": {
"contact": "admin@newapp.com"
}
}'Suspending a Tenant
Suspended tenants retain their data but cannot perform write operations:
curl -X POST https://api.phoenixwallet.io/admin/v1/tenants/ten_01HV8X.../suspend \
-H "Authorization: Bearer $ADMIN_API_KEY"Closing a Tenant
Closed tenants are permanently deactivated:
curl -X POST https://api.phoenixwallet.io/admin/v1/tenants/ten_01HV8X.../close \
-H "Authorization: Bearer $ADMIN_API_KEY"API Key Management
Each tenant can have multiple API keys with different permissions:
{
"keys": [
{
"id": "key_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"name": "Production",
"prefix": "sk_live_",
"permissions": ["read", "write"],
"created_at": "2024-01-15T10:30:00Z"
},
{
"id": "key_02HV8X9Y2KPQRS3T4UV5WX6YZ8",
"name": "Read-Only Analytics",
"prefix": "sk_live_",
"permissions": ["read"],
"created_at": "2024-01-15T10:30:00Z"
}
]
}Benefits of Multi-Tenancy
| Benefit | Description |
|---|---|
| Cost Efficiency | Shared infrastructure reduces operational costs |
| Scalability | Platform scales independently of individual tenants |
| Security | Database-level isolation prevents data leakage |
| Compliance | Each tenant's data can meet specific regulatory requirements |
| Simplicity | Single platform to manage, update, and monitor |