feat: instrument admin operations with audit logging#534
Merged
lakhansamani merged 3 commits intofeat/audit-logfrom Apr 3, 2026
Merged
feat: instrument admin operations with audit logging#534lakhansamani merged 3 commits intofeat/audit-logfrom
lakhansamani merged 3 commits intofeat/audit-logfrom
Conversation
Create logAuditEvent() helper on graphqlProvider that extracts request info (IP, UserAgent) before spawning a fire-and-forget goroutine for safe async audit logging. Instrument all user-facing auth operations: - login (success + failed), signup, logout - verify_email, verify_otp (email vs phone conditional) - magic_link_login, forgot_password, reset_password - resend_otp, resend_verify_email - deactivate_account, update_profile
Add audit events to all admin GraphQL mutations: - admin_login (success + failed), admin_logout - delete_user, update_user, enable_access, revoke_access - invite_members - add/update/delete webhook - add/update/delete email_template
3 tasks
- Remove incorrect ActorEmail from delete_user (was logging deleted user's email as actor's email, but admin has no email) - Capture ResourceID from AddWebhook return value for audit log - Capture ResourceID from AddEmailTemplate return value for audit log
lakhansamani
added a commit
that referenced
this pull request
Apr 3, 2026
* feat: structured audit log schema & storage layer (#527) * feat: add structured audit log schema and storage layer Add AuditLog schema with support for all 6 database providers (SQL/GORM, MongoDB, ArangoDB, Cassandra, DynamoDB, Couchbase). Includes AddAuditLog, ListAuditLogs (with filtering by actor_id, action, resource_type, etc), and DeleteAuditLogsBefore for log retention. Ref: RFC #505. * chore: add more auditlog events * chore: update storage provider test * feat: add _audit_logs GraphQL query for admin audit log access (#532) Add AuditLog type, AuditLogs response, and ListAuditLogRequest input to the GraphQL schema. Supports filtering by action, actor_id, resource_type, resource_id, organization_id, and timestamp range. - Add AsAPIAuditLog() conversion method to schemas - Create audit_logs.go handler with admin-only access control - Add AuditLogs method to graphql Provider interface - Wire resolver in schema.resolvers.go * feat: add audit log helper and instrument user auth flows (#533) Create logAuditEvent() helper on graphqlProvider that extracts request info (IP, UserAgent) before spawning a fire-and-forget goroutine for safe async audit logging. Instrument all user-facing auth operations: - login (success + failed), signup, logout - verify_email, verify_otp (email vs phone conditional) - magic_link_login, forgot_password, reset_password - resend_otp, resend_verify_email - deactivate_account, update_profile * feat: instrument admin operations with audit logging (#534) * feat: add audit log helper and instrument user auth flows Create logAuditEvent() helper on graphqlProvider that extracts request info (IP, UserAgent) before spawning a fire-and-forget goroutine for safe async audit logging. Instrument all user-facing auth operations: - login (success + failed), signup, logout - verify_email, verify_otp (email vs phone conditional) - magic_link_login, forgot_password, reset_password - resend_otp, resend_verify_email - deactivate_account, update_profile * feat: instrument admin operations with audit logging Add audit events to all admin GraphQL mutations: - admin_login (success + failed), admin_logout - delete_user, update_user, enable_access, revoke_access - invite_members - add/update/delete webhook - add/update/delete email_template * fix: address review findings in admin audit instrumentation - Remove incorrect ActorEmail from delete_user (was logging deleted user's email as actor's email, but admin has no email) - Capture ResourceID from AddWebhook return value for audit log - Capture ResourceID from AddEmailTemplate return value for audit log * feat: instrument OAuth/HTTP handlers with audit logging (#535) * feat: add audit log helper and instrument user auth flows Create logAuditEvent() helper on graphqlProvider that extracts request info (IP, UserAgent) before spawning a fire-and-forget goroutine for safe async audit logging. Instrument all user-facing auth operations: - login (success + failed), signup, logout - verify_email, verify_otp (email vs phone conditional) - magic_link_login, forgot_password, reset_password - resend_otp, resend_verify_email - deactivate_account, update_profile * feat: instrument admin operations with audit logging Add audit events to all admin GraphQL mutations: - admin_login (success + failed), admin_logout - delete_user, update_user, enable_access, revoke_access - invite_members - add/update/delete webhook - add/update/delete email_template * fix: address review findings in admin audit instrumentation - Remove incorrect ActorEmail from delete_user (was logging deleted user's email as actor's email, but admin has no email) - Capture ResourceID from AddWebhook return value for audit log - Capture ResourceID from AddEmailTemplate return value for audit log * feat: instrument OAuth/HTTP handlers with audit logging Create logAuditEvent() helper for httpProvider with safe goroutine pattern (extracts IP/UserAgent before spawn, uses context.Background). Instrument HTTP handlers: - oauth_callback: AuditOAuthCallbackSuccessEvent with provider metadata - token: AuditTokenIssuedEvent / AuditTokenRefreshedEvent by grant type - revoke_refresh_token: AuditTokenRevokedEvent after session deletion - logout: AuditSessionTerminatedEvent after session cleanup * refactor: audit log schema cleanup and string literal constants (#536) Schema cleanup: - Remove OrganizationID field (no org ID exists in config) - Remove Timestamp field (duplicated CreatedAt) - Remove UpdatedAt field (audit logs are immutable) - Update all 6 DB providers, GraphQL schema, helpers, and conversion - Fix Cassandra CREATE TABLE to match new schema - Fix CreatedAt handling: all providers now conditionally set it (preserves caller-supplied values for retention testing) String literal constants: - Add AuditActorTypeUser, AuditActorTypeAdmin constants - Add AuditResourceTypeUser, AuditResourceTypeSession, AuditResourceTypeAdminSession, AuditResourceTypeWebhook, AuditResourceTypeEmailTemplate, AuditResourceTypeToken constants - Replace all inline string literals across 30 files Test improvements: - Migrate audit_logs_test.go to runForEachDB pattern - Add resource_type filter test - Add timestamp range filter test - Add round-trip field preservation test - Use constants throughout all test files
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
ActorType: "admin"with appropriate ResourceType for each operationDepends on: #533 (audit log helper)
Test plan
go build ./...passesmake test-sqlitepasses🤖 Generated with Claude Code