Revoking access to pg_net objects has no effect: no privileges could be revoked
Last edited: 10/14/2026
当你以 postgres 角色在 net 架构或其对象上运行 revoke 时,语句会完成,但访问权限保持不变。Postgres 会打印一个警告而不是错误:
🌐 When you run revoke on the net schema or its objects as the postgres role, the statement completes but access stays the same. Postgres prints a warning instead of an error:
WARNING: no privileges could be revoked for "net"http_request_queue、_http_response 和 net.http_* 函数都会出现相同的警告。在这些对象上运行 grant 会打印出 no privileges were granted。SQL 编辑器不会显示警告,所以在那里看起来语句是成功的。
🌐 The same warning appears for http_request_queue, _http_response, and the net.http_* functions. A grant on these objects prints no privileges were granted. The SQL Editor doesn't display warnings, so the statement looks successful there.
查看哪些角色有访问权限 #
🌐 Check which roles have access
要列出 net 模式及其表的权限,以及授予每个权限的角色,请在 SQL 编辑器 中运行以下命令:
🌐 To list the privileges on the net schema and its tables, and the role that granted each one, run the following in the SQL Editor:
select 'schema net' as object, case acl.grantee when 0 then 'PUBLIC' else acl.grantee::regrole::text end as grantee, acl.grantor::regrole as grantor, acl.privilege_typefrom pg_namespace ncross join lateral aclexplode(n.nspacl) as aclwhere n.nspname = 'net'union allselect c.relname, case acl.grantee when 0 then 'PUBLIC' else acl.grantee::regrole::text end, acl.grantor::regrole, acl.privilege_typefrom pg_class ccross join lateral aclexplode(c.relacl) as aclwhere c.relnamespace = 'net'::regnamespaceorder by 1, 2, 4;每一行的授予者都是 supabase_admin。要查看某个角色可以做什么,请替换 my_role 然后运行:
🌐 Every row has supabase_admin as the grantor. To check what one role can do, replace my_role and run:
select has_schema_privilege('my_role', 'net', 'usage') as schema_usage, has_table_privilege('my_role', 'net.http_request_queue', 'select') as read_queue, has_function_privilege( 'my_role', 'net.http_post(text, jsonb, jsonb, jsonb, integer)', 'execute' ) as call_http_post;为什么撤销没有效果 #
🌐 Why the revoke has no effect
Supabase 会以 supabase_admin 角色创建 pg_net 扩展,所以 supabase_admin 拥有 net 模式及其中的所有内容。在 Postgres 中,角色只能撤销它自己授予的权限。更多信息,请参阅 Postgres 关于 REVOKE 的文档。
🌐 Supabase creates the pg_net extension as the supabase_admin role, so supabase_admin owns the net schema and everything in it. In Postgres, a role can revoke only the privileges that it granted. For more information, see the Postgres documentation on REVOKE.
该扩展授予 usage 在模式上的权限以及对其表和序列的所有权限给 PUBLIC。在大多数项目中,其函数也可以由 PUBLIC 执行,这是 Postgres 函数的默认设置。对于那些不能执行的项目,请参见 哪些角色可以使用 pg_net。当创建扩展时,Supabase 还会将 usage 在 net 上授予 postgres、anon、authenticated 和 service_role。
🌐 The extension grants usage on the schema and all privileges on its tables and sequences to PUBLIC. On most projects, its functions are also executable by PUBLIC, which is the Postgres default for functions. For the projects where they aren't, see Which roles can use pg_net. When the extension is created, Supabase also grants usage on net to postgres, anon, authenticated, and service_role.
postgres 角色没有做出这些授权,所以它的 revoke 找不到要移除的内容。它持有的权限没有授予选项,所以它对另一个角色的 grant 也不起作用,Postgres 会报 no privileges were granted。
🌐 The postgres role made none of these grants, so its revoke finds nothing to remove. It holds the privileges without the grant option, so its grant to another role does nothing either, and Postgres reports no privileges were granted.
对 PUBLIC 的授权适用于每个角色,包括你以后创建的角色。Postgres 没有办法从 PUBLIC 授权中排除单个角色。
🌐 A grant to PUBLIC applies to every role, including roles you create later. Postgres has no way to exclude a single role from a PUBLIC grant.
哪些角色可以使用 pg_net #
🌐 Which roles can use pg_net
下表显示了每种角色如何达到 net 架构。
🌐 The following table shows how each kind of role can reach the net schema.
| 角色 | 能使用 pg_net | 原因 |
|---|---|---|
anon、authenticated、service_role | 不行,默认情况下 | 这些角色不能直接连接数据库,而且 Data API 默认不提供 net。 |
postgres 以及你用 login 创建的任何角色 | 可以 | 该角色可以读取并修改 net.http_request_queue 和 net._http_response 中的行。工作线程会发送队列中的每一行。 |
在一些项目中,只有 postgres、anon、authenticated、service_role 和 supabase_functions_admin 可以调用 net.http_get 和 net.http_post。至于会从 PUBLIC 撤销 execute 的事件,请参见 默认权限应用时。你创建的角色仍然可以向队列中添加行,然后由工作者发送它们。要检查某个角色,运行 has_function_privilege 查询 来查看哪些角色有权限。
🌐 On some projects, only postgres, anon, authenticated, service_role, and supabase_functions_admin can call net.http_get and net.http_post. For the events that revoke execute from PUBLIC, see When the default grants are applied. A role you create can still add rows to the queue, and the worker sends them. To check a role, run the has_function_privilege query from Check which roles have access.
net.http_request_queue 中的一行保存请求的 URL、头信息和主体,直到 pg_net 工作线程发送它。要查看排队的请求暴露了什么,请参见 Database roles can read request headers queued by pg_net。
🌐 A row in net.http_request_queue holds the request's URL, headers, and body until the pg_net worker sends it. To check what a queued request exposes, see Database roles can read request headers queued by pg_net.
限制你项目的 pg_net 访问 #
🌐 Limit pg_net access on your project
Supabase 不支持为单个项目更改 pg_net 对象的权限,所以把默认权限当作平台限制吧。
🌐 Supabase doesn't support changing the grants on pg_net objects for individual projects, so treat the default grants as a platform constraint.
移除 net 表上的 PUBLIC 授权会导致 pg_net 出问题,因为 postgres 角色只能通过这些表访问它们。没有这些授权,作为 postgres 调用的请求函数会报 permission denied for table http_request_queue 错误,这也会导致调用 pg_net 的 pg_cron 任务失败。
🌐 Removing the PUBLIC grants on the net tables breaks pg_net, because the postgres role reaches those tables only through them. Without the grants, a request function called as postgres fails with permission denied for table http_request_queue, which also breaks pg_cron jobs that call pg_net.
为了减少 pg_net 暴露的内容:
🌐 To reduce what pg_net exposes:
- 只给你信任能从数据库发送 HTTP 请求的服务角色使用
login属性。 - 把你在请求头中发送的任何凭证当作每个能连接到你数据库的角色都能读取的内容。
- 在你的API 设置中,不要把
net放到公开的 schema 里。如果你暴露了它,anon和authenticated可以通过PUBLIC授权读取net.http_request_queue,包括排队的凭证。 - 如果你的项目没用 pg_net,就删掉这个扩展。删掉它会移除
net模式和所有的权限。
删除 pg_net 会清除未发送的请求和存储的响应,并停止通过 pg_net 发送请求的数据库 Webhook。在删除之前,先确认 net.http_request_queue 是空的,并且你的项目没有数据库 Webhook。
🌐 Dropping pg_net deletes unsent requests and stored responses, and stops Database Webhooks, which send their requests through pg_net. Before you drop it, check that net.http_request_queue is empty and that your project has no Database Webhooks.
要删除扩展名,运行:
🌐 To drop the extension, run:
drop extension pg_net;当默认授权被应用时 #
🌐 When the default grants are applied
删除并重新创建扩展不会移除权限,因为 create extension pg_net 会再次应用所有权限。还有另外两个事件会再次将 usage 授予 net 上的 anon、authenticated 和 service_role:
🌐 Dropping and re-creating the extension doesn't remove the grants, because create extension pg_net applies all of them again. Two other events grant usage on net to anon, authenticated, and service_role again:
- 一次重大版的 Postgres 升级。
- 正在开启数据库网络钩子。
一次主要的 Postgres 版本升级也会撤销 PUBLIC 在 net.http_get 和 net.http_post 上的 execute 权限,并将其授予 postgres、anon、authenticated、service_role 和 supabase_functions_admin。当项目启用 pg_net 0.11 或更早版本时,也会发生同样的情况。
🌐 A major Postgres version upgrade also revokes execute on net.http_get and net.http_post from PUBLIC, and grants it to postgres, anon, authenticated, service_role, and supabase_functions_admin. The same happens when pg_net 0.11 or earlier is enabled on a project.