Releases: guptaaman678/supabase-grants-lint
Releases · guptaaman678/supabase-grants-lint
Release list
v0.1.2
Patch Changes
- 90e7cca: Find the project from inside
supabase/. Without--dir,check,doctorandexplainrun fromsupabase/orsupabase/migrationsnow use the folder that containssupabase/(its config included) and name it in the summary line, and a folder of.sqlfiles 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
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
Minor Changes
- aa796ab: Add the
--formatreporters forcheck.pretty(the default) groups findings by file with the fix and docs link aligned under each rule.jsonprints{ schemaVersion: 1, tool, summary, findings, notices }, and the summary includes the resolvedsince(value, where it came from, and the detected opt-in migration).sarifwrites SARIF 2.1.0 with one rule descriptor per rule, for GitHub code scanning.githubprints workflow commands, so each finding becomes an annotation on the migration line in a GitHub Actions run.--quietlists error findings only in every format; the summary still counts everything. - 1fd0591: Add the
checkcommand and the CLI contract:--dir,--config,--since, repeatable--schema,--max-warnings,--strict-parse,--quietand--no-color, with--helpper 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 whenNO_COLORis set. The parser loads only for commands that lint. The package root exportslint(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 thesinceyou set. Replay trap: whether the migrations turn automatic grants back on when replayed (GL007), and whethersupabase/config.tomlsets[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 theinitcommand.doctortakes the same--dir,--config,--sinceand--schemaoptions ascheck, 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.explaintakes the same--dir,--config,--sinceand--schemaoptions ascheck. - ce0158d: Add rules GL000 (no-enforcement-baseline), PARSE001 (unparseable-statement) and PARSE002 (dynamic-sql-skipped). GL000 warns once, on the last migration, when no
sinceis set and no opt-in migration is found, so the rules that check new relations did not run; it points toinit --since nextfor 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-parsewill make it an error. PARSE002 reports, as info, eachDOblock that mentions grants, revokes, tables, policies or default privileges, since the replay cannot run it. Whensinceis 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_roleno 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.--helpnow 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,authenticatedorPUBLIC(or a role inclientRoles) 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 inclientRoles) holds no privilege the policy's command needs by the end of the migration (any select, insert, update or delete forALL), 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
serialcolumn that a client role (anon,authenticated, or a role inclientRoles) can insert into but holds neitherusagenorupdateon the column's sequence by the end of the migration (nextval()accepts either), with thegrant usage on sequencethat fixes it. Identity columns and uuid keys need no sequence grant. - 30df3ef: Add rule GL005 (blanket-grant): warns about
grant ... on all tables in schemaoron all sequences in schemafor a checked schema toanon,authenticated,PUBLIC, a role inclientRoles, 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 tablesoron sequencestoanon,authenticated,PUBLIC, a role inclientRoles, or the service role, for the migration role (or the role made current byset 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 privilegesgrants that giveanon,authenticated,PUBLIC, a role inclientRoles, 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, notplatformDefaults. The finding is a warning at the last statement that granted something still in effect, or an error whensincewas 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,authenticatedor a role inclientRolesTRUNCATE, REFERENCES or TRIGGER at the end of that migration, own or throughPUBLIC. The opt-in SQL Supabase announced revokes only select, insert, update and delete, so the oldgrant alldefault leaves these behind; the Data API never needs them, and TRUNCATE and REFERENCES are not subject to row level security. MAINTAIN is checked too whenpostgresMajoris 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 frompublicwhen granted through it). - 924d05f: Add
init, which writesgrants-lint.config.json(with$schemafor editor help) and.github/workflows/grants-lint.yml(runs the GitHub Action on pull requests and pushes tomain).--since nextsetssinceto the latest migration version, socheckenforces only the migrations you add from now on;--since <version>or--since noneset it directly, and without--sinceit is"auto".--no-workflowwrites only the config, and--dirwrites into another project.initnever 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 agrant all, since an explicitgrant allleaves them too. - 0b4d2cd:
--dirnow also accepts the migrations folder itself: when the directory has nosupabase/migrationsbut holds.sqlfiles, those files are the migrations (for examplecheck --dir db/migrations).doctornames the relations that the migrations grant on, revoke on or add policies to but never create (usually tables made in the dashboard), sincecheckcannot 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 nestedfile:dependency of a throwaway root, so a build-time devDependency (the bundler) never installs, andentry: supabase-grants-lint checkfails before it runs. Use the GitHub Action or the CLI directly for now; alanguage: systemhook is planned once the package is published on npm. - c176903: Write the README: quick start with
check,doctorandinit, what breaks on 2026-10-30, the GitHub Action, the rules table and a configuration summar...