dev_arc_aws/docs/aws-architecture/system-design.md

327 lines
12 KiB
Markdown
Raw Permalink Normal View History

# ArchNest — Self-Hosted Product Design
> Open-core model: free self-hosted base with $5 one-time module purchases.
> No subscriptions. No SaaS. Customer owns it forever.
---
## Business Model
| Aspect | Detail |
|--------|--------|
| **Core** | Free, self-hosted, open-source (or source-available) |
| **Modules** | $5 one-time purchase each (lifetime license) |
| **Updates** | Free core updates forever. Module updates included. |
| **License** | Phone-home on boot + weekly check. Works offline between checks. |
| **Revenue** | Volume × $5. Target: high module attach rate per install. |
| **Infrastructure cost** | Near zero (license server + payment processor only) |
---
## Free Core (What Ships for Free)
The free tier must be genuinely useful — good enough to adopt, limited enough
to want more.
| Feature | Included Free |
|---------|--------------|
| Dashboard (Glance page) | ✓ |
| Infrastructure overview | ✓ |
| SSH Terminal (1 tab, 1 pane) | ✓ |
| SSH Tunnels (manual start only) | ✓ |
| SFTP File Manager | ✓ |
| Docker management (TCP API only, 1 source) | ✓ |
| Host Metrics (basic: CPU/memory/disk) | ✓ |
| Bookmarks (10 max) | ✓ |
| Settings (Profile, Integrations) | ✓ |
| 3 SSH host integrations max | ✓ |
| 1 user (admin only) | ✓ |
| Single theme (ArchNest Dark) | ✓ |
| Help page | ✓ |
**Why this works:** A solo developer with 13 servers can use ArchNest for
free with a functional terminal, basic Docker visibility, and file management.
The moment they want split panes, more hosts, multi-user, or RDP — they buy
modules.
---
## Paid Modules ($5 Each)
### SSH Modules
| # | Module | What It Unlocks |
|---|--------|-----------------|
| 1 | **Multi-Pane Terminal** | Split panes (2/4), multiple tabs |
| 2 | **tmux Integration** | Attach to existing tmux sessions |
| 3 | **Jump-Host Chaining** | Connect through intermediary hosts (ProxyJump) |
| 4 | **Certificate Auth (OPKSSH)** | Certificate-based SSH authentication |
| 5 | **Tunnel Auto-Start** | Tunnels start automatically on boot |
| 6 | **Persistent Sessions** | Terminal sessions survive page navigation |
| 7 | **Session Recording** | Record terminal sessions to disk |
| 8 | **Host-to-Host Transfer** | Copy/move files between two SSH hosts |
### Docker Modules
| # | Module | What It Unlocks |
|---|--------|-----------------|
| 9 | **Docker over SSH** | Manage containers via `docker` CLI over SSH (no exposed socket) |
| 10 | **Docker Push Agent** | Outbound-only monitoring agent for Docker hosts |
| 11 | **Container Exec** | Interactive shell into running containers |
| 12 | **Container Detail View** | Full inspect: ports, networks, mounts, env, labels |
### Integration Modules
| # | Module | What It Unlocks |
|---|--------|-----------------|
| 13 | **Unlimited SSH Hosts** | Remove 3-host cap (unlimited integrations) |
| 14 | **Proxmox Integration** | VM/LXC management |
| 15 | **AWS Integration** | EC2 + STS resource inventory |
| 16 | **Cloudflare Integration** | DNS zones, resource listing |
| 17 | **NetBird Integration** | Mesh peers, connectivity |
| 18 | **Uptime Kuma Integration** | Monitor status/health |
### Desktop & Display Modules
| # | Module | What It Unlocks |
|---|--------|-----------------|
| 19 | **Remote Desktop (RDP)** | RDP sessions via Guacamole |
| 20 | **Remote Desktop (VNC)** | VNC sessions via Guacamole |
| 21 | **Remote Desktop (Telnet)** | Telnet sessions via Guacamole |
| 22 | **Theme: Midnight Blue** | Blue accent theme |
| 23 | **Theme: Forest** | Emerald accent theme |
| 24 | **Theme: Light** | Light mode theme |
### Platform Modules
| # | Module | What It Unlocks |
|---|--------|-----------------|
| 25 | **Multi-User** | Add users (admin/member roles, up to 10 seats) |
| 26 | **Advanced Metrics** | Full host metrics (network, processes, ports, firewall, login stats) |
| 27 | **Data Export/Import** | Backup/restore integrations + secrets + bookmarks + tunnels |
| 28 | **Audit Log** | Full activity audit log with export |
| 29 | **Unlimited Bookmarks** | Remove 10-bookmark cap |
| 30 | **Global Search** | Search across pages, integrations, bookmarks |
---
## Bundles (Discounted)
| Bundle | Modules Included | Price | Savings |
|--------|-----------------|-------|---------|
| **SSH Pro** | #18 (all SSH modules) | $25 | Save $15 |
| **Docker Pro** | #912 (all Docker modules) | $15 | Save $5 |
| **Remote Desktop** | #1921 (RDP + VNC + Telnet) | $10 | Save $5 |
| **All Themes** | #2224 (3 themes) | $10 | Save $5 |
| **Everything** | All 30 modules | $99 | Save $51 |
---
## Revenue Model
| Scenario | Installs/mo | Avg modules purchased | Revenue/mo |
|----------|-------------|----------------------|------------|
| Early (month 1-3) | 50 | 3 modules ($15 avg) | $750 |
| Growth (month 4-6) | 200 | 4 modules ($20 avg) | $4,000 |
| Steady (month 7-12) | 500 | 5 modules ($25 avg) | $12,500 |
| Mature (year 2) | 1,000 | 4 modules + bundles ($30 avg) | $30,000 |
**Infrastructure cost:** ~$20-30/month (license server + Stripe + domain).
**Profit margin:** ~95%+ (no SaaS hosting, no per-tenant compute).
---
## License System Architecture
### Phone-Home (Light Touch)
```
┌─────────────────────┐ ┌────────────────────────┐
│ Customer Install │ │ License Server │
│ │ │ (Akamai / Cloudflare │
│ Fastify Backend │────────▶│ Workers / Lambda) │
│ on boot + weekly │ │ │
│ │◀────────│ Returns: │
│ Validates signed │ │ - licensed_modules[] │
│ response locally │ │ - valid_until (7day) │
└─────────────────────┘ │ - signature │
└────────────────────────┘
```
**How it works:**
1. Customer installs ArchNest (Docker Compose or bare metal)
2. On first boot, backend calls license server with install ID
3. License server returns a signed JSON payload:
- `modules`: list of purchased module slugs
- `valid_until`: timestamp (7 days from now)
- `signature`: Ed25519 signature of the payload
4. Backend validates the signature locally (public key embedded in code)
5. If signature valid and `valid_until` hasn't expired → features unlocked
6. Re-checks weekly. If server unreachable, works offline for 7 days.
7. After 7 days without a successful check → falls back to free core only
**Grace period:** 7 days offline. Generous enough for server maintenance,
network issues, etc. If someone loses internet for a week, they keep working.
### License Server Stack
| Component | Provider | Cost |
|-----------|----------|------|
| License API | Cloudflare Workers (free tier: 100K req/day) | $0 |
| Database | Cloudflare D1 (free tier: 5GB) | $0 |
| Payment | Stripe (2.9% + $0.30 per transaction) | Per-sale |
| Domain | Route 53 or Cloudflare | $1/mo |
| **Total** | | **~$1/mo + Stripe fees** |
At $5/module, Stripe takes ~$0.45 per transaction. Net per module: **$4.55**.
### Purchase Flow
```
Customer browses modules in Settings → Module Store tab
→ Clicks "Buy" → Stripe Checkout ($5)
→ Stripe webhook → License server records purchase
→ Customer's next license check returns new module
→ Feature unlocks immediately (or within minutes on next poll)
```
### Install ID Generation
- Generated on first boot: `SHA-256(machine-id + secret-key + timestamp)`
- Stored in the database
- Tied to Stripe customer on first purchase
- Transferable (customer can request a reset if they move servers)
---
## Module Enforcement (Backend)
```typescript
// Fastify plugin — runs before route handlers
const tierMiddleware = (app) => {
app.addHook('onRequest', async (req, reply) => {
const license = app.licenseCache; // refreshed weekly
req.modules = license?.modules ?? [];
});
};
// Route-level check
app.get('/api/terminal/connect', {
preHandler: [requireModule('multi-pane-terminal')],
handler: terminalConnect
});
function requireModule(slug: string) {
return async (req, reply) => {
if (!req.modules.includes(slug)) {
reply.code(402).send({
error: 'Module required',
module: slug,
price: '$5',
purchaseUrl: `https://archnest.io/modules/${slug}`
});
}
};
}
```
**Frontend enforcement:**
- Module-gated UI elements show a lock icon + "Unlock for $5" prompt
- Clicking opens the purchase flow (in-app or redirect to store)
- After purchase, UI refreshes and feature unlocks
---
## Free Core Updates
- All users get bug fixes, security patches, and core feature improvements
- Module features don't get stripped from updates — once bought, always works
- New modules may be added over time (new revenue without churning existing customers)
- Major version upgrades (v2, v3) may require a new "Everything" bundle purchase (TBD)
---
## Comparison: SaaS vs Self-Hosted Module Model
| | SaaS (old design) | Self-Hosted Modules (new) |
|---|---|---|
| Infra cost | $66-300/mo | ~$1/mo |
| Revenue model | Recurring ($2.50-12/mo) | One-time ($5/module) |
| Churn risk | High (monthly cancel) | None (one-time) |
| Support burden | High (you host it) | Low (they host it) |
| Profit margin | 60-65% | 95%+ |
| Scale limit | Your AWS bill | Their hardware |
| Customer lock-in | Subscription | Ownership (better reputation) |
---
## Tech Stack (Unchanged)
| Layer | Tech |
|-------|------|
| Frontend | React 19, Vite 8, TypeScript, Tailwind v4 |
| Backend | Fastify 5, TypeScript, SQLite (better-sqlite3) |
| Auth | Local JWT + bcrypt (self-hosted, no Cognito) |
| License | Phone-home to Cloudflare Workers |
| Payment | Stripe Checkout |
| Deploy | Docker Compose (customer's hardware) |
| CI/CD | Forgejo Actions |
---
## What Changes From Current Codebase
| Area | Current | New |
|------|---------|-----|
| Database | SQLite (stays) | SQLite (stays — no Postgres migration needed) |
| Auth | Local JWT (stays) | Local JWT (stays — no Cognito needed) |
| Multi-tenant | Not needed | Not needed (single-tenant per install) |
| License check | None | New: weekly phone-home + local signature validation |
| Module gating | None | New: Fastify middleware + frontend lock UI |
| Settings page | Current tabs | New: "Module Store" tab |
| Stripe | None | New: Stripe Checkout for purchases |
**Key insight:** This model requires almost no infrastructure changes to the
current codebase. You're adding a license middleware layer and a store UI —
not rewriting the database, auth, or deployment.
---
## Implementation Priority
### Phase 1: License Infrastructure
1. Build license server (Cloudflare Workers + D1)
2. Add license check to backend (on boot + weekly cron)
3. Add module enforcement middleware
4. Add "Module Store" tab in Settings
### Phase 2: Module Gating
1. Define module boundaries in code (which routes require which module)
2. Add lock UI to gated features in frontend
3. Free tier caps (3 hosts, 1 pane, 10 bookmarks)
### Phase 3: Purchase Flow
1. Stripe integration (Checkout, webhooks)
2. Module activation on purchase
3. Bundle discounts
4. Purchase history in Settings
### Phase 4: Distribution
1. Public Docker image on Docker Hub / GitHub Container Registry
2. Landing page with module catalog
3. Installation docs
4. Demo instance for prospects
---
## Open Decisions
| # | Question | Options |
|---|----------|---------|
| 1 | Source code visibility | Open-source (MIT/Apache) vs source-available (BSL) vs proprietary |
| 2 | Docker Hub vs self-hosted registry | Docker Hub (wider reach) vs GHCR (free private) |
| 3 | Landing page tech | Static site on Cloudflare Pages vs separate repo |
| 4 | Refund policy | 30-day no-questions vs no refunds ($5 is low enough) |
| 5 | Module store UX | In-app tab vs external website |
| 6 | License transfer | Allow unlimited vs 1 transfer per year |