Skip to main content
All tables in Money Tracker use Row Level Security (RLS) to ensure users can only access their own data. This page documents all RLS policies.

User Management

users

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: Users can only read their own user record.
CREATE POLICY "Users can read their own data"
ON users
FOR SELECT
TO authenticated
USING (auth.uid() = id);

OAuth & Gmail

user_oauth_tokens

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: Users can read metadata for their own tokens (but not the encrypted token values).
CREATE POLICY "Users can read their own token metadata"
ON user_oauth_tokens
FOR SELECT
TO authenticated
USING (auth.uid() = user_id);
Policy Type: INSERTRole: authenticatedRule: Authenticated users cannot insert tokens directly. Only backend can modify.
CREATE POLICY "Block user insert to tokens"
ON user_oauth_tokens
FOR INSERT
TO authenticated
WITH CHECK (false);
Policy Type: UPDATERole: authenticatedRule: Authenticated users cannot update tokens. Only backend can modify.
CREATE POLICY "Block user update to tokens"
ON user_oauth_tokens
FOR UPDATE
TO authenticated
USING (false);
Policy Type: DELETERole: authenticatedRule: Authenticated users cannot delete tokens directly. Only backend can modify.
CREATE POLICY "Block user delete to tokens"
ON user_oauth_tokens
FOR DELETE
TO authenticated
USING (false);

gmail_watches

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: Users can only view their own Gmail watches.
CREATE POLICY "Users can read their own watches"
ON gmail_watches
FOR SELECT
TO authenticated
USING (auth.uid() = user_id);

pubsub_subscriptions

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: Users can only view their own Pub/Sub subscriptions.
CREATE POLICY "Users can read their own subscriptions"
ON pubsub_subscriptions
FOR SELECT
TO authenticated
USING (auth.uid() = user_id);

Transactions

transactions

RLS Status: Enabled Realtime: Enabled with full replica identity
Policy Type: SELECTRole: authenticatedRule: Users can only read their own transactions.
CREATE POLICY "transactions_select_own" ON transactions
    FOR SELECT TO authenticated
    USING (auth.uid() = user_id);
Policy Type: INSERTRole: authenticatedRule: Users can only create transactions for themselves.
CREATE POLICY "transactions_insert_own" ON transactions
    FOR INSERT TO authenticated
    WITH CHECK (auth.uid() = user_id);
Policy Type: UPDATERole: authenticatedRule: Users can only update their own transactions.
CREATE POLICY "transactions_update_own" ON transactions
    FOR UPDATE TO authenticated
    USING (auth.uid() = user_id)
    WITH CHECK (auth.uid() = user_id);
Policy Type: DELETERole: authenticatedRule: Users can only delete their own transactions.
CREATE POLICY "transactions_delete_own" ON transactions
    FOR DELETE TO authenticated
    USING (auth.uid() = user_id);
Permissions:
GRANT SELECT ON transactions TO authenticated;
GRANT SELECT ON transactions TO anon;

Processing

seeds

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: Users can view seed jobs for their Gmail accounts.
CREATE POLICY "Users can view their own seeds"
  ON seeds FOR SELECT
  USING (user_id = auth.uid());
Policy Type: INSERTRole: authenticatedRule: Users can create seed jobs for their own accounts.
CREATE POLICY "Users can insert their own seeds"
  ON seeds FOR INSERT
  WITH CHECK (user_id = auth.uid());
Policy Type: UPDATERole: authenticatedRule: Users can update their own seed jobs.
CREATE POLICY "Users can update their own seeds"
  ON seeds FOR UPDATE
  USING (user_id = auth.uid())
  WITH CHECK (user_id = auth.uid());
Policy Type: DELETERole: authenticatedRule: Users can delete their own seed jobs.
CREATE POLICY "Users can delete their own seeds"
  ON seeds FOR DELETE
  USING (user_id = auth.uid());

discarded_emails

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: Users can view discarded emails from their Gmail accounts.
CREATE POLICY "Users can view their own discarded emails"
  ON discarded_emails
  FOR SELECT
  USING (
    user_oauth_token_id IN (
      SELECT id FROM public.user_oauth_tokens 
      WHERE user_id = auth.uid()
    )
  );
Policy Type: INSERTRole: authenticatedRule: Users can insert discarded emails for their own accounts.
CREATE POLICY "Users can insert their own discarded emails"
  ON discarded_emails
  FOR INSERT
  WITH CHECK (
    user_oauth_token_id IN (
      SELECT id FROM public.user_oauth_tokens 
      WHERE user_id = auth.uid()
    )
  );
Policy Type: DELETERole: authenticatedRule: Users can delete their own discarded email records.
CREATE POLICY "Users can delete their own discarded emails"
  ON discarded_emails
  FOR DELETE
  USING (
    user_oauth_token_id IN (
      SELECT id FROM public.user_oauth_tokens 
      WHERE user_id = auth.uid()
    )
  );

Notifications

notification_categories

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: All authenticated users can read notification categories.
CREATE POLICY "notification_categories_select_authenticated"
  ON public.notification_categories
  FOR SELECT
  TO authenticated
  USING (true);

notification_types

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: All authenticated users can read notification types.
CREATE POLICY "notification_types_select_authenticated"
  ON public.notification_types
  FOR SELECT
  TO authenticated
  USING (true);

user_notification_preferences

RLS Status: Enabled
Policy Type: SELECTRole: authenticatedRule: Users can read their own notification preferences.
CREATE POLICY "user_notification_preferences_select_own"
  ON public.user_notification_preferences
  FOR SELECT
  TO authenticated
  USING (user_id = auth.uid());
Policy Type: INSERTRole: authenticatedRule: Users can create their own notification preferences.
CREATE POLICY "user_notification_preferences_insert_own"
  ON public.user_notification_preferences
  FOR INSERT
  TO authenticated
  WITH CHECK (user_id = auth.uid());
Policy Type: UPDATERole: authenticatedRule: Users can update their own notification preferences.
CREATE POLICY "user_notification_preferences_update_own"
  ON public.user_notification_preferences
  FOR UPDATE
  TO authenticated
  USING (user_id = auth.uid())
  WITH CHECK (user_id = auth.uid());
Policy Type: DELETERole: authenticatedRule: Users can delete their own notification preferences.
CREATE POLICY "user_notification_preferences_delete_own"
  ON public.user_notification_preferences
  FOR DELETE
  TO authenticated
  USING (user_id = auth.uid());

notifications

RLS Status: Enabled Realtime: Enabled via supabase_realtime publication
Policy Type: SELECTRole: authenticatedRule: Users can read their own notifications.
CREATE POLICY "notifications_select_own"
  ON public.notifications
  FOR SELECT
  TO authenticated
  USING (user_id = auth.uid());
Policy Type: INSERTRole: authenticatedRule: Users can create notifications for themselves.
CREATE POLICY "notifications_insert_own"
  ON public.notifications
  FOR INSERT
  TO authenticated
  WITH CHECK (user_id = auth.uid());
Policy Type: UPDATERole: authenticatedRule: Users can update their own notifications (e.g., mark as read).
CREATE POLICY "notifications_update_own"
  ON public.notifications
  FOR UPDATE
  TO authenticated
  USING (user_id = auth.uid())
  WITH CHECK (user_id = auth.uid());
Policy Type: DELETERole: authenticatedRule: Users can delete their own notifications.
CREATE POLICY "notifications_delete_own"
  ON public.notifications
  FOR DELETE
  TO authenticated
  USING (user_id = auth.uid());

Security Notes

OAuth tokens are protected with multiple security layers:
  • Encrypted using pgcrypto extension
  • Users can only read metadata, not actual tokens
  • Insert/Update/Delete operations blocked for authenticated users
  • Only backend services can modify tokens
All user-scoped tables use auth.uid() to verify ownership. This ensures that:
  • Users can only access their own data
  • Cross-user data leakage is prevented at the database level
  • No application-level filtering is required
Realtime subscriptions automatically respect RLS policies. Users will only receive real-time updates for data they have access to.

Build docs developers (and LLMs) love