Files
riotpiao.com/tasks/05-phase4-terminal.md
T

1.5 KiB

Phase 4 — Surface C: terminal

~2 days. First surface accepting user input — injection (A03) is the primary risk here.

RED

  • exec_parse_test.go — fuzz corpus: every non-allowlisted input rejects and performs zero upstream calls
  • exec_test.go — unknown namespace rejects on snapshot membership, not regex
  • terminal.e2e.ts (Playwright, hard requirement) — load terminal UI, submit get nodes, assert rendered output; submit an injection payload, assert rejection surfaces in UI, zero upstream call

GREEN

  • POST /api/exec — session cookie, 20/min/session; input parses to a closed command enum, anything unmatched rejected before any lookup
  • Command set: get nodes, get pods <ns>, get apps, top nodes, describe pod <ns> <name>, help
  • Namespace and resource-name arguments validated by set membership against current snapshot, not regex/escaping
  • No shell, no exec, no kubectl binary in the container image
  • Frontend: reuse components/InteractiveTerminal.tsx, wire to /api/exec
  • Structured logging: every rejected /api/exec input logged

REFACTOR

  • simplify pass on the enum parser

Verify

# attempt injection payloads against /api/exec; all rejected, all logged
curl -X POST https://riotpiao.com/api/exec -d '{"cmd":"get pods; rm -rf /"}'
pnpm test:e2e terminal.e2e.ts   # required, must pass before merge

Next: 06-phase5-chat.md