Sample Header Ad - 728x90

Why can a SELECT query produce a "permission denied for schema X" error when permission IS granted for that schema?

0 votes
0 answers
39 views
I have spent a couple hours digging into documentation, online blogs, and the particular permission settings for this DB. My best lead is https://stackoverflow.com/a/28503453/5419599 (more on that later). First, the error message from the Postgres error log, lightly redacted: > my_app_user@my_db::ERROR: permission denied for schema organization at character 417 \dn organization shows, among other things, that the owner is postgres and the permission string my_app_user=U/postgres. The query being run (which does appear in the log) is extremely complicated because it's generated under the hood by some typescript library and has a lot of __local_0__ and __local_3__ aliases, etc. And a lot of calls to to_json and json_build_object and json_build_object. But fundamentally it's just a SELECT query. Here is a simplified version to ignore some of the complexity but keep in the references that may be relevant:
select
  ... ,
  to_json(
    select
      json_build_object(
        ...
      ) as object
    from "organization"."organization" as __local_1__
    where ...
  ) as "@redactedAlias1",
  to_json(
    with __local_2__ as (
      select ...
      from "redacted_schema_name"."custom_function_2"(__local_0__) as __local_3__
      where (TRUE) and (TRUE)
    ), ...
    select
      ...    
  ) as "@redactedAlias2",
  to_json(
    with __local_5__ as (
      select ...
      from "redacted_schema_name"."custom_function_3"(__local_0__) as __local_6__
      where ...
    ), ...
    select ...
  ) as "@redactedAlias3"
from "redacted_schema_name"."custom_function_1"() as __local_0__
where (not (__local_0__ is null)) and (TRUE) and (TRUE)
(Character 417 seems to align with where "organization"."organization" appears.) The custom functions are all SQL functions with "invoker" security (the default). The only possibility I currently know of for where this error might be coming from, is the Stack Overflow answer I linked, which states: > There is a foreign key in a table referring to a table in the schema in question, to which the table owner role does not have access granted. Foreign key checks are done with the permissions of the role that owns the table, not the role performing the query. > > The query is actually doing the internal foreign key check. The organization.organization table in my case does have an awful lot of foreign keys which reference it. However, the table and the schema are both owned by the postgres user, and the postgres user also owns all the other schemas and tables which have references to organization.organization. (Note, the postgres user is NOT the DB superuser but for most purposes might as well be.) I was trying to dig up documentation to confirm the above linked answer, i.e. to confirm what permissions are used when checking foreign key constraints and when this check is done, and I was unable to find any. What could be causing this schema permission error? And, if foreign key constraints could indeed be relevant here, where is the documentation about how they are checked or how table owner permissions relate to foreign key constraint checking?
Asked by Wildcard (587 rep)
Jun 4, 2025, 03:23 AM