Skip to content

feat(audit): expose GET /api/v1/audit + dashboard page (closes #246)#248

Merged
epappas merged 2 commits into
mainfrom
feat/audit-log-api-and-dashboard
May 20, 2026
Merged

feat(audit): expose GET /api/v1/audit + dashboard page (closes #246)#248
epappas merged 2 commits into
mainfrom
feat/audit-log-api-and-dashboard

Conversation

@epappas
Copy link
Copy Markdown
Collaborator

@epappas epappas commented May 20, 2026

Closes #246.

Summary

The proxy already records audit events (tenant CRUD, API-key mint/revoke, config changes, etc.) but neither exposed them via HTTP nor surfaced them in the dashboard. This PR adds both halves.

Per-file changes

Rust (proxy)

  • crates/llmtrace-proxy/src/audit_api.rs (new) — GET /api/v1/audit handler. Admin-only via ApiKeyRole::Admin. Tenant is derived from AuthContext only — there is no tenant_id URL/query parameter, so operators cannot inspect another tenant's events. Accepts event_type, start_time, end_time (RFC3339), limit (default 100, clamped to 1000 with a warn log), offset. Returns a flat JSON array of AuditEvent. #[utoipa::path(...)] annotated.
  • crates/llmtrace-proxy/src/lib.rs — register audit_api module.
  • crates/llmtrace-proxy/src/main.rs — register /api/v1/audit route.
  • crates/llmtrace-proxy/src/openapi.rs — include handler in the OpenAPI document so Swagger picks it up.
  • 10 unit tests covering clamp_limit (default / explicit / over-max / zero), 200 happy path with full response-shape assertions, 401 unauthenticated, 403 operator-role rejection, event_type filter, explicit limit honoured, and tenant A vs tenant B isolation.

Dashboard

  • dashboard/src/lib/types.ts (new) — AuditEvent interface mirroring the Rust shape.
  • dashboard/src/lib/api.ts — re-exports AuditEvent and adds listAuditEvents() (returns a flat AuditEvent[], matching the locked Rust shape).
  • dashboard/src/app/audit/page.tsx (new) — table with columns Timestamp / Event type / Actor / Resource / Data (collapsible JSON). Free-text event-type filter, prev/next pagination at 100/page, plus loading / empty / error states.
  • dashboard/src/components/sidebar.tsx — adds Audit entry between Security and Costs with the ScrollText lucide icon. Grouping rationale: Audit is observability-adjacent like Security, so it sits next to it.

Validation evidence

  • cargo fmt --all — clean.
  • cargo build -p llmtrace — succeeded.
  • cargo test -p llmtrace --tests607 passed; 0 failed (unit) + 21 passed (main) + 19 passed (integration). The 10 new audit_api::tests::* all pass.
  • cd dashboard && npm run lint — only pre-existing warnings on unrelated files (compliance/page.tsx, guide/page.tsx, traces/page.tsx). No new warnings or errors from this PR.
  • cd dashboard && npm run build — succeeded; /audit route emitted (4.67 kB / 117 kB First Load JS).

Not validated

  • No live smoke test of the dashboard /audit page was performed from this worktree (no live proxy running). The page is exercised only by the Next.js build typecheck.

Out of scope (per the issue)

  • Aggregated audit dashboards / charts.
  • Cross-tenant audit views.
  • Export to CSV / JSON download.

epappas added 2 commits May 20, 2026 12:35
Adds an admin-only audit query endpoint that returns events recorded
for the caller's tenant. The tenant is derived from AuthContext so
operators cannot inspect events from another tenant. Query supports
event_type, time range, limit (default 100, capped at 1000), and
offset. Registered in the router and OpenAPI spec.
Adds an Audit nav entry (between Security and Costs) that surfaces the
tenant's audit log: timestamp, event type, actor, resource, and a
collapsible JSON payload. Includes a free-text event-type filter,
prev/next pagination at the default 100 page size, and loading /
empty / error states. Mirrors the locked Rust response shape (flat
JSON array of AuditEvent) — see crates/llmtrace-proxy/src/audit_api.rs.
@epappas epappas merged commit 53f1b51 into main May 20, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(audit): expose audit-event API + dashboard page

1 participant