dev_arc_aws/docs/OPEN-SOURCE-RELEASE.md
Samuel James b499759936
Some checks are pending
Deploy to racknerd1 / validate (push) Waiting to run
Deploy to racknerd1 / deploy (push) Blocked by required conditions
modified files
2026-06-22 16:10:05 -06:00

12 KiB

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, .github/workflows/deploy.yml Personal domain/deploy target Genericize to example.com / localhost; the deploy workflow should be removed or replaced with a generic CI (build + lint only, no SCP-to-my-server)
.github/workflows/deploy.yml SSHes/SCPs to the personal racknerd1 server Remove; replace with a generic build/test CI workflow
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.


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)
.github/workflows/deploy.yml  (replace with generic CI)
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 startdocker 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.
  • Replace .github/workflows/deploy.yml with a generic build/lint CI (no SCP).
  • 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.