fix(security): scope workflow target and monitor runner validation to the caller's tags

This commit is contained in:
2026-09-09 08:33:38 +00:00
parent 5fcfb40084
commit 6a48dd5d73
6 changed files with 63 additions and 19 deletions
+2 -2
View File
@@ -83,7 +83,7 @@ func createMonitor(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
created, err := services.CreateMonitor(auth.InstanceID(c), &m)
created, err := services.CreateMonitor(auth.InstanceID(c), &m, auth.ServerScope(c))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
@@ -186,7 +186,7 @@ func updateMonitor(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "no fields to update"})
return
}
if err := services.UpdateMonitor(auth.InstanceID(c), c.Param("id"), upd); err != nil {
if err := services.UpdateMonitor(auth.InstanceID(c), c.Param("id"), upd, auth.ServerScope(c)); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
+15
View File
@@ -116,6 +116,21 @@ var serverScopedRoutes = map[string]bool{
"GET /api/workflows": true,
"GET /api/workflows/:id": true,
// createWorkflow/updateWorkflow validate target_server_ids through
// services.validateTargetServers, which resolves each named ID with
// GetServerScoped — so a restricted token can neither save a workflow
// targeting a host outside its scope (which the scheduler, firing as the
// system, would otherwise run there) nor learn which IDs exist by the
// difference between "target server not found" and a successful save.
"POST /api/workflows": true,
"PUT /api/workflows/:id": true,
// createMonitor/updateMonitor validate the runner — which is a server ID
// for an agent-pushed monitor — through services.validateRunner, now
// resolving with GetServerScoped for the same two reasons.
"POST /api/monitors": true,
"PUT /api/monitors/:id": true,
// Creating a server has no server to filter yet.
"POST /api/servers": false,
// The agent's own enrolment routes authenticate as the agent, not as a
+2 -2
View File
@@ -477,7 +477,7 @@ func createWorkflow(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
out, err := services.CreateWorkflow(auth.InstanceID(c), w)
out, err := services.CreateWorkflow(auth.InstanceID(c), w, auth.ServerScope(c))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
@@ -534,7 +534,7 @@ func updateWorkflow(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := services.UpdateWorkflow(auth.InstanceID(c), c.Param("id"), w); err != nil {
if err := services.UpdateWorkflow(auth.InstanceID(c), c.Param("id"), w, auth.ServerScope(c)); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}