feat(httpapi): add local audit log with portal dual-write
Локальный audit_log (миграции pg/sqlite), GET /v1/audit, запись на CRUD и async push в auth-portal (source_app=bgp). Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -131,6 +131,7 @@ func (s *Server) handlePostAPIKey(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
out := apiKeyJSON(&created.APIKey)
|
||||
out["token"] = created.Token
|
||||
s.recordCRUDAudit(r, a, "bgp.api_key.create", "Created API key "+created.Name, created.ID, map[string]any{"api_key_id": created.ID, "role": created.Role})
|
||||
writeJSON(w, http.StatusCreated, out)
|
||||
}
|
||||
|
||||
@@ -187,6 +188,7 @@ func (s *Server) handlePatchAPIKey(w http.ResponseWriter, r *http.Request) {
|
||||
writeProblem(w, http.StatusInternalServerError, "Internal Server Error", "failed to reload api keys")
|
||||
return
|
||||
}
|
||||
s.recordCRUDAudit(r, a, "bgp.api_key.update", "Updated API key "+k.Name, k.ID, map[string]any{"api_key_id": k.ID, "role": k.Role})
|
||||
writeJSON(w, http.StatusOK, apiKeyJSON(k))
|
||||
}
|
||||
|
||||
@@ -195,7 +197,8 @@ func (s *Server) handleDeleteAPIKey(w http.ResponseWriter, r *http.Request) {
|
||||
if !ok || !s.requirePerm(w, a, "bgp:access:admin") {
|
||||
return
|
||||
}
|
||||
if err := s.store.RevokeAPIKey(a.TenantID, r.PathValue("id")); err != nil {
|
||||
keyID := r.PathValue("id")
|
||||
if err := s.store.RevokeAPIKey(a.TenantID, keyID); err != nil {
|
||||
writeStoreErr(w, err)
|
||||
return
|
||||
}
|
||||
@@ -203,6 +206,7 @@ func (s *Server) handleDeleteAPIKey(w http.ResponseWriter, r *http.Request) {
|
||||
writeProblem(w, http.StatusInternalServerError, "Internal Server Error", "failed to reload api keys")
|
||||
return
|
||||
}
|
||||
s.recordCRUDAudit(r, a, "bgp.api_key.revoke", "Revoked API key", keyID, map[string]any{"api_key_id": keyID})
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
@@ -222,5 +226,6 @@ func (s *Server) handleRotateAPIKey(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
out := apiKeyJSON(&rotated.APIKey)
|
||||
out["token"] = rotated.Token
|
||||
s.recordCRUDAudit(r, a, "bgp.api_key.rotate", "Rotated API key "+rotated.Name, rotated.ID, map[string]any{"api_key_id": rotated.ID})
|
||||
writeJSON(w, http.StatusOK, out)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user