Skip to content

feat: instrument admin operations with audit logging#534

Merged
lakhansamani merged 3 commits intofeat/audit-logfrom
feat/audit-log-admin-instrumentation
Apr 3, 2026
Merged

feat: instrument admin operations with audit logging#534
lakhansamani merged 3 commits intofeat/audit-logfrom
feat/audit-log-admin-instrumentation

Conversation

@lakhansamani
Copy link
Copy Markdown
Contributor

Summary

  • Instrument all 13 admin GraphQL mutations with audit events
  • Covers: admin login/logout, user CRUD (delete, update, enable/revoke access, invite), webhook CRUD, email template CRUD
  • Uses ActorType: "admin" with appropriate ResourceType for each operation

Depends on: #533 (audit log helper)

Test plan

  • go build ./... passes
  • make test-sqlite passes
  • Perform admin operations and verify audit entries in database

🤖 Generated with Claude Code

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
- 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 lakhansamani merged commit b5e2168 into feat/audit-log Apr 3, 2026
@lakhansamani lakhansamani deleted the feat/audit-log-admin-instrumentation branch April 3, 2026 06:56
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
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.

1 participant