Summary
Internal edge functions called from DB triggers/cron jobs via pg_net currently use verify_jwt = false (no authentication). This works but means anyone who discovers the function URL could call it.
Scope
Evaluate all edge functions and database functions for auth posture — not just the ones currently using verify_jwt = false. This should be a comprehensive security audit covering:
- Functions called from DB triggers/cron (currently no auth)
- Functions called from the client (JWT or service_role auth)
- Functions exposed to external webhooks (sms-webhook, gmail-inbound, etc.)
- Database functions with
SECURITY DEFINER that may need tighter access control
Known Functions Using verify_jwt = false
process-notification-push (DB trigger on notifications INSERT)
gmail-watch-renew (daily cron)
check-lead-warnings (cron)
process-lead-scheduled-messages (cron)
sms-webhook, gmail-inbound, call-webhook (external webhooks)
request-access, accept-invitation, validate-invitation (public registration flow)
contact-form-webhook, testflight-webhook
Proposed Solution
Migrate to Supabase Vault for secure secret storage where appropriate:
- Store a dedicated internal API key in Vault
- Retrieve it at runtime in trigger/cron SQL:
SELECT decrypted_secret FROM vault.decrypted_secrets WHERE name = 'internal_api_key'
- Pass as Authorization header in
pg_net calls
- Add auth validation to each internal edge function
- Remove
verify_jwt = false where possible
- For external webhooks, evaluate per-function (e.g., OpenPhone signature verification for sms-webhook)
References
Priority
Low — current approach matches existing project patterns and works. This is a hardening improvement for a future security pass.
Summary
Internal edge functions called from DB triggers/cron jobs via
pg_netcurrently useverify_jwt = false(no authentication). This works but means anyone who discovers the function URL could call it.Scope
Evaluate all edge functions and database functions for auth posture — not just the ones currently using
verify_jwt = false. This should be a comprehensive security audit covering:SECURITY DEFINERthat may need tighter access controlKnown Functions Using
verify_jwt = falseprocess-notification-push(DB trigger on notifications INSERT)gmail-watch-renew(daily cron)check-lead-warnings(cron)process-lead-scheduled-messages(cron)sms-webhook,gmail-inbound,call-webhook(external webhooks)request-access,accept-invitation,validate-invitation(public registration flow)contact-form-webhook,testflight-webhookProposed Solution
Migrate to Supabase Vault for secure secret storage where appropriate:
SELECT decrypted_secret FROM vault.decrypted_secrets WHERE name = 'internal_api_key'pg_netcallsverify_jwt = falsewhere possibleReferences
Priority
Low — current approach matches existing project patterns and works. This is a hardening improvement for a future security pass.