diff options
Diffstat (limited to 'docs/CHAT-PRODUCTION.txt')
| -rw-r--r-- | docs/CHAT-PRODUCTION.txt | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/docs/CHAT-PRODUCTION.txt b/docs/CHAT-PRODUCTION.txt new file mode 100644 index 0000000..fdb48a6 --- /dev/null +++ b/docs/CHAT-PRODUCTION.txt @@ -0,0 +1,222 @@ +Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. + + +PRODUCTION CHAT INTEGRATION + + Implemented on main. Builds/tests do not activate the VPS. Experimental; + no independent cryptographic or application security audit. Read + CHAT-APPLICATION.txt limitations before private use. + + Rootless Podman runs Caddy, cgit, SearXNG, and chat. Releases contain static + x86_64 GNU/Linux management/chat binaries, browser WASM, exact corresponding + sources, and native images. Chat starts FROM scratch: no compiler, shell, + package manager, or first-party Python. Root filesystem is read-only; + capabilities are dropped; only private data is writable. + + Caddy serves HTTPS at CHAT_HOST and redirects www.CHAT_HOST, preserving paths. + CHAT_UPSTREAM defaults to private chat:8080. Chat publishes no host ports; + only gateway HTTP and TCP/UDP HTTPS are published. Host SSH policy is separate. + + Root .env selects the explicit external origin. Chat accepts exactly that + HTTPS origin or the dedicated local gateway origin. Forwarded client headers + cannot select it. Origin checks supplement cryptographic authentication. + +BUILD ON THE WORKSTATION + + Build host and target must be x86_64 GNU/Linux. Requires pinned Rust, Podman, + Git, GnuPG, GCC-compatible C compiler, Linux UAPI headers, libclang, pkg-config, + make, Perl, curl, tar, Node >=22.18.0, npm, and OpenSSL 3.5+ development libraries. + Browser tests also need pinned Playwright, Chromium, and Firefox. Workstation + tools stay local; production needs neither Cargo nor compiler. + + cargo stack release + + Runs TypeScript build/checks, formatting, strict Clippy, workspace tests, + rustdoc, cargo-deny, and cargo-about. Builds static binaries, WASI, exact + sources, chat/cgit images, and complete image export. Regenerates workspace + THIRD-PARTY-LICENSES.html. Verify archive checksum and recovery before deployment. + + infra/chat/build-native.sh verifies OpenSSL 3.6.5's original source archive: + a2157c2830efdec3788939b00c9b0638306d3f0bbb76dc4832ee503bb397df98 + It verifies Alpine musl-dev 1.2.6-r3 headers: + 310b51cff12e1d5ce5f135c558a82e2550427da5465bbd16c9ff9b05e63ee3d9 + Sources: official OpenSSL GitHub release and Alpine CDN. Compilation uses + isolated musl/GCC built-in and host Linux UAPI headers, excluding glibc. + Static OpenSSL has no dynamic providers and seeds through getrandom. The + native compatibility probe must pass. WASI uses separately verified SDK/OpenSSL + inputs in CHAT-OPENSSL-MIGRATION.txt. Cryptographic algorithms stay fixed. + + Inputs cache under .tools/. Version/source/flag changes require an OpenSSL + rebuild. Updates require upstream advisory review, every affected URL/hash, + native/WASI rebuilds, both browsers, cargo-deny, regenerated notices/sources, + and release recovery. Never waive advisories to pass. cargo-deny excludes C/OpenSSL. + + Source downloads include first-party code, Cargo-vendored dependencies, and + unmodified OpenSSL, excluding development toolchain/sysroot inputs. Saved + images preserve tested runtime. ARM requires a separately supported native release. + +LOCAL MODES AND ORIGIN BINDING + + Direct Rust development: + cargo stack chat + http://127.0.0.1:9080/ + var/data/chat + + Container preview: + cargo stack dev + http://chat.localhost:8080/ + var/data/chat-local + + Production: + ./bin/stack up --production + https://CHAT_HOST/ with the configured HTTPS_PORT + var/data/chat + + Distinct origins require separate identity files. Direct development and + production share a relative database path on separate machines; do not switch + valuable installations between them. Integration tests need a fresh restored + release. Rebuild after edits to refresh browser, server, sources, notices, and image. + + One root .env holds hostnames, ports, upstreams, backups, SEARXNG_SECRET, and + CHAT_SETUP_TOKEN. Only the example is public; releases/source downloads exclude + actual .env. Caddy keys/chat databases stay under var/data. Initialization + preserves configured values and generates missing secrets. + +DEPLOY AND CREATE THE REAL OWNER FILE + + Follow OPERATIONS.txt. Extract the verified release's new management binary + into var/incoming/bootstrap; invoke with --root set to the current installation. + The new binary understands its release schema, verifies the archive, and + installs chat artifacts before startup. + The host needs rootless Podman prerequisites, user linger, low-port permission, + DNS A/AAAA records for CHAT_HOST and www.CHAT_HOST, and the normal 80/443 + firewall rules. Caddy obtains and renews public certificates automatically. + Public certificate validation requires standard reachable ACME ports. + + The systemd user service runs ./bin/stack up --production at boot and + ./bin/stack down on stop. Podman restarts + failed containers. Complete matching-architecture releases need no compilation + or registry pull. Check all four services after activation: + + ./bin/stack status + + Check HTTPS, HTTP-to-HTTPS and www redirects, the homepage Services entry, + /LIMITATIONS.txt, /javascript.html, and /SOURCE.tar.gz on the chat origin. + The displayed limitations are CHAT-APPLICATION.txt. Chat has its own origin; + the main website remains JavaScript-free. Its Message Me links lead to chat. + + At the production HTTPS origin, choose OWNER SETUP. Read the root .env token + locally; never publish or send it through chat. Choose a unique password; + save, reopen, and unlock the downloaded owner file. Keep file/password in + KeePassXC with a protected database backup. The token cannot replace the file. + Never silently change a development file's pinned origin. + +BACKUP, RESTORE, AND KEY LOSS + + A complete encrypted application export: + ./bin/stack backup --include-images + + Copy .gpg and .sha256 off the VPS; local backups cannot survive VPS loss. + Configured recipients apply. Export includes one .env, online SQLite snapshots + for chat/chat-local, Caddy certificates, repositories, static binaries, WASM, + sources, and exact images. Chat stays unpaused so pending writers can complete. + Database contents are ciphertext/public keys and CHAT-APPLICATION.txt metadata. + Owner private file and GnuPG secret key need separate backups. + + Restore to a new directory, verify, then explicitly start production mode: + ./bin/stack restore /path/export.tar.gz.gpg /path/stack-restored + cd /path/stack-restored + ./bin/stack up --production + + Restore defaults to local mode with fresh project names, avoiding replacement + of another installation. up --production reselects production database/origin. + Keep hostname/origin, repoint DNS, and use unchanged identity files/passwords. + IP changes preserve origin; hostname/HTTPS-port changes do not. Never expose + two restored copies under one origin. Restart invalidates sessions; reopening + files authenticates again. Historical ciphertext/counters persist. + + CHAT_SETUP_TOKEN cannot recover a lost private file. If backups are also lost, + reset deletes every conversation/message; it decrypts and recovers nothing. + Reset has no HTTP endpoint and requires filesystem/Podman access: + + ./bin/stack chat --owner-fingerprint + ./bin/stack down + ./bin/stack chat --reset-owner PASTE_CURRENT_OWNER_FINGERPRINT_HERE + ./bin/stack up --production + + Reset requires a stopped server and matching full fingerprint. Root .env and + exports survive. Create a new production owner file; old visitor files reject + its changed key and need fresh identities. Exports/external snapshots are not erased. + +VERIFICATION + + The browser harness supports packaged HTTPS installations without Rust or + target/ inside them. It creates disposable identities and a separate temporary + GnuPG key, takes a complete encrypted export with images during live chat, + restores into a new directory, starts the saved images, and reopens the same + files to decrypt history. It also exercises wrong passwords, safe text, + counters, 0-to-N history, 50-row batches, retry deduplication, origin rejection, + browser storage checks, and backend reset guards. It never resets real data. + + Example after restoring a release to a disposable staging directory and + configuring fixture .localhost hostnames, WEB_BIND=127.0.0.1, HTTP_PORT=8181, + HTTPS_PORT=8443, and LOCAL_HTTP_PORT=8180: + + ./bin/stack up --production + CHAT_TEST_ROOT=/absolute/disposable/stack CHAT_TEST_ORIGIN=https://chat.fixture.localhost:8443 PLAYWRIGHT_BROWSERS_PATH=.tools/browsers npm run test:chat + + Run from the source checkout for the harness and Playwright installation. + Add CHAT_LIBREJS=1 for Firefox with the actual GNU LibreJS add-on. That test + verifies the add-on is active and blocks an unlicensed control script. + Disposable staging needs a fresh database for each complete run. + + Browser automation permits the fixture's private CA only for functional tests. + Separately verify its chain and hostname with curl --cacert and --resolve; + test the canonical route and www redirect without disabling verification. + Production uses ordinary trusted public certificates with no TLS bypass. + Passing these checks demonstrates recovery and functional compatibility; it + does not establish absence of attacks or constitute an independent audit. + +RECORDED RESULTS, 2026-10-31 + + The complete native workspace check passed: formatting, strict Clippy, + 14 tests, private rustdoc, cargo-deny with no ignored advisories, and + cargo-about generation. Static musl and WASI OpenSSL 3.6.5 probes passed + without changing the required RFC 9980 algorithms. + + Direct development passed in Chromium. Packaged HTTPS passed independently + in Chromium and Firefox with GNU LibreJS 7.21.1 active; its unlicensed-script + control was rejected. Both packaged tests recovered a complete encrypted + application export, including saved images, into a new directory, then + reopened the unchanged owner/visitor files and decrypted the history. + Export and checksum permissions were verified as 0600. + + Runtime inspection verified read-only root filesystem, zero effective + capabilities, no chat host ports, and unless-stopped restart policy. Killing + the disposable chat process with SIGKILL caused an automatic restart, and + its owner fingerprint persisted. The supplied systemd user unit passed + systemd-analyze verification; this did not reboot the real VPS. + + curl independently verified the fixture CA chain and hostname for canonical + chat, www redirect, and homepage. The homepage Services limitations link + resolved correctly. The source download matched the packaged source archive + byte-for-byte and contained only .env.example, without actual .env. + + Upgrade testing started the 2026-10-30 three-service release, then activated + the chat-enabled release through its new prebuilt management binary. All + four services started, existing data and SearXNG secret persisted, and the + new owner setup token was generated in the same root .env. These tests used + disposable local data; they did not register a real production owner. |
