Skip to content

Admin audit log viewer (backend endpoint exists, no UI consumes it) #45

Closed

Description

@prometheusgr

Context

GET /api/settings/audit (backend/app/api/settings.py:276-287) is a fully working, admin-only endpoint backed by AuditLogRepository.list_recent() (backend/app/repositories/audit_log_repository.py). It's populated today by every settings mutation (retention.update, guardrail.config_update, tracing.config_update, rate_limit.config_update, guardrail.pattern_update) and by two runtime events (guardrail.input_rejected, guardrail.output_redacted).

frontend/src/api/settingsClient.ts's SettingsClient never calls it. App.tsx has exactly 5 views (chat, apikeys, embeddings, embeddings-search, settings) — there is no audit view anywhere. Settings.tsx even tells an admin making a change "This change will be recorded in the audit log" (implying there's somewhere to go look), but there is no such place in the product. The only way to read audit_logs today is direct database access.

This is the largest gap found in a review of backend capabilities with no frontend surface — the backend work here (including a purpose-built read endpoint) is complete; only the consumer is missing.

Principle

Per project direction: this system should be transparent by default. Anything that inspects or changes system state — an admin's own settings edits, a guardrail trip, a rate-limit config change — should be visible in-product without requiring DB access, unless a specific fork has a real reason to hide it. Where that's a reasonable question (see below), make it configurable to disable, but default it on.

Scope

  1. Add getAuditLog (or similar) to frontend/src/api/settingsClient.ts, following the existing client pattern (HTTP-only, token param, no business logic).
  2. Add a thin service method if warranted per docs/FRONTEND_ARCHITECTURE.md's three-layer pattern (client → service → hook → component).
  3. Add an "Audit Log" admin view — a new entry in App.tsx's view set, gated the same way Settings is (admin-only) — rendering list_recent() entries: timestamp, actor, action, field, old→new value. Read-only, paginated or capped consistent with whatever the backend endpoint already returns.
  4. Config to disable the UI, off by default: some forks may not want an in-app audit trail surface (e.g. if they route audit consumption through an external SIEM instead). Add an admin-configurable flag (e.g. audit_log_ui_enabled, following the existing env-default + nullable-DB-override pattern used for tracing_enabled/guardrails_input_enabled) that can hide this view — defaulting to enabled. Do not make hiding it the default behavior of shipping this feature.

Standards

Per AGENTS.md: TDD for the new client/service/hook layers; a Vitest component test for the new view; an e2e spec once the UI exists (real login as the seeded testuser/admin, real backend) confirming an admin can see a real audit entry after making a settings change.

Done when

  • An admin can view real audit log entries from within the product, with no DB access required.
  • The view is admin-gated the same way Settings is.
  • A config flag exists to disable the view for forks that don't want it, defaulting to enabled.
  • Covered by unit/component tests and an e2e spec per the standards above.
  • docs/SECURITY.md and/or docs/AUDIT_EVENTS.md updated to describe the new UI surface.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions