如何为现有的 postgres 数据库创建用户(读写和只读)和管理员角色?

How to create user(read-write & readonly) and admin roles for an existing postgres database?

我们在生产中有一个现有的 postgres 数据库,超级用户 adm 被用来做所有事情。我们的 Web 应用程序使用相同的用户连接到数据库,管理员(patching/updating 等)也使用相同的凭据。

我们必须解决这个问题才能拥有角色,这样我们才能拥有 read-writereadonlyadmin 角色。 我们不希望我们的 Web 应用程序和管理员以 superuser.

的身份连接到数据库

话虽如此,我创建了以下 sql 脚本来制作适当的角色。 我不是数据库专家(还不是)所以想知道问题或解决这个问题的更好方法。

ALTER ROLE adm NOLOGIN;

CREATE role user_role NOINHERIT;
CREATE role readonlyuser_role NOINHERIT;
CREATE role admin_role CREATEDB CREATEROLE NOINHERIT;
CREATE ROLE u_service LOGIN PASSWORD '<some password>' INHERIT;
CREATE ROLE u_admin LOGIN PASSWORD '<some password>' INHERIT;
CREATE ROLE u_reader LOGIN PASSWORD '<some password>' INHERIT;

GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser_role;
GRANT ALL PRIVILEGES ON SCHEMA public TO admin_role;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL PROCEDURES IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL ROUTINES IN SCHEMA public TO user_role, admin_role;

GRANT ALL PRIVILEGES ON SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL PROCEDURES IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL ROUTINES IN SCHEMA audit TO admin_role;

GRANT admin_role TO u_admin;
GRANT user_role TO u_service;
GRANT readonlyuser_role TO u_reader;

需要考虑的几件事。

说明 user_role 和 readonlyuser_role 可以做什么

首先撤销这两个角色的 所有 权限,然后仅在需要时将它们添加回来。这使您对角色应该做什么的意图更加清晰,并且在实践中更安全,因为比预期更高的权限不会意外潜入。

REVOKE ALL ON SCHEMA public FROM public;  --only authorized roles can do anything here.
REVOKE ALL ON SCHEMA public FROM user_role;
REVOKE ALL ON SCHEMA public FROM readonlyuser_role;


GRANT ...

数据库所有者是本地超级用户

我们通常让数据库所有者成为一个额外的角色;仅登录以创建或更改模式,然后优雅退出的人。如果您的 admin_role 不止于此,请考虑添加 owner_role.

public 角色需要连接吗?

考虑添加

 REVOKE CONNECT ON DATABASE yourdb FROM public;

这阻止了在同一数据库服务器上创建的 任何 角色可以登录到此数据库的漏洞。

在交易块中完成所有这些

在作业中途停止权限分配会导致各种麻烦,就像将钥匙锁在车里一样。尽可能将权限分配作为一个事务,这样漏掉的分号就不会把你拒之门外。