Skip to content

Releases: guptaaman678/supabase-grants-lint

v0.1.2

Choose a tag to compare

@guptaaman678 guptaaman678 released this 29 Sep 04:06
d4ac070

Patch Changes

  • 90e7cca: Find the project from inside supabase/. Without --dir, check, doctor and explain run from supabase/ or supabase/migrations now use the folder that contains supabase/ (its config included) and name it in the summary line, and a folder of .sql files is linted as --dir <that folder> would. The "Migrations directory not found" error now says to run from the project root or pass --dir <project or migrations folder>.

v0.1.1

Choose a tag to compare

@guptaaman678 guptaaman678 released this 28 Sep 05:26
e46a531

Patch Changes

  • b32fa16: The GitHub Action's description is now short enough for the GitHub Marketplace (under 125 characters), and the actions it uses (actions/setup-node, github/codeql-action/upload-sarif) are pinned to full commit SHAs. Releases are now staged on npm by CI through trusted publishing, with provenance, and go live only after a maintainer approves them with 2FA.

v0.1.0

Choose a tag to compare

@guptaaman678 guptaaman678 released this 27 Sep 19:08
2f1b3e4

Minor Changes

  • aa796ab: Add the --format reporters for check. pretty (the default) groups findings by file with the fix and docs link aligned under each rule. json prints { schemaVersion: 1, tool, summary, findings, notices }, and the summary includes the resolved since (value, where it came from, and the detected opt-in migration). sarif writes SARIF 2.1.0 with one rule descriptor per rule, for GitHub code scanning. github prints workflow commands, so each finding becomes an annotation on the migration line in a GitHub Actions run. --quiet lists error findings only in every format; the summary still counts everything.
  • 1fd0591: Add the check command and the CLI contract: --dir, --config, --since, repeatable --schema, --max-warnings, --strict-parse, --quiet and --no-color, with --help per command and examples. Exit codes: 0 no errors and warnings within --max-warnings, 1 findings over the threshold, 2 usage or config error (an unknown flag or command suggests the closest one), 3 internal error or unparseable SQL under --strict-parse. Colour is used only on a terminal and never when NO_COLOR is set. The parser loads only for commands that lint. The package root exports lint(options), which returns the findings, notices and a summary.
  • 2a42d03: Add doctor, a readiness report for 2026-10-30 in four sections. Opt-in status: the opt-in migration it detected, or the since you set. Replay trap: whether the migrations turn automatic grants back on when replayed (GL007), and whether supabase/config.toml sets [api] auto_expose_new_tables = false. History exposure: the relations your migrations create that a database without automatic grants could not reach through the Data API. Next steps: the opt-in SQL, the fixes, and the init command. doctor takes the same --dir, --config, --since and --schema options as check, fits 100 columns, and exits 0 whatever it finds.
  • a83bb51: Add explain <schema.relation>, the grant timeline of one relation: every migration line that created it (with the default privileges it received), granted or revoked on it, renamed, moved or dropped it, or created, altered, renamed or dropped one of its policies, followed by its final effective privileges per role and its policies. A renamed relation is found by its old or its new name. A name no migration mentions exits 2 and lists the closest names. explain takes the same --dir, --config, --since and --schema options as check.
  • ce0158d: Add rules GL000 (no-enforcement-baseline), PARSE001 (unparseable-statement) and PARSE002 (dynamic-sql-skipped). GL000 warns once, on the last migration, when no since is set and no opt-in migration is found, so the rules that check new relations did not run; it points to init --since next for projects opted in from the dashboard or by the 2026-10-30 change. PARSE001 reports, as info, each statement the parser could not read (it is skipped and the replay continues) and each migration file without a version prefix; --strict-parse will make it an error. PARSE002 reports, as info, each DO block that mentions grants, revokes, tables, policies or default privileges, since the replay cannot run it. When since is set, a notice now records the platform revoke assumed before the first checked migration, and grants of privileges that do not apply to the object are reported as notices.
  • 0daebfa: Add rule GL001 (missing-service-role-grant): flags a table or view created in an enforced migration that gives service_role no select, insert, update or delete by the end of that migration, with the grant to add. Truncate, references, trigger and maintain do not count, so GL001 also fires after the platform revoke, which leaves those behind. --help now lists the implemented rules.
  • 66842dc: Add rule GL002 (unreachable-new-relation): flags a table created in an enforced migration that has RLS policies for anon, authenticated or PUBLIC (or a role in clientRoles) while that role holds no select, insert, update or delete privilege on it by the end of the migration, with the grant covering the policies' commands.
  • e95ecb1: Add rule GL003 (dead-policy): flags an RLS policy created or altered in an enforced migration whose role (anon, authenticated, PUBLIC, or a role in clientRoles) holds no privilege the policy's command needs by the end of the migration (any select, insert, update or delete for ALL), with the grant that makes it apply. A policy on a table no migration creates is reported as a warning.
  • 566c2bb: Add rule GL004 (serial-sequence-usage): flags a table created in an enforced migration with a serial column that a client role (anon, authenticated, or a role in clientRoles) can insert into but holds neither usage nor update on the column's sequence by the end of the migration (nextval() accepts either), with the grant usage on sequence that fixes it. Identity columns and uuid keys need no sequence grant.
  • 30df3ef: Add rule GL005 (blanket-grant): warns about grant ... on all tables in schema or on all sequences in schema for a checked schema to anon, authenticated, PUBLIC, a role in clientRoles, or the service role in an enforced migration. Such a grant re-grants every object that exists at that point, including ones narrowed on purpose, and none created later. The suggested fix grants the same privileges on the objects the migration created, by name.
  • 38e356b: Add rule GL006 (default-privileges-regrant): reports alter default privileges ... grant ... on tables or on sequences to anon, authenticated, PUBLIC, a role in clientRoles, or the service role, for the migration role (or the role made current by set role), in a checked schema or in every schema, in an enforced migration. Such a statement turns automatic grants back on for every object created afterwards. Remove it and grant on each new relation by name.
  • 2dac1d6: Add rule GL007 (replay-reenables-defaults): reports when the migrations themselves, replayed from the first file to the last, leave alter default privileges grants that give anon, authenticated, PUBLIC, a role in clientRoles, or the service role privileges on new tables or sequences the migration role creates in a checked schema. Only the privileges Supabase's published opt-in revoke removes count (select, insert, update, delete on tables; usage, select on sequences), so a project that opts in with exactly that SQL is not reported for the TRUNCATE, REFERENCES, TRIGGER or sequence UPDATE defaults it keeps (GL008 reports those per relation). A replay (supabase db reset, a preview branch) then grants new relations what production, with automatic grants off, does not. Only statements in the files count, not platformDefaults. The finding is a warning at the last statement that granted something still in effect, or an error when since was auto-detected and that statement comes after the opt-in migration. The fix revokes the defaults in a new migration.
  • 5d8c457: Add rule GL008 (leftover-privileges): warns when a table or view created in a checked migration still gives anon, authenticated or a role in clientRoles TRUNCATE, REFERENCES or TRIGGER at the end of that migration, own or through PUBLIC. The opt-in SQL Supabase announced revokes only select, insert, update and delete, so the old grant all default leaves these behind; the Data API never needs them, and TRUNCATE and REFERENCES are not subject to row level security. MAINTAIN is checked too when postgresMajor is 17 or later, since it does not exist before Postgres 17. One finding per relation; the fix revokes them from the roles that hold them (and from public when granted through it).
  • 924d05f: Add init, which writes grants-lint.config.json (with $schema for editor help) and .github/workflows/grants-lint.yml (runs the GitHub Action on pull requests and pushes to main). --since next sets since to the latest migration version, so check enforces only the migrations you add from now on; --since <version> or --since none set it directly, and without --since it is "auto". --no-workflow writes only the config, and --dir writes into another project. init never overwrites a file: if one exists it writes nothing and exits 2, unless you pass --force.

Patch Changes

  • 8f1826c: Clearer messages for two findings seen on real projects. GL003's warning for a policy on a relation the replay has not seen now names the later migration that creates it, when there is one: that file sorts after the policy, so replaying the migrations (supabase db reset, a preview branch) fails at the policy. GL008 now says the leftover privileges come from the default privileges or a grant all, since an explicit grant all leaves them too.
  • 0b4d2cd: --dir now also accepts the migrations folder itself: when the directory has no supabase/migrations but holds .sql files, those files are the migrations (for example check --dir db/migrations). doctor names the relations that the migrations grant on, revoke on or add policies to but never create (usually tables made in the dashboard), since check cannot see them, and an opt-in migration with nothing after it now reads "No migrations after it yet; check will enforce every new one".
  • 7a21c26: The pre-commit hook (.pre-commit-hooks.yaml) is not included in this release: pre-commit's node-language installer builds the hook repo as a nested file: dependency of a throwaway root, so a build-time devDependency (the bundler) never installs, and entry: supabase-grants-lint check fails before it runs. Use the GitHub Action or the CLI directly for now; a language: system hook is planned once the package is published on npm.
  • c176903: Write the README: quick start with check, doctor and init, what breaks on 2026-10-30, the GitHub Action, the rules table and a configuration summar...
Read more