drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.44k stars 641 forks source link

[BUG]: RLS Policies not applied with `push` but applied with `migrate` #3504

Open Serlych opened 1 week ago

Serlych commented 1 week ago

Report hasn't been filed before.

What version of drizzle-orm are you using?

0.36.0

What version of drizzle-kit are you using?

0.27.2

Other packages

No response

What is the undesired behavior?

Using drizzle-kit push does not apply the RLS policy SQL statements correctly. However, using drizzle-kit generate and drizzle-kit migrate does apply these policies as expected.

Command Supabase Evidence
After running drizzle-kit push Captura de pantalla 2024-11-06 a la(s) 11 56 23 a m
After running drizzle-kit generate and drizzle-kit migrate Captura de pantalla 2024-11-06 a la(s) 12 09 28 p m

What are the steps to reproduce it?

Minimal reproducible example

package.json

{
  "name": "minimal-reproducible-example",
  "dependencies": {
    "drizzle-kit": "^0.27.2",
    "drizzle-orm": "^0.36.0",
    "pg": "^8.13.1"
  }
}

index.ts

import { sql } from "drizzle-orm";
import { authenticatedRole } from "drizzle-orm/supabase";
import { pgPolicy, pgTable, uuid } from "drizzle-orm/pg-core";

export const table = pgTable(
  "table",
  {
    id: uuid().unique().defaultRandom().primaryKey(),
  },
  (_) => [
    pgPolicy("policy", {
      as: "permissive",
      to: authenticatedRole,
      for: "all",
      using: sql`true`,
      withCheck: sql`true`,
    }),
  ],
);

drizzle.config.ts

import { type Config } from "drizzle-kit";

export default {
  schema: "./src/schema/index.ts",
  dialect: "postgresql",
  out: "./src/migrations",
  strict: true,
  entities: {
    roles: {
      provider: "supabase",
    },
  },
  migrations: {
    prefix: "supabase",
    table: "journal",
    schema: "drizzle",
  },
  dbCredentials: {
    url: HARDCODED_DATABASE_URL,
  },
  casing: "snake_case",
} satisfies Config;

What I've tried to fix it

1. Use the link API.

index.ts

import { sql } from "drizzle-orm";
import { authenticatedRole } from "drizzle-orm/supabase";
import { pgPolicy, pgTable, uuid } from "drizzle-orm/pg-core";

export const table = pgTable("table", {
  id: uuid().unique().defaultRandom().primaryKey(),
}).enableRLS();

export const policy = pgPolicy("policy", {
  as: "permissive",
  to: authenticatedRole,
  for: "all",
  using: sql`true`,
  withCheck: sql`true`,
}).link(table);

2. Use different runtimes:

3. Use a different driver:

package.json

{
  "name": "minimal-reproducible-example",
  "dependencies": {
    "drizzle-kit": "^0.27.2",
    "drizzle-orm": "^0.36.0",
    "postgres": "^3.4.5"
  }
}

4. Remove the entities property in drizzle.config.ts:

drizzle.config.ts

import { type Config } from "drizzle-kit";

export default {
  schema: "./src/schema/index.ts",
  dialect: "postgresql",
  out: "./src/migrations",
  strict: true,
  migrations: {
    prefix: "supabase",
    table: "journal",
    schema: "drizzle",
  },
  dbCredentials: {
    url: HARDCODED_DATABASE_URL,
  },
  casing: "snake_case",
} satisfies Config;

5. Upgrade Postgres version:

What is the desired result?

I expected drizzle-kit push to apply all Row-Level Security (RLS) policies correctly, similar to the behavior of drizzle-kit generate and drizzle-kit migrate. After reviewing the RLS documentation, the drizzle-kit push documentation and the release notes, I found no indications of limitations or differences in how drizzle-kit push handles RLS policies.

Additional info

push output

❯ npx drizzle-kit push
No config path provided, using default 'drizzle.config.ts'
Reading config file '/minimal-reproducible-example/drizzle.config.ts'
Using 'pg' driver for database querying
[✓] Pulling schema from database...
[✓] Changes applied

generate output

❯ npx drizzle-kit generate
(node:69550) ExperimentalWarning: CommonJS module /opt/homebrew/lib/node_modules/npm/node_modules/debug/src/node.js is loading ES Module /opt/homebrew/lib/node_modules/npm/node_modules/supports-color/index.js using require().
Support for loading ES Module in require() is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
No config path provided, using default 'drizzle.config.ts'
Reading config file '/minimal-reproducible-example/drizzle.config.ts'
1 tables
table 1 columns 0 indexes 0 fks

[✓] Your SQL migration file ➜ src/migrations/20241106180834_colossal_turbo.sql 🚀

migrate output

❯ npx drizzle-kit migrate
(node:69740) ExperimentalWarning: CommonJS module /opt/homebrew/lib/node_modules/npm/node_modules/debug/src/node.js is loading ES Module /opt/homebrew/lib/node_modules/npm/node_modules/supports-color/index.js using require().
Support for loading ES Module in require() is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
No config path provided, using default 'drizzle.config.ts'
Reading config file '/minimal-reproducible-example/drizzle.config.ts'
Using 'pg' driver for database querying
abdul-mustapha commented 4 days ago

Can replicate the same issue, was driving me insane thinking I was misunderstanding something

I am also having an issue where I can edit the USING statement in the supabase dashboard