dev_arc_aws/docs/OPEN-SOURCE-RELEASE.md

235 lines
12 KiB
Markdown
Raw Permalink Normal View History

2026-06-22 16:10:05 -06:00
# ArchNest — Open-Source Release Readiness (v1)
This document is the checklist + plan for publishing ArchNest as an open-source
project. It is an internal planning doc — **do not copy this file into the public
repo.** It covers what to copy, what to scrub, licensing, repo structure,
README/screenshots, the release cadence, and resume/LinkedIn framing.
The public OSS repo should be a **fresh repository with a clean history** (see
"Why a fresh repo" below), not a fork of the working repo.
---
## 1. Security sweep result (done 2026-06-22)
A full secret/credential sweep of tracked files **and entire git history**
(`git log --all -p`) was run. Result: **clean — no real secrets are committed.**
- No private keys, no hardcoded secret assignments in tracked source.
- No real `.env`, `.pem`, `.key`, or `.db` was ever committed at any point in
history. The only `BEGIN RSA PRIVATE KEY` / `AKIA…` matches are documentation
prose and AWS's official `AKIAIOSFODNN7EXAMPLE` placeholder.
- `.gitignore` correctly excludes `backend/.env`, `backend/data`, `*.db`.
- Both `.env.example` files contain only placeholders (empty / `change-me-…`).
### Code-level security review (solid)
- JWT auth (Fastify `@fastify/jwt`). Every route group registers a blanket
`addHook('onRequest', app.authenticate)` before its routes; the three
WebSocket routes (`terminal`, `docker`, `guacamole`) verify
`app.jwt.verify(query.token)` explicitly (WS can't use header hooks).
- Mutating shared-config endpoints (integrations, tunnels, data export/import,
user management) are gated by `adminOnly` / `requireAdmin`. `authenticate`
re-reads `role`/`active` from the DB each request, so demote/deactivate takes
effect immediately even with an older token.
- Integration secrets: `serialize()` returns only secret **key names**
(`secretKeys`), never values. Secrets are encrypted at rest (AES-256-GCM,
`backend/src/db/crypto.ts`).
- Docker agent ingest is a **separately registered** route with a constant-time
bearer-token check; returns 503 when `ARCHNEST_AGENT_TOKEN` is unset (disabled
by default), and is NOT behind the user-auth hook (by design).
- Command-injection surfaces are guarded: tmux session names validated against
`^[A-Za-z0-9_-]{1,64}$` before interpolation; `system.ts` uses `execFile` (no
shell); Docker-over-SSH single-quotes container refs.
### Things to improve / note for OSS (not leaks)
- **CORS default**: `server.ts` does `origin: process.env.ARCHNEST_CORS_ORIGIN ?? true`.
`true` reflects any origin. Fine for a self-hosted single-origin deploy, but the
OSS README should tell users to set `ARCHNEST_CORS_ORIGIN` in production, and the
default `.env.example` should point at `http://localhost:5173` (it already does
for the backend example).
- Default JWT/secret env values in `backend/.env.example` are `change-me-…` — the
README must stress generating real ones (`openssl rand -hex 32`). The server
already refuses to boot without `ARCHNEST_SECRET_KEY` + `ARCHNEST_JWT_SECRET`.
---
## 2. What to SCRUB / NOT copy to the public repo
None of these are security leaks, but they are personal/infra-specific or
internal working notes that don't belong in a public project:
| Item | Why | Action |
|---|---|---|
| `docs/rdp-debug-handoff.md` | Contains lab creds (`sam` / `happy2026`) + private VM IP `192.168.122.55` + personal host names | **Exclude** (or heavily genericize into a "Remote Desktop setup" guide with no creds/IPs) |
| `HANDOFF.md` | Internal session-to-session working notes | **Exclude** |
| `docs/OPEN-SOURCE-RELEASE.md` (this file) | Internal release plan | **Exclude** |
| `archnest.snsnetlabs.com` references in `.env.example`, `docker-compose.yml` | Personal domain/deploy target | **Genericize** to `example.com` / `localhost` |
| Forgejo CI (`.forgejo/workflows/`) | Already build/validate only (no SCP/personal server). The build workflow pushes to a private registry + deploys to a private host | **Keep but genericize** the registry host + deploy job, or strip the deploy job for a public build-only CI |
2026-06-22 16:10:05 -06:00
| `agent/` deploy specifics | Fine to include the agent script, but scrub any host-specific URLs/tokens in its README | **Review + genericize** |
| `assets/` personal background images | Large PNGs; keep the ones the UI needs (hero banner, logo, KPI backgrounds), drop unused experiments (`opt1.bg`, `settings-custom-bg`, `pics/`) | **Trim to what's referenced** |
| Test/scratch files | `backend/data/`, any `*.db`, session logs | Already gitignored — confirm none are force-added |
Keep `ROADMAP.md` and `TERMIX_MIGRATION.md`? — `ROADMAP.md` yes (genericize:
it's a fine public roadmap once paid-tier framing is softened). `TERMIX_MIGRATION.md`
is build history; optional — can keep as `docs/HISTORY.md` or drop.
---
## 3. Why a fresh repo (recommended)
The working repo's history contains personal commit author emails, the personal
deploy workflow, the lab-cred debug doc, and the personal domain. The simplest
clean cut for a public project:
1. Create a new empty public repo (e.g. `archnest` under the personal GitHub).
2. Copy the **working tree** (not `.git`) of the files in the "INCLUDE" list below.
3. Genericize the scrubbed items.
4. `git init`, single initial commit ("Initial public release — ArchNest v1"),
author set to the public identity.
5. Add `LICENSE`, public `README.md`, `CONTRIBUTING.md`, screenshots.
This avoids dragging history-scrubbing tooling (BFG/`git filter-repo`) and
guarantees nothing personal leaks via an old commit.
### INCLUDE (the actual app)
```
src/ # React frontend
backend/src/ # Fastify backend
backend/package.json, backend/tsconfig*.json, backend/Dockerfile
backend/.env.example # (placeholders only — already clean)
package.json, package-lock.json, tsconfig*.json, vite.config.*, index.html
Dockerfile, docker-compose.yml # genericized (no personal domain)
.env.example # genericized
.gitignore, .dockerignore
public/ # fonts + static assets actually referenced
assets/ # ONLY images the UI imports
agent/archnest-docker-agent.sh + a genericized agent/README.md
design-decisions.md, ROADMAP.md # genericized
.kiro/steering/design-rules.md # optional — useful for contributors
LICENSE, README.md, CONTRIBUTING.md, screenshots/ # new, written for OSS
```
### EXCLUDE
```
.git/ # fresh history instead
HANDOFF.md
docs/rdp-debug-handoff.md
docs/OPEN-SOURCE-RELEASE.md (this file)
.forgejo/workflows/ (genericize: strip registry host + deploy job, or build-only CI)
2026-06-22 16:10:05 -06:00
backend/data/, *.db, session logs, *.tsbuildinfo
unused assets/ experiments + pics/
```
---
## 4. License
Recommended: **MIT** or **Apache-2.0**.
- **MIT** — shortest, most permissive, maximum adoption, easiest "I built this"
story. Good default for a portfolio/resume project.
- **Apache-2.0** — same permissiveness plus an explicit patent grant and a
NOTICE mechanism; slightly more "enterprise-friendly."
Given the goal (resume/LinkedIn showcase, broad adoption, simple), **MIT** is the
recommendation. Add a `LICENSE` file with the chosen license and the author's name
+ year. Note third-party components keep their own licenses (Guacamole = Apache-2.0,
the bundled Nerd Font has its own license already in `public/fonts/NERD-FONTS-LICENSE.txt`).
---
## 5. README.md (public) — outline
1. **Hero**: one-line pitch + a screenshot/GIF of the Glance dashboard.
> "A self-hosted, web-based control panel for your homelab and cloud — SSH
> terminal, file manager, Docker, tunnels, RDP/VNC, host metrics, and
> integration dashboards, all in one browser tab."
2. **Screenshots** (see §6).
3. **Features** — bullet list grouped by page; mark paid add-ons / not-yet-done
honestly (mirror the in-app Help "Not in the open-source version" notes).
4. **Architecture** — short: React + Vite + TS frontend, Fastify + SQLite backend,
guacd sidecar for RDP/VNC. One diagram is plenty.
5. **Quick start**`docker compose up` path + the required env vars (with
`openssl rand -hex 32` generation), and the local-dev path (`npm install` /
`npm run dev` in root and `backend/`).
6. **Configuration** — env var table (from `.env.example`), CORS note, first-run
`/api/setup` admin creation, the 10-user cap.
7. **Security notes** — secrets encrypted at rest; set a real CORS origin in prod;
it's designed to sit behind your own mesh/VPN, not be exposed raw to the
internet (mesh prerequisite gate exists, defaults off).
8. **Roadmap** — link `ROADMAP.md` + the "updates ~every 3 months" promise.
9. **Contributing** — link `CONTRIBUTING.md`.
10. **License** — MIT.
11. **Credits / "Built with AI"** — see §7.
---
## 6. Screenshots to capture (for README + LinkedIn)
Capture in the **default dark theme**, with demo/sanitized data (no real
hostnames, IPs, or tokens — use the placeholder-y names):
- Glance dashboard (hero shot)
- Infrastructure → Node Status with a couple of integrations
- Terminal with a split-pane / multiple tabs
- Files (SFTP browser) + a host-to-host transfer in progress
- Containers list + a container detail tab
- Remote Desktop showing a live XFCE session
- Host Metrics widgets
- Settings → Integrations (shows the breadth) and the locked Appearance "Paid
add-on" card (shows the free/paid split honestly)
- Help page (shows the per-page docs + OSS-edition note)
A short screen-recording GIF of opening a terminal or RDP session makes the
strongest LinkedIn post.
---
## 7. Resume / LinkedIn framing
Honest, specific, and ownership-forward. Suggested phrasing:
> **ArchNest** — a self-hosted, web-based homelab/cloud control panel
> (React + TypeScript + Fastify + SQLite, Dockerized). Single-pane access to SSH
> terminals, SFTP, Docker, SSH tunnels, browser-based RDP/VNC (Apache Guacamole),
> live host metrics, and pluggable infrastructure integrations (Proxmox, AWS,
> Cloudflare, NetBird, Uptime Kuma). Built with AI-assisted development; I owned
> the architecture, product decisions, security review, and integration/debugging
> (e.g. root-caused and fixed a FreeRDP/NLA + Guacamole tunnel-keepalive issue
> end-to-end across browser, proxy, and target VM). Open source under MIT, shipped
> v1, ongoing ~quarterly releases.
Notes for credibility:
- It's fine and increasingly normal to say "AI-assisted." Pair it with the
*engineering judgment* you provided (architecture, security, debugging) so it
reads as "I directed and verified," not "I prompted and pasted."
- The RDP debugging saga is a genuinely strong, concrete story — it shows
multi-layer debugging (browser ↔ guacd/FreeRDP ↔ xrdp/desktop) and root-cause
rigor. Worth a short LinkedIn write-up on its own.
---
## 8. Pre-publish checklist
- [ ] Create fresh public repo, copy INCLUDE list, exclude EXCLUDE list.
- [ ] Genericize personal domain → `example.com`/`localhost` in
`.env.example`, `docker-compose.yml`.
- [ ] Genericize `.forgejo/workflows/` for public use (strip the private registry host + the racknerd2 deploy job, or ship build-only CI).
2026-06-22 16:10:05 -06:00
- [ ] Add `LICENSE` (MIT), public `README.md`, `CONTRIBUTING.md`.
- [ ] Capture + add screenshots (sanitized data, dark theme).
- [ ] Re-run a secret scan on the NEW repo before first push
(`git log -p | grep -iE 'AKIA|BEGIN .*PRIVATE KEY|password|secret'` plus a
tool like `gitleaks detect` for good measure).
- [ ] Confirm `npm run build` (root) and `npx tsc --noEmit` (backend) pass on the
copied tree.
- [ ] Confirm first-run works from a clean `docker compose up` with freshly
generated secrets and no prior DB.
- [ ] Tag `v1.0.0`.
---
## 9. Release cadence (commitment)
Public promise: **updates approximately every 3 months.** Keep a short
`CHANGELOG.md` in the public repo and cut a tagged release each cycle. The Help
page's "Open-source edition" note and the README both reference this cadence —
keep them in sync.