PostgreSQL 15: 支持 security invoker 视图

John Doe 七月 7, 2025

你希望视图的访问权限,和底层的表访问权限一致吗?

在山坡漫步的大象

特性提交日志

新增对 security invoker 视图的支持。

security invoker 视图在访问其底层基础关系时,会使用视图调用者的权限进行权限检查,而非视图所有者的权限。此外,如果任何基础关系是启用了行级安全策略(RLS)的表,那么将会应用视图调用者的策略,而非视图所有者的策略。

这使得视图可以在不授予底层基础关系额外权限的情况下被定义,并且与其他数据库系统中的类似功能相匹配。

它还允许视图与行级安全策略更自然地结合使用,而不会影响为用户分配的策略。

讨论:https://postgr.es/m/b66dd6d6-ad3e-c6f2-8b90-47be773da240%40cybertec.at

示例

这个特性相当不错。对于表,你可以设置权限,允许某些用户访问,而拒绝其他用户访问。

在函数方面,通常函数是以调用者的身份运行的。例如,如果执行下面的命令:

$ psql -U redrock -c "select some_function()"

那么,some_function函数体内的所有操作(包括所有查询),都会以redrock用户的身份执行。

但有时候,创建一个能绕过安全检查的函数是有意义的,例如,它要执行一些用户不应该“手动”执行的操作。这类函数被称为 “security definer” 函数,因为标记为该类型的函数在被调用时,会以创建该函数的用户的权限执行,而非调用者的权限。

视图在这之前一直是 “security definer” 类型的。其设计思路是,如果你创建了一个视图,就可以精细地调整对该视图的权限,而表上的权限则不那么重要。

现在,我们可以改变这种情况了。

让我们来做个测试:

$ psql -X -U redrock -c 'CREATE USER test'

$ psql -X -U redrock -c 'CREATE TABLE source_data as select id from generate_series(1,10) id'

$ psql -X -U redrock -c 'CREATE VIEW old_type_view as select * from source_data'

$ psql -X -U redrock -c 'GRANT SELECT on old_type_view to test'

$ psql -X -U redrock -c 'CREATE VIEW new_type_view with (security_invoker = true ) as select * from source_data'

$ psql -X -U redrock -c 'GRANT SELECT on new_type_view to test'

现在,以test用户的身份操作:

$ psql -X -U test -d redrock -c "select * from old_type_view"
 id
----
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
(10 rows)

$ psql -X -U test -d redrock -c "select * from new_type_view"
ERROR:  permission denied for table source_data

旧类型的视图实际上是security_invoker = false,即使调用者没有底层表的访问权限,也能进行查询;而新类型的视图(security_invoker = true)则会查询失败。

非常不错的体验,感谢所有参与的社区人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/7faa5fc84bf46ea6c543993cffb8be64dff60d25