block / block/pg-sprite

preflight: CheckTable/LookupTargetFacts misreport privilege-blocked targets

Open
#61 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
7
Forks
1
Avg merge
18h 2m
Merged PRs (30d)
74

Description

`CheckTable` and `LookupTargetFacts` resolve the target with `to_regclass`, whose behavior when the connected role lacks schema `USAGE` produces two misleading outcomes instead of an actionable refusal:

- **Qualified name, no `USAGE` on the schema:** `to_regclass` raises `insufficient_privilege` (SQLSTATE 42501), which surfaces as a raw wrapped permission-denied error rather than a typed refusal naming the missing `GRANT`.
- **Unqualified name:** search_path resolution silently skips schemas the role cannot use, so `to_regclass` returns `NULL` and the check reports `ErrTableNotFound` for a table that exists — the operator is told the table is missing when the real problem is a missing `GRANT USAGE`.

The engine-role access check already handles this correctly: `gatherAccessFacts` in `pkg/preflight/privileges.go` catches SQLSTATE 42501 and routes both it and the `NULL`-resolution case through `unresolvedTargetCause`, which separates "does not exist" from "not visible to this role". `CheckTable` and `LookupTargetFacts` in `pkg/preflight/preflight.go` lack the same handling.

**Proposed fix:** mirror the `privileges.go` handling in both functions — catch SQLSTATE 42501 and route through `unresolvedTargetCause` (or an equivalent typed cause), so a privilege-blocked target refuses with the missing grant instead of a raw error or a false not-found. Integration coverage per the test methodology: a role without schema `USAGE`, exercising both the qualified and unqualified paths.

---
*This issue was drafted by Kiran's (@Kiran01bm) coding agent (Amp / Claude Opus 4.5) from a review finding on #60.*

Contributor guide

Open the contributing guide

Research direction

Start in pkg/preflight/preflight.go at CheckTable and LookupTargetFacts, then compare their target-resolution handling with gatherAccessFacts and unresolvedTargetCause in pkg/preflight/privileges.go. Follow the existing integration test methodology with a role lacking schema USAGE, covering qualified and unqualified names. Done means both paths distinguish a missing grant from a nonexistent table and return the typed refusal.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, postgresql
Domain
databases, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.