Files
2026-05-29 13:47:34 +02:00

71 lines
3.0 KiB
Markdown

# 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