[codex] Add actor attribution to audit logs#2462
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
🔗 Linked repositories identifiedCodeRabbit considers these linked repositories for cross-repo context during reviews:
📝 WalkthroughWalkthroughAdds actor attribution fields across audit-log types, parsing, webhooks, tests, and frontend display. It also adds organization tombstone type coverage, seed reset handling, audit snapshot assertions, localized actor labels, and a workflow checkout-depth update. ChangesAudit Log Actor Attribution
Estimated code review effort: 3 (Moderate) | ~25 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant AuditLog as Audit log
participant Webhook as buildWebhookPayload
participant Table as AuditLogTable.vue
participant Modal as Details modal
AuditLog->>Webhook: Provide actor metadata
Webhook->>Webhook: Build actor-attributed payload
AuditLog->>Table: Provide actor fields
Table->>Table: Resolve and format actor
Table->>Modal: Render source details
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
Merging this PR will improve performance by 61.92%
Performance Changes
Tip Curious why this is faster? Comment Comparing Footnotes
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c26343e090
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 478246fcda
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8f2effed3d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/tables/AuditLogTable.vue`:
- Around line 253-255: The getActorUserEmail helper currently returns
actor_user_email or user?.email unconditionally; change
getActorUserEmail(ExtendedAuditLog) so it only returns those values when the
audit item represents a user actor (e.g., item.actor_type === 'user'), otherwise
return null; likewise update places that fallback to actor_user_id / user_id
(calls/usages of getActorUserEmail and any inline fallbacks) to only use those
user-specific fields when actor_type === 'user' to prevent showing user
emails/IDs for non-user actors (API key/system).
In `@supabase/migrations/20260608160711_audit_log_actor_attribution.sql`:
- Around line 358-500: The SECURITY DEFINER function
public.delete_accounts_marked_for_deletion() is currently executable by any
role; revoke public execute and explicitly grant EXECUTE only to trusted
roles/groups (e.g., your admin role(s)) to prevent privilege escalation. Add
statements after the function definition that REVOKE EXECUTE ON FUNCTION
public.delete_accounts_marked_for_deletion() FROM PUBLIC; and then GRANT EXECUTE
ON FUNCTION public.delete_accounts_marked_for_deletion() TO <trusted_role1>[,
<trusted_role2>] (replace with your actual admin/trusted role names), ensuring
the function remains owned by postgres.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 68f48908-b20b-4600-ad4e-1b872de3c325
📒 Files selected for processing (11)
messages/en.jsonsrc/components/tables/AuditLogTable.vuesrc/types/supabase.types.tssupabase/functions/_backend/public/organization/audit.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/_backend/utils/webhook.tssupabase/migrations/20260608160711_audit_log_actor_attribution.sqlsupabase/seed.sqlsupabase/tests/29_test_delete_accounts_marked_for_deletion.sqlsupabase/tests/40_test_audit_log_apikey.sqltests/audit-logs.test.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
RobinWitch
left a comment
There was a problem hiding this comment.
audit_log_trigger() now resolves the actor by looking at get_apikey_header() before checking auth.uid(). That changes live JWT requests whenever the client also sends capgkey: the existing 31_test_get_apikey_header.sql case documents that get_apikey_header() returns the capgkey even when Authorization: Bearer ... is present, so lines 215-228 classify the mutation as actor_type = 'apikey' and skip the user branch at lines 231-236.
That means a normal Supabase/PostgREST write that succeeds under the JWT/RLS identity on orgs, apps, channels, app_versions, or org_users can be audited as if it was performed by whichever unexpired API key happened to be in the headers. In particular, a read-only or otherwise unrelated key can appear to have performed the write even though authorization came from the JWT user. The old get_identity('{read,upload,write,all}') path returned auth.uid() first, so actor attribution should preserve that precedence or otherwise only treat the key as the actor when it is the credential that authorized the operation.
|
Addressed the outstanding review feedback in 6eefb7b: legacy actor rows are now marked unknown, authenticated users take precedence over a co-present API key, actor emails are limited to user actors, and the account-deletion function is service-role-only with a privilege regression test. |
There was a problem hiding this comment.
Stale comment
Risk: high. Not approving: Cursor Bugbot skipped on this sync and reported one unresolved issue (org delete webhooks), and this migration/auth/audit change exceeds the low-risk approval threshold. RobinWitch and WcaleNieWolny are already assigned for human review.
Sent by Cursor Approval Agent: Pull Request Approver External
|
Addressed the org-delete webhook finding in f3ab6ea. The audit row is retained, but the trigger now intentionally skips enqueueing the undeliverable org DELETE event because that transaction has already cascaded the organization webhooks away. |
|
Fixed the Cloudflare shard failure in babadfe: the stale-org retry fixture now makes its unique (name, created_by) key dynamic as well as its UUID and email. Local typecheck passes; restarting the full CI/review loop. |
There was a problem hiding this comment.
Risk: high. Not approving: Cursor Bugbot skipped on this sync (usage limit reached), so the latest commit lacks a clean automated review, and this migration/auth/audit change exceeds the low-risk approval threshold. RobinWitch and WcaleNieWolny are already assigned for human review.
Sent by Cursor Approval Agent: Pull Request Approver External
babadfe to
d968f8b
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_3535ca7f-5aba-4eab-9883-d1541568a6e7) |
There was a problem hiding this comment.
Risk: high. Not approving: Cursor Bugbot skipped on this sync (usage limit reached), so the latest commit lacks a clean automated review, and this migration/auth/audit change exceeds the low-risk approval threshold. RobinWitch and WcaleNieWolny are already assigned for human review.
Sent by Cursor Approval Agent: Pull Request Approver External
|
|
@codspeedbot explain the regression on /updates manifest response with metadata |
Looked into the CodSpeed data for What the data showsComparing the PR head (
Why the small shift appearsThe base and head runs executed on different CI hardware:
This benchmark runs in Simulation mode, which estimates CPU cycles against a simulated cache model derived from the physical CPU. When the underlying CPU/toolchain changes, the estimate can drift on identical source code. The drift here is concentrated in the instruction-execution component (~54.3 µs → ~58.0 µs), which is exactly the pattern you'd expect from a runner change rather than a real code difference. More on this: https://codspeed.io/docs/instruments/cpu/regression-causes#ci-runner-variability Is this PR responsible?Very unlikely. This PR changes audit-log actor attribution (SQL triggers/migration, webhook payload fields, Supabase types, and the audit-log UI). None of that is on the Bottom line: no action needed for this benchmark — the difference is attributable to the base/head runs landing on different CPUs, and CodSpeed correctly classifies it as unchanged. If you'd like a clean apples-to-apples confirmation, re-running the base and head on the same runner type would remove the environment difference entirely. Summary
Was this response helpful? React with 👍 or 👎 to help us improve CodSpeedBot. |





Summary (AI generated)
Motivation (AI generated)
Audit logs previously only stored a user id, which made it hard to distinguish direct user actions from API key actions or automated backend actions. The old foreign keys could also erase or mutate attribution when dependent resources were deleted.
Business Impact (AI generated)
This improves incident investigation and customer support by making audit trails clearer and more durable. Teams can identify whether an action came from a user, an API key id/name, or automation without exposing API key secrets.
Test Plan (AI generated)
bun lintbun typecheckbun run supabase:with-env -- bunx vitest run tests/audit-logs.test.tsbun run supabase:with-env -- bunx vitest run tests/audit-logs.test.ts tests/webhook-delivery-security.unit.test.ts tests/webhook-delivery-redirect.unit.test.ts tests/webhook-queue-processing.test.tsbun run supabase:with-env -- bunx vitest run tests/organization-api.test.tsbun run supabase:with-env -- bunx vitest run tests/chart-refresh-rpc.test.tsbun run supabase:with-env -- bunx vitest run tests/webhook-signature.test.tsbun run supabase:with-env -- bunx vitest run tests/bundle.test.tsbun test:allwas run twice locally; each run had one unrelated parallel-suite failure, and each failed file passed when rerun alone.Generated with AI
Summary by CodeRabbit
New Features
Bug Fixes
Note
High Risk
Touches audit triggers, org lifecycle, webhook dispatch, and account deletion—security-sensitive paths with broad behavioral changes; migration alters constraints and production audit semantics.
Overview
Audit logs now record who performed an action via snapshot fields (
actor_type, user email/id, API key id/name) instead of relying only onuser_id. The audit log UI replaces the email column with an Actor column and expands the details modal with source, API key, and user email.A large migration drops
audit_logsforeign keys tousersandorgsso retained rows keep attribution after deletes, addsorg_id_tombstonesand triggers to block org UUID reuse, and rewritesaudit_log_triggerto classify JWT users vs write-capable API keys vs system, suppress noisy stats/counter updates, and skip orphaned webhooks during org deletion. Webhook payloads and the organization audit API expose the new actor fields; generated Supabase types are updated.Tests and CI: integration tests assert actor attribution and tombstone behavior;
test:cliand Vitest hook timeouts are raised for CI stability; workflow checkout uses full history for path filters on long-lived branches.Reviewed by Cursor Bugbot for commit d968f8b. Bugbot is set up for automated code reviews on this repo. Configure here.