dev_arc_aws/docs/aws-architecture/system-design.md
Samuel James 04d491c277
All checks were successful
CI / validate (push) Successful in 48s
System design, CloudFormation, theming assets (#3)
2026-06-24 13:55:04 +00:00

326 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 |