feat(audit): record and display actor full name in audit logs#233
Merged
Conversation
- Add an ActorFullName snapshot column to the audit log model and entry - Add a context helper to read the actor full name during enrichment - Fill the full name from the context user or a single backfill lookup - Show username with full name in the audit and dashboard actor columns - Match the audit search against the actor full name - Add a separate actor full name column to the CSV export
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the audit logging pipeline to snapshot and surface an actor’s full name alongside the username, enabling display as username (full name), search by full name, and CSV export of the full-name field.
Changes:
- Add
ActorFullNameto the shared audit entry/model contract and persist it inaudit_logs. - Enrich audit log building to fill full name from request context or a DB fallback (skipping machine identities).
- Update admin UI templates, search filtering, and CSV export to display/export the full name; add tests for enrichment and search.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/templates/admin_dashboard.templ | Render actor as username (full name) via UserDisplay. |
| internal/templates/admin_audit_logs.templ | Update actor rendering and search placeholder to include full name. |
| internal/store/audit_log.go | Extend search filter to match actor_full_name. |
| internal/store/audit_log_test.go | Add coverage for searching by actor full name. |
| internal/services/audit.go | Enrich audit log entries with actor full name and persist it. |
| internal/services/audit_test.go | Add test coverage for context + DB fallback full-name enrichment. |
| internal/models/context.go | Add GetFullNameFromContext helper. |
| internal/models/audit_log.go | Add actor_full_name column to AuditLog model. |
| internal/handlers/audit.go | Add “Actor Full Name” column to CSV export output. |
| internal/core/audit.go | Add ActorFullName to core.AuditLogEntry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Truncate actor username and full name to the varchar(100) audit columns so over-long names cannot error the INSERT on Postgres - Add a unit test for the full name context accessor - Cover actor name truncation in the audit log builder tests
- Clamp audit string fields only when they exceed the varchar width so values already within the limit are stored verbatim instead of being needlessly truncated with an ellipsis - Drop the now-unused GetFullNameFromContext helper and its test; the audit builder reads the full name from the context user directly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Audit logs currently show only the actor's username in the Actor column. This PR records the actor's full name as an immutable snapshot at write time and surfaces it across the admin audit views, so reviewers can tell who acted and search by a person's real name. The actor now renders as
username (full name)(falling back to bareusernamewhen no full name exists), the audit search matches on full name, and the CSV export gains a dedicated full-name column. Existing rows are unaffected — no backfill.AI Authorship
internal/services/audit.go,internal/models/context.go,internal/core/audit.go, andinternal/store/audit_log.go, plus the handler/template/model changes. All 13ActorUsernamecall sites were audited to rule out full-name misattribution.Change classification
Touches the shared
AuditLogEntrycontract, a shared context helper, a DB schema column, and the centralbuildAuditLogenrichment path that every audited action flows through.Plan reference
See
plan.mdin the repo — "Audit Log Actor — record & display username + full name". Both of its open questions were resolved before implementation: (1) CSV export uses a separate "Actor Full Name" column; (2) the DB lookup is decoupled so the full name is backfilled even when the username is already set.Verification
buildAuditLogfills full name from context, from the DB-lookup fallback, and when the username is already pre-set; machine identities (client:<id>) still skip the lookupGetAuditLogsPaginatedmatches a stored actor full name ("Wang Xiaoming" via search "Xiaoming") and returns nothing for a non-matching termmake generate && make build && ./bin/authgate server, log in as admin, perform an action, open/admin/auditand the dashboard, confirm the Actor column showsusername (full name), search the full name, then export CSV and confirm the new column.Verifiability check
ActorUsername)UserDisplayhelper without re-reading every lineRisk & rollback
varchar(100), supported on both SQLite and Postgres;AuditLogis already in the migration list. Misattribution risk is mitigated by reusing the existingActorUserID-vs-context guard. Empty()rendering is prevented byUserDisplayreturning a bare username when the full name is empty.Reviewer guide
internal/services/audit.go— the refactoredbuildAuditLogenrichment (context fill + decoupled DB fallback, gated onresolvedFromContextto avoid a redundant query when the context user already supplies the actor).internal/core/audit.go,internal/models/audit_log.go,internal/models/context.go, the two.templactor cells, and the CSV export columns ininternal/handlers/audit.go— all are one-line parallels of the existingActorUsernamepattern.Note for reviewers (non-blocking, from self-review)
The decoupled DB lookup means call sites that pre-set
ActorUsernamebut notActorFullName(e.g. login-failure and admin user-management events) now incur one indexedGetUserByIDin the async/batched audit path. Impact is low (off the request critical path, PK lookup,/loginrate-limited). Happy to follow up by settingActorFullNamedirectly at the call sites that already hold the*User, if preferred.🤖 Generated with Claude Code