Phony Cloud Platform - Technical Architecture
System Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ PHONY CLOUD ARCHITECTURE │
│ (Nuxt + Go + Rust Stack) │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ PRESENTATION LAYER │ │
│ │ (Nuxt Dashboard) │ │
│ ├───────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ Web Dashboard CLI Tool Management API │ │
│ │ (Nuxt 3 + (Go binary) (Nuxt Server │ │
│ │ Vue 3 + TS) Routes) │ │
│ │ │ │
│ │ • Auth (Auth.js) • phony login • /api/projects/* │ │
│ │ • Billing (Stripe) • phony sync • /api/users/* │ │
│ │ • Project UI • phony snapshot • /api/billing/* │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ HTTP/gRPC │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ APPLICATION LAYER │ │
│ │ (Go Engine) │ │
│ ├───────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ Sync │ │ Job │ │ Mock API │ │ │
│ │ │ Worker │ │ Scheduler │ │ Server │ │ │
│ │ │ (Go) │ │ (Go) │ │ (Go) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ Schema │ │ Training │ │ Export │ │ │
│ │ │ Manager │ │ Worker │ │ Manager │ │ │
│ │ │ (Go) │ │ (Go) │ │ (Go) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ │
│ │ │ │
│ │ Database Connectors: pgx (PostgreSQL), go-mysql, go-sqlite3 │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ FFI │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ CORE LAYER │ │
│ │ (Rust) │ │
│ ├───────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ PHONY CORE (Rust) │ │ │
│ │ │ ~5M records/sec │ │ │
│ │ │ │ │ │
│ │ │ ┌───────────┐ ┌───────────┐ ┌───────────────────┐ │ │ │
│ │ │ │ N-gram │ │ Generator │ │ Model │ │ │ │
│ │ │ │ Engine │ │ (seed) │ │ Serialization │ │ │ │
│ │ │ └───────────┘ └───────────┘ └───────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ┌───────────┐ ┌───────────┐ │ │ │
│ │ │ │ Trainer │ │ Batch │ .phony format │ │ │
│ │ │ │ │ │ Generate │ (MessagePack) │ │ │
│ │ │ └───────────┘ └───────────┘ │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ INFRASTRUCTURE LAYER │ │
│ ├───────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ Database │ │ Queue │ │ Storage │ │ │
│ │ │ (pgx, etc.) │ │ (Redis/ │ │ (S3/Local) │ │ │
│ │ │ │ │ NATS) │ │ │ │ │
│ │ │ • MySQL │ │ │ │ • Model files │ │ │
│ │ │ • Postgres │ │ Go-native │ │ • Export files │ │ │
│ │ │ • SQLite │ │ job queue │ │ • Snapshots │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘Technology Stack
DASHBOARD (Nuxt) GO ENGINE
├── Nuxt 3 ├── Go 1.22+
├── Vue 3 + Composition API ├── pgx (PostgreSQL)
├── TypeScript ├── go-mysql-driver
├── Tailwind CSS ├── go-sqlite3
├── Auth.js (authentication) ├── net/http (API server)
├── Stripe SDK (billing) └── asynq (job queue)
└── Nuxt UI (components)
RUST CORE INFRASTRUCTURE
├── Rust (stable) ├── PostgreSQL 15
├── N-gram engine ├── Redis (cache, queue)
├── MessagePack (serde) ├── S3-compatible storage
└── FFI exports (C ABI) └── Docker & GitHub Actions
DEPLOYMENT
├── Dashboard: Vercel or Docker
├── Go Engine: Docker / Kubernetes
└── Rust Core: Compiled into Go binary (CGO)Why This Stack?
| Component | Choice | Rationale |
|---|---|---|
| Dashboard | Nuxt | Vue familiar (from Inertia), TypeScript, easy deploy |
| Engine | Go | Best DB libs (pgx), goroutines, fast HTTP |
| Core | Rust | Maximum N-gram performance (5M/sec), memory efficient |
| No Laravel | - | Go handles all backend; Laravel would be overhead |
| Billing | Stripe SDK | After Delaware C-Corp incorporation (see 08_OPERATIONS) |
Billing Strategy (Phased)
| Phase | Revenue | Method | Notes |
|---|---|---|---|
| Early | $0-10K MRR | Paddle (MoR) | No company needed, 5% + $0.50 fees |
| Growth | $10K+ MRR | Stripe Billing | After Delaware C-Corp via Stripe Atlas |
Note: See /reference/operations for full incorporation timeline.
Security Model
Credential Storage
┌─────────────────────────────────────────────────────────────────┐
│ CREDENTIAL SECURITY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Storage: │
│ ├── All credentials encrypted at rest (AES-256) │
│ ├── Encryption key in environment, not in database │
│ ├── Credentials never logged or exposed in UI │
│ └── Option: Customer-managed keys (Enterprise) │
│ │
│ Database Connection Credentials: │
│ ├── Stored encrypted in phony_connections table │
│ ├── Decrypted only at sync runtime (in-memory) │
│ ├── Connection string never persisted in logs │
│ └── Test connection validates without storing data │
│ │
│ API Keys: │
│ ├── Hashed (bcrypt) - original never stored │
│ ├── Prefix visible for identification (pk_xxx...) │
│ ├── Revocable per-key │
│ └── Scoped permissions (read, write, admin) │
│ │
└─────────────────────────────────────────────────────────────────┘Network Security
┌─────────────────────────────────────────────────────────────────┐
│ NETWORK TOPOLOGY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Connection Methods: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. Direct SSL/TLS (Default) │ │
│ │ Customer DB ←──── TLS 1.3 ────→ Phony Cloud │ │
│ │ • Requires DB to accept external connections │ │
│ │ • IP allowlisting recommended │ │
│ │ │ │
│ │ 2. SSH Tunnel (Secure) │ │
│ │ Customer DB ←── SSH ──→ Bastion ←── TLS ──→ Phony │ │
│ │ • For DBs not exposed to internet │ │
│ │ • SSH key stored encrypted │ │
│ │ │ │
│ │ 3. VPC Peering (Enterprise) │ │
│ │ Customer VPC ←── Peering ──→ Phony VPC │ │
│ │ • Private network, no internet exposure │ │
│ │ • AWS/GCP/Azure supported │ │
│ │ │ │
│ │ 4. On-Premise Agent (Enterprise) │ │
│ │ Customer Network: [DB] ←→ [Phony Agent] │ │
│ │ ↓ (outbound only) │ │
│ │ Phony Cloud: ←── Control Plane │ │
│ │ • Data never leaves customer network │ │
│ │ • Agent pulls config, pushes status only │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Phony Cloud Static IPs (for allowlisting): │
│ ├── Production: 52.x.x.x, 52.x.x.y (published in docs) │
│ └── Staging: 54.x.x.x (separate environment) │
│ │
└─────────────────────────────────────────────────────────────────┘Data Processing & Retention
┌─────────────────────────────────────────────────────────────────┐
│ DATA HANDLING POLICY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ During Sync Operations: │
│ ├── Data streamed, not stored (batch processing) │
│ ├── Only transformation rules persist │
│ ├── N-gram frequencies stored (not source data) │
│ └── Source data purged after transformation │
│ │
│ What We Store: │
│ ├── Schema metadata (table names, column types) │
│ ├── Transformation rules (which columns to mask) │
│ ├── Trained models (n-gram frequencies only) │
│ ├── Sync job history (timestamps, row counts) │
│ └── Generated output (to destination DB/file) │
│ │
│ What We NEVER Store: │
│ ├── Raw source data (PII) │
│ ├── Unmasked values │
│ ├── Database credentials in logs │
│ └── Query results beyond transformation │
│ │
│ Data Residency (GDPR Compliance): │
│ ├── EU customers: eu.phony.cloud (Frankfurt) │
│ ├── US customers: us.phony.cloud (Virginia) │
│ └── Enterprise: Customer-specified region │
│ │
│ Retention Periods: │
│ ├── Sync logs: 90 days │
│ ├── Export files: 7 days (auto-delete) │
│ ├── Models: Until deleted by user │
│ └── Audit logs: 1 year (Enterprise: configurable) │
│ │
└─────────────────────────────────────────────────────────────────┘API Design
Versioning Strategy
┌─────────────────────────────────────────────────────────────────┐
│ API VERSIONING │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Strategy: URL Path Versioning │
│ │
│ Current: /api/v1/... │
│ Future: /api/v2/... │
│ │
│ Versioning Rules: │
│ ├── Major version in URL (/v1, /v2) │
│ ├── Breaking changes require new major version │
│ ├── Additive changes allowed within version │
│ ├── Deprecation notice 6 months before removal │
│ └── Minimum 12 months support for each version │
│ │
│ Breaking Changes (require new version): │
│ ├── Removing endpoints │
│ ├── Removing required fields │
│ ├── Changing field types │
│ └── Changing authentication method │
│ │
│ Non-Breaking Changes (allowed): │
│ ├── Adding new endpoints │
│ ├── Adding optional fields │
│ ├── Adding new enum values │
│ └── Deprecating (not removing) fields │
│ │
│ Headers: │
│ ├── X-API-Version: Returns current version │
│ ├── X-Deprecation-Date: If endpoint deprecated │
│ └── X-Rate-Limit-*: Rate limiting info │
│ │
└─────────────────────────────────────────────────────────────────┘Webhook System
┌─────────────────────────────────────────────────────────────────┐
│ PHONY CLOUD WEBHOOKS │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Available Events: │
│ ├── sync.started - Sync job began │
│ ├── sync.completed - Sync job finished successfully │
│ ├── sync.failed - Sync job failed │
│ ├── model.trained - Custom model training complete │
│ ├── export.ready - Export file ready for download │
│ ├── usage.threshold - Usage approaching limit (80%, 90%) │
│ └── api.deployed - Mock API deployment complete │
│ │
│ Webhook Payload: │
│ { │
│ "event": "sync.completed", │
│ "timestamp": "2026-01-15T10:30:00Z", │
│ "project_id": "proj_abc123", │
│ "data": { │
│ "job_id": "job_xyz789", │
│ "rows_processed": 150000, │
│ "duration_seconds": 45 │
│ } │
│ } │
│ │
│ Security: │
│ ├── HMAC-SHA256 signature in X-Phony-Signature header │
│ ├── Timestamp validation (reject >5 min old) │
│ ├── Retry with exponential backoff (3 attempts) │
│ └── Webhook secret per endpoint │
│ │
│ Configuration: │
│ ├── Multiple endpoints per project │
│ ├── Filter by event type │
│ ├── Custom headers support │
│ └── Test webhook button in UI │
│ │
└─────────────────────────────────────────────────────────────────┘CLI Authentication
┌─────────────────────────────────────────────────────────────────┐
│ CLI AUTHENTICATION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Method 1: API Key (Recommended for CI/CD) │
│ $ export PHONY_API_KEY=pk_live_xxxxx │
│ $ phony sync start --project my-project │
│ │
│ Method 2: OAuth Device Flow (Interactive) │
│ $ phony login │
│ → Opens browser: phony.cloud/device │
│ → Enter code: ABCD-1234 │
│ → Authenticated! Token stored in ~/.phony/credentials │
│ │
│ Method 3: Config File │
│ # ~/.phony/config.yaml │
│ api_key: pk_live_xxxxx │
│ default_project: my-project │
│ │
│ Token Storage: │
│ ├── Stored in ~/.phony/credentials (chmod 600) │
│ ├── Encrypted with OS keychain when available │
│ └── Environment variable takes precedence │
│ │
│ CLI Commands: │
│ $ phony login # OAuth flow │
│ $ phony logout # Clear credentials │
│ $ phony whoami # Show current user │
│ $ phony config set # Set configuration │
│ $ phony sync start # Start sync job │
│ $ phony sync status # Check sync status │
│ $ phony snapshot list # List snapshots │
│ $ phony snapshot restore <id> # Restore snapshot │
│ │
└─────────────────────────────────────────────────────────────────┘CI/CD Integration
┌─────────────────────────────────────────────────────────────────┐
│ CI/CD NATIVE INTEGRATION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ GitHub Actions: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ - name: Refresh staging data │ │
│ │ uses: phonyland/sync-action@v1 │ │
│ │ with: │ │
│ │ project: my-project │ │
│ │ api-key: ${{ secrets.PHONY_API_KEY }} │ │
│ │ subset: 1% │ │
│ │ wait: true │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ GitLab CI: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ refresh_test_data: │ │
│ │ image: phonyland/cli:latest │ │
│ │ script: │ │
│ │ - phony sync start --project $PROJECT --wait │ │
│ │ variables: │ │
│ │ PHONY_API_KEY: $PHONY_API_KEY │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Generic (any CI): │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ # Install CLI │ │
│ │ curl -fsSL https://phony.cloud/install.sh | bash │ │
│ │ │ │
│ │ # Or use Docker │ │
│ │ docker run phonyland/cli sync start --project X │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Supported Platforms: │
│ ├── GitHub Actions (native action) │
│ ├── GitLab CI (Docker image) │
│ ├── Bitbucket Pipelines (Docker image) │
│ ├── Jenkins (CLI or Docker) │
│ ├── CircleCI (Orb planned) │
│ └── Azure DevOps (CLI or Docker) │
│ │
│ Webhook Triggers: │
│ ├── On sync complete → trigger test suite │
│ ├── On sync fail → alert Slack/Teams │
│ └── On snapshot create → notify team │
│ │
└─────────────────────────────────────────────────────────────────┘Disaster Recovery & Backup
┌─────────────────────────────────────────────────────────────────┐
│ DISASTER RECOVERY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Platform Data (Phony Cloud's own data): │
│ ├── Daily automated backups │
│ ├── Point-in-time recovery (7 days) │
│ ├── Cross-region replication (Enterprise) │
│ └── RTO: 4 hours, RPO: 1 hour │
│ │
│ Customer Data: │
│ ├── Models: Versioned, exportable anytime │
│ ├── Schemas: JSON export available │
│ ├── Sync configs: Full export/import │
│ └── Mock API data: Regeneratable from seed │
│ │
│ Export & Portability: │
│ ├── Full project export (JSON) │
│ ├── Model export (portable .phony format) │
│ ├── API spec export (OpenAPI) │
│ └── No vendor lock-in: OSS can use exported models │
│ │
│ Incident Response: │
│ ├── Status page: status.phony.cloud │
│ ├── Incident notification via email │
│ ├── Post-incident reports (Enterprise) │
│ └── Scheduled maintenance windows (announced 48h ahead) │
│ │
│ SLA Guarantees: │
│ ├── Free/Starter: Best effort │
│ ├── Team: 99.5% uptime │
│ ├── Business: 99.9% uptime │
│ └── Enterprise: 99.95%+ (custom SLA) │
│ │
└─────────────────────────────────────────────────────────────────┘Team & Collaboration Features
┌─────────────────────────────────────────────────────────────────┐
│ TEAM COLLABORATION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Roles: │
│ ├── Owner - Full access, billing, delete org │
│ ├── Admin - Manage members, all project access │
│ ├── Developer - Create/edit projects, run syncs │
│ └── Viewer - Read-only access, view logs │
│ │
│ Permissions Matrix: │
│ ┌────────────────┬───────┬───────┬───────┬────────┐ │
│ │ Action │ Owner │ Admin │ Dev │ Viewer │ │
│ ├────────────────┼───────┼───────┼───────┼────────┤ │
│ │ View projects │ ✓ │ ✓ │ ✓ │ ✓ │ │
│ │ Create project │ ✓ │ ✓ │ ✓ │ ✗ │ │
│ │ Run sync │ ✓ │ ✓ │ ✓ │ ✗ │ │
│ │ Edit schema │ ✓ │ ✓ │ ✓ │ ✗ │ │
│ │ Manage members │ ✓ │ ✓ │ ✗ │ ✗ │ │
│ │ Billing │ ✓ │ ✗ │ ✗ │ ✗ │ │
│ │ Delete org │ ✓ │ ✗ │ ✗ │ ✗ │ │
│ └────────────────┴───────┴───────┴───────┴────────┘ │
│ │
│ Audit Logging: │
│ ├── Who did what, when │
│ ├── IP address and user agent │
│ ├── Searchable and exportable │
│ └── Retention: 90 days (Business: 1 year) │
│ │
└─────────────────────────────────────────────────────────────────┘