diff --git a/app/app/Http/Middleware/EnsureSaasAdmin.php b/app/app/Http/Middleware/EnsureSaasAdmin.php index 7e232499..588d4999 100644 --- a/app/app/Http/Middleware/EnsureSaasAdmin.php +++ b/app/app/Http/Middleware/EnsureSaasAdmin.php @@ -11,28 +11,26 @@ use Symfony\Component\HttpFoundation\Response; /** * Гейт SaaS-admin зоны (/api/admin/*) — audit-находка J2. * - * СТАБ (Sprint 3F): полноценная авторизация saas-admin требует Yandex 360 - * SSO-входа, который гейтится Б-1 (регистрация ООО) + DO-4. До их закрытия - * реального механизма аутентификации нет. + * СТОПГЭП (2026-05-25): защита боевой админ-зоны (/admin + /api/admin/*) + * перенесена на уровень nginx — отдельный HTTP Basic Auth с собственным + * паролем (`/etc/nginx/.htpasswd-admin`, location ^~ /admin и ^~ /api/admin). + * Поэтому middleware больше не закрывает зону на проде: дверь держит nginx. * - * Поведение стаба: - * - dev / testing (local, testing) → пропускаем. Admin-панель работает на - * dev; admin_user_id передаётся параметром (трейт ResolvesAdminUserId). - * - прочие окружения (production / staging) → fail-closed 503: зона - * закрыта до подключения реального SSO. Явный 503 лучше, чем тихо - * открытый /api/admin/* в проде. + * Ранее (Sprint 3F) здесь был fail-closed 503 вне dev/testing — он закрывал + * всю админку на проде наглухо, т.к. настоящий saas-admin SSO (Yandex 360) + * ещё не готов (гейтится Б-1 + DO-4). Замок 503 снят осознанно: оголять + * /api/admin/* в интернет нельзя, но nginx-пароль её прикрывает. * - * TODO (после Б-1 + DO-4): заменить на проверку Yandex 360 SSO-сессии - * saas-admin (отдельный guard) + роль (compliance и т.п. где требуется). + * admin_user_id для audit-trail по-прежнему резолвится трейтом + * ResolvesAdminUserId (стаб super_admin) — это отдельная зона. + * + * TODO (после Б-1 + DO-4): заменить nginx-дверь на настоящий saas-admin + * guard (Yandex 360 SSO-сессия + роль), вернуть проверку в это middleware. */ class EnsureSaasAdmin { public function handle(Request $request, Closure $next): Response { - if (! app()->environment('local', 'testing')) { - abort(503, 'SaaS-admin авторизация не настроена (ожидает Б-1 + DO-4).'); - } - return $next($request); } } diff --git a/app/tests/Feature/SaasAdminMiddlewareTest.php b/app/tests/Feature/SaasAdminMiddlewareTest.php index 8fd815d4..a09cc7c9 100644 --- a/app/tests/Feature/SaasAdminMiddlewareTest.php +++ b/app/tests/Feature/SaasAdminMiddlewareTest.php @@ -5,21 +5,25 @@ declare(strict_types=1); use Illuminate\Foundation\Testing\DatabaseTransactions; /** - * J2 (Sprint 3F) — стаб-гейт SaaS-admin зоны. + * J2 (Sprint 3F) — гейт SaaS-admin зоны. * - * EnsureSaasAdmin на /api/admin/*: dev/testing пропускает (admin-панель - * работает на dev), прочие окружения — fail-closed 503 до подключения - * реального Yandex 360 SSO (TODO под Б-1+DO-4). + * EnsureSaasAdmin на /api/admin/*: пропускает запрос во ВСЕХ окружениях. + * Защита боевой админ-зоны (/admin + /api/admin/*) перенесена на nginx + * (HTTP Basic Auth, отдельный пароль — /etc/nginx/.htpasswd-admin), потому + * что настоящий saas-admin SSO (Yandex 360) ещё не готов (Б-1 + DO-4). + * Ранее middleware fail-closed 503 вне dev/testing — это закрывало всю + * админку на проде наглухо; стопгэп заменил замок на nginx-дверь. */ uses(DatabaseTransactions::class); -test('/api/admin/* пропускается на testing-окружении (стаб permissive)', function () { - // Дефолтное тестовое окружение = testing → middleware пропускает. +test('/api/admin/* пропускается на testing-окружении', function () { $this->getJson('/api/admin/tenants')->assertStatus(200); }); -test('/api/admin/* возвращает 503 вне dev/testing (стаб fail-closed)', function () { +test('/api/admin/* пропускается и на production (замок 503 снят, дверь держит nginx)', function () { $this->app->detectEnvironment(fn () => 'production'); - $this->getJson('/api/admin/tenants')->assertStatus(503); + // Раньше тут был 503. Теперь приложение зону не закрывает — её держит + // nginx basic-auth (стопгэп до реального Yandex 360 SSO). + $this->getJson('/api/admin/tenants')->assertStatus(200); }); diff --git a/docs/observer/STATUS.md b/docs/observer/STATUS.md index 06245192..799e8d9d 100644 --- a/docs/observer/STATUS.md +++ b/docs/observer/STATUS.md @@ -1,6 +1,6 @@ # Brain Status (auto-generated) -Last updated: 2026-05-25T03:31:18.491Z +Last updated: 2026-05-25T04:31:41.337Z | Контролёр | Состояние | Детали | |---|---|---| @@ -8,13 +8,13 @@ Last updated: 2026-05-25T03:31:18.491Z | C2 Cross-ref consistency | 🔴 | Update cross-refs in offending files. | | C3 Observer-of-observer | ✅ | [observer-of-observer] OK — last read 0 week(s) ago | | C4 Сигнальный статус | ✅ | This file (self-reference) | -| C5 Observer-coverage | ⚠️ | 339 episode(s) this month · Stop-hook + post-commit OK · 21 missed activation(s) — see /brain-retro | +| C5 Observer-coverage | ⚠️ | 341 episode(s) this month · Stop-hook + post-commit OK · 21 missed activation(s) — see /brain-retro | | C6 Chain map sync | ✅ | [chain-map-checker] OK — 16 chains in sync | ## Метрики (информационные, не алерты) -- Observer evidence: 339 episodes this month, 0 observer_error markers, 31 PII matches before filter -- Legacy v1 episodes (not in factor analysis): 200 +- Observer evidence: 341 episodes this month, 0 observer_error markers, 31 PII matches before filter +- Legacy v1 episodes (not in factor analysis): 202 - Last /brain-retro: 0 day(s) ago - Использование узлов: см. `/brain-retro` (раз в спринт). missed_activations: 21. **Неиспользованные узлы — не алерт, если профильной задачи не было** (Pravila §16.4 v1.36; capability-readiness; см. memory `feedback_brain_unused_tools_not_problem` — outside-repo memory store). @@ -27,14 +27,14 @@ Baseline дисциплины роутера (этап 2 router discipline overh | analysis | 15 | 46.7% | 26.7% | | monitoring | 12 | 0.0% | 0.0% | | bugfix | 10 | 40.0% | 40.0% | +| planning | 9 | 11.1% | 22.2% | | feature | 9 | 22.2% | 0.0% | -| planning | 7 | 14.3% | 14.3% | | refactor | 1 | 0.0% | 0.0% | | cleanup | 1 | 0.0% | 0.0% | -Router step distribution: 1: 139, 2: 117, 3: 37, 5: 41 +Router step distribution: 1: 139, 2: 118, 3: 37, 5: 42 -Boundaries applied (ADR / границы): 47 of 334 эпизодов (14.1%). +Boundaries applied (ADR / границы): 47 of 336 эпизодов (14.0%). ## Активные многоэтапные проекты