Skip to content

fix(access): warn when the generated grant is only a template - #350

Merged
huyplb merged 3 commits into
mainfrom
fix/comment-only-grants-warn
Sep 3, 2026
Merged

fix(access): warn when the generated grant is only a template#350
huyplb merged 3 commits into
mainfrom
fix/comment-only-grants-warn

Conversation

@huyplb

@huyplb huyplb commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Found testing Oracle by hand: the read-only preset at database scope produced

GRANT CREATE SESSION TO "FOXUSER";

-- Oracle grants object privileges per object. Repeat for each table:
-- GRANT SELECT ON <schema>.<table> TO "FOXUSER";

with no warning at all. Paste and run that and the account can log in and read nothing — the opposite of what "read only" implies, and not obvious from the SQL unless you spot that the second block is commented out.

Why nothing warned

missedPermissionWarning exists for exactly this. It was being silenced: Oracle and Db2 passed the table permissions as the covers argument on a statement that is entirely a comment, so SELECT counted as granted. PostgreSQL's ownership note did the same for ALTER/DROP.

A template cannot grant anything, so none of them claim coverage now.

The advice was also wrong

Handle those through object ownership or an engine-specific privilege.

That is right for the PostgreSQL ownership case and useless for Oracle, where the answer is to narrow the scope. Where the engine has per-object grants and the miss is a table privilege, it now reads:

oracle cannot express read data at this scope — nothing below grants it. Switch the scope to Tables and pick the objects to grant on — oracle has no schema-wide table grant.

PostgreSQL still gets the ownership wording, since "pick tables" would be wrong there.

Verification

4 new tests, including one asserting the Oracle output has exactly one runnable line, and one confirming no warning appears when the grant really is expressible (Tables scope). A/B'd: restoring the false coverage fails the Oracle test.

Gates: 3292 tests, typecheck clean, 0 ESLint errors.

🤖 Generated with Claude Code


Note

Medium Risk
Changes permission SQL generation and warning behavior for Oracle, Db2, and PostgreSQL—areas where incorrect output could mislead operators about what was actually granted.

Overview
Fixes a dangerous gap where comment-only SQL templates were treated as covering table privileges, so presets like “read only” at database scope could show a runnable CREATE SESSION plus commented SELECT lines with no caution. Oracle, Db2 (database scope), and PostgreSQL ownership hints no longer pass covers for those templates, so missedPermissionWarning fires when the requested permission is not actually granted.

missedPermissionWarning now gives actionable remedies: pick tables when the engine has no schema-wide table grant (Oracle), choose a schema when it does (Db2/PostgreSQL at database scope), or ownership wording for non-table misses like PostgreSQL ALTER/DROP.

Db2 schema scope now emits real …IN ON SCHEMA grants (SELECTIN, INSERTIN, etc.) instead of a commented per-table template, with human-readable labels for those keywords in PRIV_VERB. Tests cover Oracle/Db2 warnings, Db2 schema grants/revokes, and deduped EXECUTEIN.

Reviewed by Cursor Bugbot for commit ff57381. Bugbot is set up for automated code reviews on this repo. Configure here.

huyplb and others added 2 commits September 2, 2026 23:47
Reported from a live Oracle test: the read-only preset at database scope
produced

  GRANT CREATE SESSION TO "FOXUSER";
  -- Oracle grants object privileges per object. Repeat for each table:
  -- GRANT SELECT ON <schema>.<table> TO "FOXUSER";

with no warning at all. Pasting that gives the account login and no read
access, which is the opposite of what "read only" implies and is not
visible from the SQL unless you notice the second block is commented out.

The warning built for exactly this case was being silenced. Oracle and
Db2 passed the table permissions as the `covers` argument on a statement
that is entirely a comment, so `missedPermissionWarning` counted SELECT
as granted. PostgreSQL's ownership note did the same for ALTER and DROP.
A template cannot grant anything, so none of them claim coverage now.

The advice was wrong for this case too. "Handle those through object
ownership or an engine-specific privilege" is right for the PostgreSQL
ownership case and useless for Oracle, where the answer is to narrow the
scope. Where the engine has per-object grants and the miss is a table
privilege, the warning now says to switch the scope to Tables and pick
the objects.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reviewing privilege grouping across the dialects turned up a wrong claim
in this repo. `db2.access-sql.ts` said "Db2 has no schema-wide table
grant — SELECTIN-style schema privileges exist only for a few verbs" and
emitted a commented template instead of SQL.

Verified against the Db2 12.1 container: SELECTIN, INSERTIN, UPDATEIN,
DELETEIN, EXECUTEIN, ALTERIN, CREATEIN and DROPIN all grant on a schema
and all record as Y in SYSCAT.SCHEMAAUTH. The generated statement was
then executed as-is and recorded exactly the four privileges asked for.

So schema scope now emits a real grant. Unlike PostgreSQL's ALL TABLES,
Db2's form keeps covering objects created later, which the explanation
says.

The block sits above the empty-table-privileges return, because EXECUTEIN,
ALTERIN and DROPIN have nothing to do with table privileges — with it
below, an execute-only grant at schema scope emitted nothing at all. A
test covers that case.

Database scope keeps the template: there is no schema to name there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fb69433. Configure here.

Comment thread packages/sql/src/modules/access/access-sql-helpers.ts
The remedy text was written when the only engines that missed a table
privilege at a wide scope were ones with no schema-wide grant at all. The
previous commit gave Db2 real SELECTIN-style schema grants, which made
the advice contradict both the SQL and the template's own explanation:
the warning said "db2 has no schema-wide table grant" while the emitter
one scope over produced exactly that grant.

The two situations are different and the message now tells them apart. An
engine with schema-wide grants missing a privilege at *database* scope
needs a schema named, so it says to choose one. Oracle genuinely has
none, so there it still points at Tables.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@huyplb
huyplb merged commit e47b05d into main Sep 3, 2026
12 checks passed
@huyplb
huyplb deleted the fix/comment-only-grants-warn branch September 3, 2026 06:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant