0.8.0

Added

  • Setup-токен: при старте без юзеров TaigaClaw генерирует одноразовый 32-байтный URL-safe токен, печатает его в stderr и подставляет в URL открываемого браузера (/onboarding?setup_token=...). /api/v1/setup без знания токена отдаёт 403
  • Флаг --bind и env TAIGACLAW_BIND для выбора интерфейса. По умолчанию — 127.0.0.1 (раньше 0.0.0.0)
  • Rate-limit middleware (internal/server/middleware/ratelimit.go): in-memory sliding-window 5 запросов/минута/IP на /oauth/* и /api/v1/setup
  • Per-account login lockout (internal/auth/lockout.go): 5 неудачных попыток за 15 минут блокируют username на 15 минут
  • Security-headers middleware (internal/server/middleware/securityheaders.go): CSP с allowlist 'self' и запретом inline-script, X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: no-referrer, Permissions-Policy, HSTS только под TLS
  • Эндпоинты /healthz (всегда 200, без БД) и /readyz (с БД, 503 при ошибках). /api/v1/health оставлен как алиас Readyz для обратной совместимости
  • Маски *** для секретных полей Headers и Env в ответах MCP API. Update игнорирует значение *** в request, чтобы не перезаписывать секрет маской
  • Поле setup_token в WebUI/onboarding: автоматически забирается из URL, при ручном переходе показывается поле для ввода
  • Тесты: ratelimit_test.go, securityheaders_test.go, setup_test.go (middleware и handler), lockout_test.go, mcp_test.go. Всего ~25 новых кейсов

Changed

  • CORS-allowlist по умолчанию пустой (same-origin only). Раскрывается через env TAIGACLAW_CORS_ORIGINS=https://a,https://b. Раньше было AllowedOrigins: ["*"] с AllowCredentials: true
  • /api/v1/metrics перенесён под RequireGlobalAdmin (раньше был публичным)
  • /api/v1/mcp-servers, /api/v1/settings/providers, /api/v1/preset-commands перенесены в защищённую группу с auth-middleware
  • server.New(handler, port)server.New(handler, bind, port) — bind стал явным параметром
  • middleware.NewSetupGuard(s)NewSetupGuard(s, token) — guard теперь хранит токен и проверяет его через crypto/subtle
  • handler.NewSetupHandler(oauth)NewSetupHandler(oauth, guard) — handler требует setup-токен в body

Fixed

  • C-4: race «первый получит admin» — без знания setup-токена аккаунт не создать; bind по умолчанию loopback
  • M-1: отсутствие rate-limit на /oauth/login и /oauth/token (теперь 5/min/IP + 5/15min lockout по аккаунту)
  • M-2 (частично): сервер слушал 0.0.0.0 — теперь 127.0.0.1 по умолчанию. TLS-документация — в итерации 22
  • M-3: отсутствие HTTP security-заголовков
  • M-4: mcp-servers, settings/providers, preset-commands, metrics отдавались без auth
  • M-8: MCPHandler.List раскрывал HeadersAuthorization: Bearer) и Env (с API-ключами) без фильтрации