diff --git a/lib/Controller/HealthController.php b/lib/Controller/HealthController.php index d239e5869..ad5bca3da 100644 --- a/lib/Controller/HealthController.php +++ b/lib/Controller/HealthController.php @@ -79,13 +79,15 @@ public function __construct( * which is a meaningful answer for a monitoring probe: the app is reachable, * its declarative health engine is not. * + * Rate-limit rationale: this is a liveness probe — no credential, so a + * ceiling and no counter. + * * @return JSONResponse `{status, app, version, checks}`. * * @spec openspec/changes/adopt-apphost/specs/prometheus-metrics/spec.md — Requirement: Health Check Endpoint (REQ-PROM-007) */ #[PublicPage] #[NoCSRFRequired] - // Liveness probe — no credential, so a ceiling and no counter. #[AnonRateLimit(limit: 120, period: 60)] public function index(): JSONResponse { $appId = $this->appName; diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 85b9986a0..9efe3ef6b 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -555,18 +555,19 @@ private function buildWorkspaceCsp(): ContentSecurityPolicy { * The image CSP is widened to `data:` so the bundled NL Design tile icons * (base64 SVG data URIs) render for anonymous visitors too. * + * Rate-limit rationale: this is the public share page — one of only four + * rendered public pages in the fleet (ADR-081). The share TOKEN is checked by + * PublicShareController, which already has brute-force protection wired + * through PublicShareService::registerAttempt(); this is just the shell that + * hosts it, so a volume ceiling is the right control and it is deliberately + * generous — a recipient reloading the page must not be what trips it. + * * @return TemplateResponse The public page response. * * @spec openspec/changes/dashboard-public-share/specs/dashboard-public-share/spec.md */ #[PublicPage] #[NoCSRFRequired] - // The public share page — one of only four rendered public pages in the - // fleet (ADR-081). The share TOKEN is checked by PublicShareController, - // which already has brute-force protection wired through - // PublicShareService::registerAttempt(); this is just the shell that hosts - // it, so a volume ceiling is the right control and it is deliberately - // generous — a recipient reloading the page must not be what trips it. #[AnonRateLimit(limit: 120, period: 60)] public function publicShare(): TemplateResponse { Util::addScript(application: Application::APP_ID, file: 'launchpad-public');