Skip to content

feat: instrument OAuth/HTTP handlers with audit logging#535

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

feat: instrument OAuth/HTTP handlers with audit logging#535
lakhansamani merged 4 commits intofeat/audit-logfrom
feat/audit-log-http-instrumentation

Conversation

@lakhansamani
Copy link
Copy Markdown
Contributor

Summary

  • Create logAuditEvent() helper for httpProvider (same safe goroutine pattern as graphql helper)
  • Instrument OAuth callback: AuditOAuthCallbackSuccessEvent with provider metadata
  • Instrument token endpoint: AuditTokenIssuedEvent / AuditTokenRefreshedEvent by grant type
  • Instrument token revocation: AuditTokenRevokedEvent after session deletion
  • Instrument HTTP logout: AuditSessionTerminatedEvent after session cleanup

Depends on: #534 (admin instrumentation)

Test plan

  • go build ./... passes
  • make test-sqlite passes
  • Perform OAuth login, token refresh, token revoke, and verify audit entries

🤖 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
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
@lakhansamani lakhansamani force-pushed the feat/audit-log-http-instrumentation branch from 248f78c to a6c1a34 Compare April 3, 2026 06:39
@lakhansamani lakhansamani merged commit b6d5198 into feat/audit-log Apr 3, 2026
@lakhansamani lakhansamani deleted the feat/audit-log-http-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