Skip to main content

Policy

Valid Use Cases

Webhook Processing

  • Purpose: Validate external webhooks
  • Functions: checkout-stripe-webhook, sendgrid-webhook
  • Reason: No user context available

User Creation

  • Purpose: Create initial user records
  • Functions: patient-signup
  • Reason: User has no permissions yet

Cross-User Operations

  • Purpose: Send notifications across users
  • Functions: prescription-notifications
  • Reason: Must access multiple user records

Authentication Management

  • Purpose: Manage auth operations
  • Functions: auth-operations
  • Reason: Password resets, invitations

Payment Processing

  • Purpose: Process payments from webhooks
  • Functions: checkout-submit-order
  • Reason: Complex multi-table operations

Mobile Sync

  • Purpose: Sync data for mobile app
  • Functions: mobile-application-patient-sync
  • Reason: Cross-table data access

Security Requirements

Service Key Functions

  • Document why service key is required
  • Minimize data access scope
  • Add audit logging for sensitive operations

Anon Key Functions

  • Always validate JWT tokens
  • Use RLS policies for data access
  • Add comments about RLS requirements

Implementation

Refactoring Checklist

  1. Check if function only accesses user’s own data
  2. Verify RLS policies support the access pattern
  3. Replace service key with anon key + auth header
  4. Test all operations still work
  5. Deploy updated function

Code Pattern

// Create client with user auth
const supabase = createClient(
  Deno.env.get('SUPABASE_URL'),
  Deno.env.get('SUPABASE_ANON_KEY'),
  {
    global: {
      headers: {
        Authorization: authHeader
      }
    }
  }
);

// Verify user
const { data: { user }, error } = await supabase.auth.getUser();
if (error || !user) {
  return new Response(JSON.stringify({
    error: 'Invalid authentication'
  }), {
    status: 401
  });
}
RLS Required: Functions using anon key require proper RLS policies on all accessed tables