[Unit] Description=ttyd — chat.saiden.dev web terminal (BT-7274 bridge) After=network-online.target Wants=network-online.target [Service] Type=simple User=chi Group=chi WorkingDirectory=/home/chi Environment=HOME=/home/chi Environment=TERM=xterm-256color Environment=LANG=en_US.UTF-8 # ttyd flags: # -p 7681 : listen on this port # -i lo : LOCALHOST ONLY — public path is via cloudflared # -W : enable writable terminal (input from browser) # -t titleFixed=... : browser tab title # -t fontFamily=... : font # -t fontSize=14 # -t cursorBlink=true # -t theme={...} : Saiden dark palette # -T xterm-256color # -O : check origin (CSRF defense) # -c chi:DUMMY : ttyd basic auth — ignored, CF Access is the real gate, # but enabling -c blocks accidental direct access ExecStart=/home/linuxbrew/.linuxbrew/bin/ttyd \ -p 7681 \ -i lo \ -W \ -O \ -T xterm-256color \ -t titleFixed='BT-7274 — chat.saiden.dev' \ -t fontFamily='JetBrains Mono, Menlo, monospace' \ -t fontSize=14 \ -t cursorBlink=true \ -t cursorStyle=bar \ -t 'theme={"background":"#0a0d10","foreground":"#c8d3d8","cursor":"#7fb069","cursorAccent":"#0a0d10","selectionBackground":"#1f2a30","black":"#0a0d10","red":"#c94f4f","green":"#7fb069","yellow":"#d4a85a","blue":"#5c8fb8","magenta":"#a070b8","cyan":"#5cb8a8","white":"#c8d3d8","brightBlack":"#3a4248","brightRed":"#e06a6a","brightGreen":"#9ec77f","brightYellow":"#e8c275","brightBlue":"#7eb0d4","brightMagenta":"#bb8fce","brightCyan":"#7fd4c4","brightWhite":"#e8edf0"}' \ /home/chi/.local/bin/ttyd-wrapper.sh Restart=on-failure RestartSec=3 StandardOutput=journal StandardError=journal # Hardening — ttyd doesn't need much NoNewPrivileges=true ProtectSystem=strict ProtectHome=read-only ReadWritePaths=/home/chi/.marauder /home/chi/.claude /tmp PrivateTmp=true [Install] WantedBy=multi-user.target