diff --git a/internal/api/router.go b/internal/api/router.go index 06d9f768c..48f9f58dd 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -289,9 +289,13 @@ func (r *Router) setupRoutes() { // GET is for agents to fetch config (host config scope) // PATCH is for UI to update config (host_manage scope, admin only) if req.Method == http.MethodPatch { - if !ensureScope(w, req, config.ScopeHostManage) { - return - } + RequireAdmin(r.config, func(w http.ResponseWriter, req *http.Request) { + if !ensureScope(w, req, config.ScopeHostManage) { + return + } + r.hostAgentHandlers.HandleConfig(w, req) + })(w, req) + return } r.hostAgentHandlers.HandleConfig(w, req) return @@ -299,10 +303,12 @@ func (r *Router) setupRoutes() { // Route DELETE /api/agents/host/{id} to HandleDeleteHost // SECURITY: Require settings:write (not just host_manage) to prevent compromised host tokens from deleting other hosts if req.Method == http.MethodDelete { - if !ensureScope(w, req, config.ScopeSettingsWrite) { - return - } - r.hostAgentHandlers.HandleDeleteHost(w, req) + RequireAdmin(r.config, func(w http.ResponseWriter, req *http.Request) { + if !ensureScope(w, req, config.ScopeSettingsWrite) { + return + } + r.hostAgentHandlers.HandleDeleteHost(w, req) + })(w, req) return } http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) diff --git a/internal/api/security_regression_test.go b/internal/api/security_regression_test.go index 78e01d47f..efa785094 100644 --- a/internal/api/security_regression_test.go +++ b/internal/api/security_regression_test.go @@ -1965,6 +1965,8 @@ func TestProxyAuthNonAdminDeniedAdminEndpoints(t *testing.T) { {method: http.MethodDelete, path: "/api/agents/kubernetes/clusters/cluster-1", body: ``}, {method: http.MethodPost, path: "/api/agents/host/link", body: `{}`}, {method: http.MethodPost, path: "/api/agents/host/unlink", body: `{}`}, + {method: http.MethodPatch, path: "/api/agents/host/host-1/config", body: `{}`}, + {method: http.MethodDelete, path: "/api/agents/host/agent-1", body: ``}, {method: http.MethodGet, path: "/api/admin/profiles/", body: ""}, {method: http.MethodPost, path: "/api/agent-install-command", body: `{}`}, {method: http.MethodPost, path: "/api/setup-script-url", body: `{}`},