Re: Authorization semantics and candidate pruning in GRAPH_TABLE - Mailing list pgsql-hackers

From Ashutosh Bapat
Subject Re: Authorization semantics and candidate pruning in GRAPH_TABLE
Date
Msg-id CAExHW5vtdCxynq61Q+XgbRv_6betO1KEK9Q7whniZOLOBoUanQ@mail.gmail.com
Whole thread
List pgsql-hackers
Hi Wataru,


On Tue, Sep 8, 2026 at 10:19 AM Wataru Naotsuka
<naotsukawataru@gmail.com> wrote:
>
> Hello pgsql-hackers,
>
> I would like to ask about authorization behavior for unlabeled patterns in Property Graph / GRAPH_TABLE, in
particularwhether the current permission error behavior is an intentional authorization semantic or mainly a
consequenceof the current rewrite implementation. 
>
> As I understand it, a user executing GRAPH_TABLE needs SELECT privileges on the property graph itself, as well as on
theunderlying base relations that are actually referenced. I also understand the motivation for using security-invoker
semantics,in order to avoid unintended privilege escalation through the graph owner's privileges. 
>
> However, unlabeled patterns seem to have an interesting consequence.
>
> My understanding of the current rewrite flow is roughly:
>
> candidate
>    ↓
> does it form a valid path?
>    ├─ no  → does not remain as a Query/RTE
>    └─ yes → generate RTE → permission check
>
> For example, suppose the possible vertex candidates are A, B, and C. The current user has SELECT privilege on A and
C,but not on B. 
>
> If a path containing B is structurally valid and therefore rewritten into an RTE, the entire query appears to fail
withpermission denied, even if that path would never actually return any rows. 
>
> The first thing I would like to clarify is whether the following behavior is intentional:
>
> If any valid path candidate internally generated by unlabeled expansion contains an element for which the current
userlacks the required privilege, the entire query is rejected. 
>
> Is this an intended authorization semantic, or is it primarily a consequence of applying the normal RTE permission
checksto the current rewrite result? 
>
> I would also be interested to know whether SQL/PGQ or the SQL standard provides any requirement or guidance on this
point.
>
> Relation to future candidate pruning
>
> One reason I am interested in clarifying this now is that I think there is room for more static candidate pruning
beforeDFS or during path generation, in order to reduce the combinatorial explosion of possible path candidates. 
>
> Even today, candidates that cannot form a structurally valid path are not retained as final Query/RTEs. In the
future,it may also be possible to eliminate candidates earlier based on information such as available properties or
WHEREpredicates. 
>
> For example, suppose a future optimization reduces:
>
> [A, B(!permitted), C]
>         ↓ static pruning
> [C]
>         ↓
> DFS → Query / RTE
>
> Before such an optimization, B may be materialized as an RTE and cause permission denied. After the optimization, B
maydisappear before RTE generation, and the same query may succeed. 
>
> What I would especially like to avoid is a situation where, for semantically equivalent queries, whether permission
deniedis raised depends on implementation details of the rewrite, such as which candidates happen to be eliminated
beforeRTE generation. 
>
> For that reason, I wonder whether it would be better to establish the authorization boundary explicitly before
introducingmore candidate-pruning optimizations. 
>
> I see two broad possibilities.
>
> 1. Make all-or-error an explicit semantic
>
> [A, B(!permitted), C]
>         ↓ authorization
> permission denied
>
> Privileges would be checked against the semantic candidate set before optimization. If any required element is not
accessible,the query would fail. 
>
> This would preserve the current behavior while making the authorization result independent of later candidate
pruning.
>
> 2. Filter candidates by the current user's privileges first
>
> [A, B(!permitted), C]
>         ↓ authorization-based filtering
> [A, C]
>         ↓ static pruning
> [C]
>         ↓
> DFS → Query / RTE
>
> Personally, I am interested in exploring this direction.
>
> Under this model, GRAPH_TABLE could be viewed as querying the part of the graph visible to the current user. If
authorizationdetermines the candidate set first, then later pruning based on connectivity, properties, WHERE
predicates,or other static information would be less likely to affect authorization behavior. 
>
> This filtering step would also reduce the number of candidates passed to DFS. As a possible future step, I would like
toexplore optimizations such as eliminating an element candidate early when a property referenced by a restrictive
predicateis known not to exist on that element. I am not proposing that optimization in this discussion; my main goal
hereis to clarify the authorization boundary first. 
>
> Of course, visible-subgraph semantics also has trade-offs. Reachability, shortest paths, aggregates, and similar
resultsmay differ depending on which part of the graph is visible to the current user, so such semantics would need to
beclearly defined and documented. 
>
> There are also related questions that would need further discussion, for example:
>
> whether the same visible-subgraph semantics should apply when labels are explicitly specified, or only for unlabeled
expansion;
>
> how column-level SELECT privileges should be handled;
>
> and where exactly such authorization filtering should occur in the rewrite pipeline.
>
> I am not proposing security-definer semantics or using the graph owner's privileges to access underlying tables. I
agreewith the motivation for security-invoker behavior. The question I am interested in is instead at what stage the
setof elements visible to the current user should be determined. 
>
> If the current all-or-error behavior is intentional, I would like to understand the reasoning and would then consider
makingauthorization explicit before candidate pruning. 
>
> If, on the other hand, the current behavior is mainly a consequence of the rewrite implementation and
permission-basedcandidate filtering would be acceptable, I would be interested in exploring that as a first step toward
moregeneral static candidate pruning. 
>
> I would appreciate any thoughts on the intended authorization semantics here, especially regarding SQL/PGQ and what
authorizationboundary would be preferable in view of future rewrite optimizations. 

SQL/PGQ patch has been reverted now, but let me answer your question.
In order to know whether a relation would produce rows or not, it
needs to be read, which needs appropriate permissions. If a relation
can be pruned because the path it contains is incomplete, it is not
converted into an RTE and hence does not undergo permission check
since it will not be read. In case of a join or union we don't
selectively eliminate a query arm because of lack of permissions.
Similar rationale applies to the queries generated by SQL/PGQ.

--
Best Wishes,
Ashutosh Bapat



pgsql-hackers by date:

Previous
From: "Greg Burd"
Date:
Subject: Re: Speed up COPY FROM text/CSV parsing using SIMD
Next
From: Dmitry Dolgov
Date:
Subject: Re: Add ssl_(supported|shared)_groups to sslinfo