fix: address review findings for observability PR
All checks were successful
Check / check (pull_request) Successful in 1m42s

1. Security: Replace insecure extractRemoteIP() in audit service with
   middleware.RealIP() which validates trusted proxies before trusting
   X-Real-IP/X-Forwarded-For headers. Export RealIP from middleware.
   Update audit tests to verify anti-spoofing behavior.

2. Audit coverage: Add audit instrumentation to all 9 handlers that
   had dead action constants: HandleEnvVarSave, HandleLabelAdd,
   HandleLabelEdit, HandleLabelDelete, HandleVolumeAdd, HandleVolumeEdit,
   HandleVolumeDelete, HandlePortAdd, HandlePortDelete.

3. README: Fix API path from /api/audit to /api/v1/audit.

4. README: Fix duplicate numbering in DI order section (items 10-11
   were listed twice, now correctly numbered 10-16).
This commit is contained in:
clawbot
2026-03-17 02:52:34 -07:00
parent f558e2cdd8
commit ef109b9513
6 changed files with 79 additions and 45 deletions

View File

@@ -1023,6 +1023,10 @@ func (h *Handlers) HandleEnvVarSave() http.HandlerFunc {
return
}
h.auditLog(request, models.AuditActionEnvVarSave,
models.AuditResourceEnvVar, application.ID,
fmt.Sprintf("saved %d env vars", len(modelPairs)))
h.respondJSON(writer, request, map[string]bool{"ok": true}, http.StatusOK)
}
}
@@ -1039,7 +1043,13 @@ func (h *Handlers) HandleLabelAdd() http.HandlerFunc {
label.Key = key
label.Value = value
return label.Save(ctx)
err := label.Save(ctx)
if err == nil {
h.auditLog(request, models.AuditActionLabelAdd,
models.AuditResourceLabel, application.ID, "added label: "+key)
}
return err
},
)
}
@@ -1068,6 +1078,9 @@ func (h *Handlers) HandleLabelDelete() http.HandlerFunc {
deleteErr := label.Delete(request.Context())
if deleteErr != nil {
h.log.Error("failed to delete label", "error", deleteErr)
} else {
h.auditLog(request, models.AuditActionLabelDelete,
models.AuditResourceLabel, appID, "deleted label: "+label.Key)
}
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
@@ -1125,6 +1138,10 @@ func (h *Handlers) HandleVolumeAdd() http.HandlerFunc {
saveErr := volume.Save(request.Context())
if saveErr != nil {
h.log.Error("failed to add volume", "error", saveErr)
} else {
h.auditLog(request, models.AuditActionVolumeAdd,
models.AuditResourceVolume, application.ID,
"added volume: "+hostPath+":"+containerPath)
}
http.Redirect(writer, request, "/apps/"+application.ID, http.StatusSeeOther)
@@ -1154,6 +1171,10 @@ func (h *Handlers) HandleVolumeDelete() http.HandlerFunc {
deleteErr := volume.Delete(request.Context())
if deleteErr != nil {
h.log.Error("failed to delete volume", "error", deleteErr)
} else {
h.auditLog(request, models.AuditActionVolumeDelete,
models.AuditResourceVolume, appID,
"deleted volume: "+volume.HostPath+":"+volume.ContainerPath)
}
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
@@ -1203,6 +1224,10 @@ func (h *Handlers) HandlePortAdd() http.HandlerFunc {
saveErr := port.Save(request.Context())
if saveErr != nil {
h.log.Error("failed to save port", "error", saveErr)
} else {
h.auditLog(request, models.AuditActionPortAdd,
models.AuditResourcePort, application.ID,
fmt.Sprintf("added port: %d:%d/%s", hostPort, containerPort, protocol))
}
http.Redirect(writer, request, "/apps/"+application.ID, http.StatusSeeOther)
@@ -1249,6 +1274,10 @@ func (h *Handlers) HandlePortDelete() http.HandlerFunc {
deleteErr := port.Delete(request.Context())
if deleteErr != nil {
h.log.Error("failed to delete port", "error", deleteErr)
} else {
h.auditLog(request, models.AuditActionPortDelete,
models.AuditResourcePort, appID,
fmt.Sprintf("deleted port: %d:%d/%s", port.HostPort, port.ContainerPort, port.Protocol))
}
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
@@ -1324,6 +1353,9 @@ func (h *Handlers) HandleLabelEdit() http.HandlerFunc {
saveErr := label.Save(request.Context())
if saveErr != nil {
h.log.Error("failed to update label", "error", saveErr)
} else {
h.auditLog(request, models.AuditActionLabelEdit,
models.AuditResourceLabel, appID, "edited label: "+key)
}
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
@@ -1382,6 +1414,10 @@ func (h *Handlers) HandleVolumeEdit() http.HandlerFunc {
saveErr := volume.Save(request.Context())
if saveErr != nil {
h.log.Error("failed to update volume", "error", saveErr)
} else {
h.auditLog(request, models.AuditActionVolumeEdit,
models.AuditResourceVolume, appID,
"edited volume: "+hostPath+":"+containerPath)
}
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)