get('/superuser/system/security/summary', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/system/security/summary'); global $response; $this->requireClassicSuperuserPermission('superuser_security_view'); $response->success((new security_policy_service())->summary()); }, [ 'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents', ]); $this->get('/superuser/system/security/settings', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/system/security/settings'); global $response; $this->requireClassicSuperuserPermission('superuser_security_view'); $response->success((new security_policy_service())->settings()); }, [ 'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents', 'superuser_security_limits_exempt' => 'Exempt requests from observe-mode security limit incidents', ]); $this->patch('/superuser/system/security/settings', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/system/security/settings'); global $response; $this->requireClassicSuperuserPermission('superuser_security_settings_manage'); try { $response->success((new security_policy_service())->updateSettings( $this->getParametersAsArray(), $this->actorUserId() )); } catch (Throwable $throwable) { $response->error(['message' => $throwable->getMessage()], 400); } }, [ 'superuser_security_settings_manage' => 'Configure observe-mode security thresholds and exemptions', ]); $this->get('/superuser/system/security/firewall-rules', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/system/security/firewall-rules'); global $response; $this->requireClassicSuperuserPermission('superuser_security_view'); $response->success((new security_policy_service())->listFirewallRules($this->getParametersAsArray())); }, [ 'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents', ]); $this->post('/superuser/system/security/firewall-rules', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/system/security/firewall-rules'); global $response; $this->requireClassicSuperuserPermission('superuser_security_firewall_manage'); try { $response->success((new security_policy_service())->createFirewallRule( $this->getParametersAsArray(), $this->actorUserId() ), 201); } catch (Throwable $throwable) { $response->error(['message' => $throwable->getMessage()], 400); } }, [ 'superuser_security_firewall_manage' => 'Create, update, and delete application firewall rules', ]); $this->patch('/superuser/system/security/firewall-rules/{id}', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/system/security/firewall-rules/{id}'); global $response; $this->requireClassicSuperuserPermission('superuser_security_firewall_manage'); try { $response->success((new security_policy_service())->updateFirewallRule( $this->routeId(), $this->getParametersAsArray(), $this->actorUserId() )); } catch (Throwable $throwable) { $response->error(['message' => $throwable->getMessage()], 400); } }, [ 'superuser_security_firewall_manage' => 'Create, update, and delete application firewall rules', ]); $this->delete('/superuser/system/security/firewall-rules/{id}', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/system/security/firewall-rules/{id}'); global $response; $this->requireClassicSuperuserPermission('superuser_security_firewall_manage'); try { $response->success((new security_policy_service())->deleteFirewallRule( $this->routeId(), $this->actorUserId() )); } catch (Throwable $throwable) { $response->error(['message' => $throwable->getMessage()], 400); } }, [ 'superuser_security_firewall_manage' => 'Create, update, and delete application firewall rules', ]); $this->get('/superuser/system/security/incidents', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/system/security/incidents'); global $response; $this->requireClassicSuperuserPermission('superuser_security_view'); $response->success((new security_policy_service())->listIncidents($this->getParametersAsArray())); }, [ 'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents', ]); $this->get('/superuser/system/security/incidents/{id}', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/system/security/incidents/{id}'); global $response; $this->requireClassicSuperuserPermission('superuser_security_view'); try { $response->success((new security_policy_service())->incidentDetail($this->routeId())); } catch (Throwable $throwable) { $response->error(['message' => $throwable->getMessage()], 404); } }, [ 'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents', ]); $this->patch('/superuser/system/security/incidents/{id}', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/system/security/incidents/{id}'); global $response; $this->requireClassicSuperuserPermission('superuser_security_incidents_manage'); try { $response->success((new security_policy_service())->updateIncident( $this->routeId(), $this->getParametersAsArray(), $this->actorUserId() )); } catch (Throwable $throwable) { $response->error(['message' => $throwable->getMessage()], 400); } }, [ 'superuser_security_incidents_manage' => 'Acknowledge, resolve, reopen, and note security incidents', ]); $this->post('/superuser/system/security/incidents/{id}/notes', function () { ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/system/security/incidents/{id}/notes'); global $response; $this->requireClassicSuperuserPermission('superuser_security_incidents_manage'); try { $parameters = $this->getParametersAsArray(); $response->success((new security_policy_service())->addIncidentNote( $this->routeId(), (string)($parameters['note'] ?? ''), $this->actorUserId() ), 201); } catch (Throwable $throwable) { $response->error(['message' => $throwable->getMessage()], 400); } }, [ 'superuser_security_incidents_manage' => 'Acknowledge, resolve, reopen, and note security incidents', ]); } private function requireClassicSuperuserPermission(string $permission): bool { global $response; if ((new authentication())->get_subuser() !== false) { $response->error('Subuser sessions cannot manage security controls.', 403); } return $this->requirePermission($permission); } private function routeId(): int { $id = (int)$this->fromRoute('id'); $this->requireParameterIntPositive($id, 'id'); return $id; } private function actorUserId(): ?int { try { $user = (new authentication())->get_user(); return $user !== false && isset($user->id) ? (int)$user->id : null; } catch (Throwable) { return null; } } }