Supabase audit logs: what they record—and what they miss

By Defencecore Research · · Updated

Supabase has several logging surfaces, but they answer different security questions. This guide separates Platform Audit Logs, Auth Audit Logs, the Logs Explorer, and database-level auditing so you can choose the trail you actually need.

Short answer

Supabase Platform Audit Logs record control-plane actions performed by organization members in the dashboard and Platform API. Auth Audit Logs separately record authentication events such as logins, signups, password changes, token refreshes, and logouts.

Operational activity appears in the Logs Explorer, which exposes logs from the API, Auth, Postgres, Storage, Realtime, and Edge Functions. None of those surfaces is a row-level change history for your application tables; tracking who changed a row requires pgAudit or an audit trigger configured before the change occurs.

Four audit and logging surfaces

The names overlap, but the records do not. Start with the question you need answered, then choose the surface that can produce that evidence.

SurfaceRecordsAnswers
Platform Audit LogsDashboard and Platform API actions by organization membersWho changed the project, and when
Auth Audit LogsSignups, logins, password changes, token refreshes, and logoutsWhat happened in a user's authentication lifecycle
Logs ExplorerAPI, auth, Postgres, Edge Function and storage traffic — edge_logs, auth_logs, postgres_logs and the restWhat requests hit the project
Audit trail in the databaseNothing, until you set up pgAudit or triggersWhich rows changed, and how

Platform Audit Logs watch your team, not your application traffic

Supabase Platform Audit Logs automatically record dashboard and Platform API actions by organization members. The record includes the actor, action, target, timestamp, and related metadata. Supabase currently makes this surface available on Team and Enterprise plans.

But it is scoped to the control plane. Traffic that arrives with an API key never touches it. Your application does not appear in it. Neither does a leaked service_role key reading every row of every table, nor a coding agent connected to production, nor an anonymous request that Row Level Security should have filtered and did not. Those are all data-plane events, and the audit log is structurally blind to them.

This matters because the surfaces can tell one story between them. Platform Audit Logs can show a project setting or Edge Function changing on Tuesday; the Logs Explorer can show the resulting application traffic on Wednesday. Nothing in either surface automatically turns those separate records into one investigation.

Auth Audit Logs record the authentication lifecycle

Supabase Auth Audit Logs capture signups, logins, password changes and resets, verification events, token refreshes, and logouts. Supabase stores them externally by default and lets you optionally write them to auth.audit_log_entries for SQL access.

They answer identity questions that Platform Audit Logs do not, but they still do not show which application row a signed-in user later inserted, updated, or deleted. Authentication and data modification are separate events; joining them requires your own application context or database audit design.

How Defencecore spots a hacked or abused Supabase project

Defencecore watches for warning signs in the logs your project already creates. It does not wait for someone to open the dashboard and search manually. New events are checked against security rules, and related events are grouped into one incident when a rule matches.

Here are three examples in simple terms:

Each incident explains what happened, which project resource was involved, and what to check first. It also keeps the matching log lines so you can confirm the finding instead of trusting a black-box score.

There is an important limit: Defencecore can only detect activity that leaves a useful signal in the available Supabase logs. It is a security monitor, not a guarantee that every possible breach will be visible.

Postgres does not record who deleted the rows

This is the assumption that costs people the most time. postgres_logs exists, so it feels reasonable to expect that a destructive statement left a trace in it. By default it did not: successful INSERT, UPDATE, and DELETE statements are not a row-level change history, and Supabase disables Postgres connection logging on new projects until you enable it. When the rows are gone, the missing audit configuration cannot be applied retroactively.

Two ways to fix that, with different costs:

-- Enable pgAudit first, then choose the narrowest useful statement classes.
alter role postgres set pgaudit.log = 'function, write, ddl';

-- API traffic connects through the authenticator role.
alter role authenticator set pgaudit.log = 'write';

-- Apply the settings with a fast reboot, then inspect Postgres Logs.

Note what neither approach gives you on its own: identity. A log line names the Postgres role that ran the statement, which for anything arriving through PostgREST is authenticated or anon, not a person. Tying a change back to an end user means capturing auth.uid() in the audit record yourself — and a statement run with the service_role key has no user to capture, which is the point at which an audit trail stops being able to answer the question at all.

Retention depends on the plan and destination

Supabase documents plan-dependent retention for Platform Audit Logs and the Logs Explorer. For project logs, a log drain can stream Postgres, Auth, Storage, Edge Function, Realtime, and API Gateway logs to an external observability or archival destination. That changes the retention boundary, but it also adds a separate service and usage cost.

Upgrading buys a longer window and a larger bill without changing the shape of the problem — the log retention guide works through why paying to keep routine traffic is the wrong lever, and what to keep instead.

What an audit trail is actually for

An audit log you read after an incident is forensics. It is worth having, and it is the wrong instrument for the job everyone actually wants done, which is finding out on Wednesday rather than in November.

Defencecore reads your Supabase logs continuously, normalizes them, and applies detection rules as events arrive — a spike in RLS denials after a migration, authentication patterns that look like credential stuffing, a read volume that does not match the number of users online. When a rule matches, it opens an incident and attaches the log lines that triggered it. Those stay readable after the originals age out of Supabase, so the evidence outlives the retention window that would otherwise have destroyed it. Access is read-only: it can explain what happened to your database, never cause it.

Evaluating how widely the platform is used? Browse the curated directory of companies using Supabase in production.

For the operational workflow, compare manual Supabase log review with Defencecore.

Frequently asked questions

Does Supabase have audit logs?
Yes. Platform Audit Logs record dashboard and Platform API actions by organization members, while Auth Audit Logs record authentication events such as logins, signups, password changes, token refreshes, and logouts. Neither is a row-level history of INSERT, UPDATE, and DELETE activity in your application tables.
Do Supabase logs show who deleted a row?
Not by default. Postgres does not log the text of ordinary DML statements unless it is configured to, and even then a log line records the statement and the connecting role rather than the end user behind it. Answering 'who deleted this row' requires either pgAudit or an audit table populated by triggers, set up before the deletion happens.
What is the difference between Supabase audit logs and the Logs Explorer?
Platform Audit Logs cover control-plane actions made by organization members. Auth Audit Logs cover authentication events. The Logs Explorer exposes operational logs from the API, Auth, Postgres, Storage, Realtime, and Edge Functions. A dashboard user changing a project setting belongs in Platform Audit Logs; requests reaching the application belong in the Logs Explorer.
How long are Supabase audit logs kept?
Supabase states that Platform Audit Log and Logs Explorer retention depend on your plan. Auth Audit Logs can also be written to auth.audit_log_entries in Postgres. For longer retention, Supabase offers log drains that stream project logs to an external destination; check the current pricing and documentation before choosing a retention design.
Can Defencecore tell me if my Supabase project was hacked?
Defencecore detects warning signs in the logs Supabase already creates. It can flag Row Level Security being turned off, repeated failed sign-ins from one address, and repeated requests blocked by an RLS policy. It opens an incident with the affected table or address, the matching log lines, and a first action to take. No log monitor can prove that every possible attack was seen, especially when the activity was never logged.