chore: initial commit — chat-saiden web chat baseline
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# chat-saiden
|
||||
|
||||
Web terminal for BT on the MARAUDER mesh. **chat.saiden.dev** lands a browser-native
|
||||
xterm.js session on `claude` CLI (bt7274 cart) running on junkpile, gated by
|
||||
Cloudflare Access with Google OAuth.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
User browser
|
||||
│ HTTPS
|
||||
▼
|
||||
chat.saiden.dev ──┐ Cloudflare edge
|
||||
│ │
|
||||
│ CF Access │ Google IdP challenge
|
||||
│ (whitelist) │ → reject if not on list
|
||||
│ │
|
||||
▼ │
|
||||
Cloudflare Tunnel │ Zero-trust ingress
|
||||
│ │
|
||||
▼
|
||||
junkpile:7681 │ ttyd (localhost-only, no public bind)
|
||||
│ │
|
||||
▼
|
||||
claude (bt7274) │ marauder MCP gives BT identity + memory + tools
|
||||
```
|
||||
|
||||
**Properties**
|
||||
- No frontend code. ttyd ships xterm.js + WS + theming. Custom Saiden palette via CLI flags.
|
||||
- No auth code. CF Access does Google OAuth + whitelist enforcement before the request ever reaches the tunnel.
|
||||
- ttyd binds `127.0.0.1` only — the public path is *exclusively* through the Tunnel + Access.
|
||||
- Real BT. Not an API impersonation. Full marauder MCP toolkit available in-session.
|
||||
|
||||
## Components
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `junkpile/ttyd-wrapper.sh` | Launches `claude` with bt7274 cart, with Saiden banner |
|
||||
| `junkpile/ttyd-chat.service` | systemd unit for ttyd (localhost-only bind, Saiden palette) |
|
||||
| `junkpile/cloudflared-chat-saiden.service` | systemd unit for tunnel (token-mode, reads `/etc/cloudflared/chat-saiden.env`) |
|
||||
| `cloudflare/dashboard-setup.md` | Step-by-step: create tunnel + public hostname + Access app + Google IdP + whitelist |
|
||||
| `install.sh` | Junkpile-side installer (ttyd + units + token env stub) |
|
||||
| `deploy.md` | End-to-end deploy walkthrough |
|
||||
|
||||
**Tunnel mode:** token-based, matches existing junkpile pattern
|
||||
(`cloudflared-mesh`, `cloudflared-tensors-art`). Tunnel ingress lives in the CF
|
||||
dashboard, not in a local config file. Token sits in
|
||||
`/etc/cloudflared/chat-saiden.env` (mode 0640, root:chi).
|
||||
|
||||
## Threat model (read before deploying)
|
||||
|
||||
ttyd-over-claude exposes **shell-equivalent power** on junkpile. The defense is the
|
||||
CF Access whitelist. Treat the whitelist as the security boundary:
|
||||
|
||||
- **Never** open the Access policy to "any Google account" or "any domain".
|
||||
- **Always** keep `cloudflared-chat-saiden` and `ttyd-chat` localhost-bound.
|
||||
- If the whitelist is ever modified, `auth_verify` the change with the Pilot first.
|
||||
|
||||
## Status
|
||||
|
||||
- [x] ttyd installed on junkpile (1.7.7_11)
|
||||
- [x] ttyd wrapper installed → `~/.local/bin/ttyd-wrapper.sh`
|
||||
- [x] systemd units installed (`ttyd-chat`, `cloudflared-chat-saiden`)
|
||||
- [ ] Tunnel created in CF dashboard → token in `/etc/cloudflared/chat-saiden.env`
|
||||
- [ ] Public hostname `chat.saiden.dev → http://localhost:7681`
|
||||
- [ ] CF Access app + Google IdP + whitelist configured
|
||||
- [ ] WebSocket support enabled on Access app
|
||||
- [ ] `sudo systemctl enable --now ttyd-chat cloudflared-chat-saiden`
|
||||
- [ ] First successful login as adam.ladachowski@gmail.com
|
||||
- [ ] Whitelist denial verified from second Google account
|
||||
Reference in New Issue
Block a user