
# 权限配置最佳实践
#### 背景
一个数据库可能有很多的用户需要访问，为了方便管理这些用户，将用户组成一个数据库角色。一个数据库角色可以视为一个数据库用户或者一组数据库用户。
对于数据库来说，用户和角色是基本相同的概念，不同之处在于，使用CREATE ROLE创建角色，不会创建同名的SCHEMA，并且默认没有LOGIN权限；而使用CREATE USER创建用户，会自动创建同名的SCHEMA，默认有LOGIN权限。换句话说，一个拥有LOGIN权限的角色可以被认为是一个用户。在业务设计中，仅建议通过ROLE来组织权限，而不是用来访问数据库。
#### 最佳实践概述
权限配置不当会存在权限被利用的风险，本章节描述各权限角色的作用。
#### 解决方案
1. **数据库用户**
   数据库用户的主要用途是使用该用户账号连接数据库、访问数据库对象和执行SQL语句。在连接数据库时，必须使用一个已经存在的数据库用户。因此，作为数据库管理员，需要为每一个需要连接数据库的使用者规划一个数据库用户。
   在创建数据库用户时，至少需要指定用户名和密码。
   默认情况下，数据库用户可以分为两大类，详细信息请参见[表1]。
    表1用户分类 
   | 分类   | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   |:---|:---|
   | 初始用户 | 具有数据库的最高权限，并且具有所有的系统权限和对象权限。初始用户不受对象的权限设置影响。这个特点类似Unix系统的root的权限。从安全角度考虑，除了必要的情况，建议尽量避免以初始用户身份操作。 在安装数据库或者初始化数据库时，可以指定初始用户名和密码。如果不指定用户名则会自动生成一个与安装数据库的OS用户同名的初始用户。如果不指定密码则安装后初始用户密码为空，需要通过gsql客户端设置初始用户的密码后才能执行其他操作。 说明： 基于安全性考虑，GaussDB Kernel禁止了所有用户trust方式的远程登录方式，禁止了初始用户的任何方式的远程登录。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | 普通用户 | 默认可以访问数据库的默认系统表和视图（pg_authid、pg_largeobject、pg_user_status和pg_auth_history除外），可以连接默认的数据库postgres以及使用public模式下的对象（包括表、视图和函数等）。 - 可以通过CREATE USER、ALTER USER指定系统权限，或者通过GRANT ALL PRIVILEGE授予SYSADMIN权限。  - 可以通过GRANT语句授予某些对象的权限。  - 可以通过GRANT语法将其他角色或用户的权限授权给该用户。   |
      
   
2. **数据库权限** **分类**
   通过权限和角色，可以控制用户访问指定的数据，以及执行指定类型的SQL语句。详细信息请参见[表2]。
   系统权限只能通过CREATE/ALTER USER、CREATE/ALTER ROLE语句指定（其中SYSADMIN还可以通过GRANT/REVOKE ALL PRIVILEGES的方式赋予、回收），无法从角色继承。
    表2权限分类 
   | 分类   | 描述                                                                                                                                                                                                                                                                                                                                        |
   |:---|:---|
   | 系统权限 | 系统权限又称为用户属性，可以在创建用户和修改用户时指定，包括SYSADMIN、MONADMIN、OPRADMIN、POLADMIN、CREATEDB、CREATEROLE、AUDITADMIN和LOGIN。 系统权限一般通过CREATE/ALTER USER语句指定。除了SYSADMIN外的其他系统权限，无法通过GRANT/REVOKE进行授予和撤销。并且，系统权限无法通过ROLE被继承。 |
   | 对象权限 | 对象权限是指在表、视图、索引和函数等数据库对象上执行各种操作的权限，对象权限包括SELECT、INSERT、UPDATE和DELETE等。 只有对象的所有者或者系统管理员才可以执行GRANT/REVOKE语句来分配/撤销对象权限。                                                                                 |
   | 角色   | 角色是一组权限的集合，可以将一个角色的权限赋予其他角色和用户。 由于无法给其他角色和用户赋予系统权限，所以角色只有是对象权限的集合时才有意义。                                                                                                                            |
      
   
3. **数据库权限模型**
   1. **系统权限模型**
      - **默认权限机制**
        图1权限架构   
        ![](https://support.huaweicloud.com/distributed-devg-v8-gaussdb/figure/zh-cn_image_0000002558058359.png "点击放大")
        权限架构如[图1]，默认权限机制下sysadmin具有大多数的权限。
        - **初始安装用户**：集群安装过程中自动生成的账户，拥有系统的最高权限，能够执行所有的操作。
        
        - **SYSADMIN**：系统管理员权限，权限仅次于初始安装用户，默认具有与对象所有者相同的权限，但不包括监控管理员权限和运维管理员权限。
        
        - **MONADMIN**：监控管理员权限，具有监控模式dbe_perf及模式下视图和函数的访问权限和授予权限。
        
        - **OPRADMIN**：运维管理员权限，具有使用Roach工具执行备份恢复的权限。
        
        - **CREATEROLE**：安全管理员权限，具有创建、修改、删除用户/角色的权限。
        
        - **AUDITADMIN**：审计管理员权限，具有查看和维护数据库审计日志的权限。
        
        - **CREATEDB**：具有创建数据库的权限。
        
        - **POLADMIN**：安全策略管理员权限，具有创建资源标签，数据动态脱敏策略和统一审计策略的权限。
         
      
      - **三权分立机制**
        图2三权分立机制   
        ![](https://support.huaweicloud.com/distributed-devg-v8-gaussdb/figure/zh-cn_image_0000002558218337.png "点击放大")
        - **SYSADMIN**：系统管理员权限，不再具有创建、修改、删除用户/角色的权限，也不再具有查看和维护数据库审计日志的权限。
        
        - **CREATEROLE**：安全管理员权限，具有创建、修改、删除用户/角色的权限。
        
        - **AUDITADMIN**：审计管理员权限，具有查看和维护数据库审计日志的权限。
        
        - 一个用户/角色只能具有SYSADMIN、CREATEROLE和AUDITADMIN中的一项系统权限。
         
       
   
   2. **对象权限模型**
      - 对象权限：指在数据库、模式、表等数据库对象上执行特定动作的权限，比如：SELECT、INSERT、UPDATE、DELETE和CONNECT等。
      
      - 针对不同的数据库对象有不同的对象权限，相应地可以被授予用户/角色。
      
      - 通过GRANT/REVOKE来传递对象权限，对象权限可以通过角色被继承。
       
   
   3. **角色权限模型**
      GaussDB Kernel提供了一组默认角色，以gs_role_开头命名。它们提供对特定的、通常需要高权限操作的访问，可以将这些角色GRANT给数据库内的其他用户或角色，让这些用户能够使用特定的功能。在授予这些角色时应当非常小心，以确保它们被用在需要的地方。[表3]描述了内置角色允许的权限范围。
       表3内置角色权限 
      | 角色                       | 权限描述                                                                                                                                                                                                                                                                                                                                                        |
      |:---|:---|
      | gs_role_copy_files       | 具有执行copy ... to/from filename的权限，但需要先打开GUC参数enable_copy_server_files。                                                                                                                                                                                                                                                                                       |
      | gs_role_signal_backend   | 具有调用函数pg_cancel_backend()、pg_terminate_backend()和pg_terminate_session()来取消或终止其他会话的权限，但不能操作属于初始用户和PERSISTENCE用户的会话。                                                                                                                                                                                                                                          |
      | gs_role_tablespace       | 具有创建表空间（tablespace）的权限。                                                                                                                                                                                                                                                                                                                                     |
      | gs_role_replication      | 具有调用逻辑复制相关函数的权限，例如kill_snapshot()、pg_create_logical_replication_slot()、pg_create_physical_replication_slot()、pg_drop_replication_slot()、pg_replication_slot_advance()、pg_create_physical_replication_slot_extern()、pg_logical_slot_get_changes()、pg_logical_slot_peek_changes()，pg_logical_slot_get_binary_changes()、pg_logical_slot_peek_binary_changes()。 |
      | gs_role_account_lock     | 具有加解锁用户的权限，但不能加解锁初始用户和PERSISTENCE用户。                                                                                                                                                                                                                                                                                                                        |
      | gs_role_pldebugger       | 具有执行dbe_pldebugger下调试函数的权限。                                                                                                                                                                                                                                                                                                                                 |
      | gs_role_directory_create | 具有执行创建directory对象的权限，但需要先打开GUC参数enable_access_server_directory。                                                                                                                                                                                                                                                                                             |
      | gs_role_directory_drop   | 具有执行删除directory对象的权限，但需要先打开GUC参数enable_access_server_directory。                                                                                                                                                                                                                                                                                             |
         
      
    
4. 系统权限配置
   - **默认权限机制配置方法**
     - **初始用户**
       数据库安装过程中自动生成的账户称为初始用户。初始用户也是系统管理员、监控管理员、运维管理员和安全策略管理员，拥有系统的最高权限，能够执行所有的操作。如果安装时不指定初始用户名称则该账户与进行数据库安装的操作系统用户同名。如果在安装时不指定初始用户的密码，安装完成后密码为空，在执行其他操作前需要通过gsql客户端修改初始用户的密码。如果初始用户密码为空，则除修改密码外无法执行其他SQL操作以及升级、扩容和节点替换等操作。
       初始用户会绕过所有权限检查。建议仅将此初始用户作为DBA管理用途，而非业务用途。
       
     
     - **系统管理员**
       ```
       gaussdb=#CREATE USER u_sysadmin WITH SYSADMIN password '********';
       --或者使用如下SQL，效果一样，需要该用户已存在。
       gaussdb=#ALTER USER u_sysadmin01 SYSADMIN;
       ```
       
     
     - **监控管理员**
       ```
       gaussdb=#CREATE USER u_monadmin WITH MONADMIN password '********';
       --或者使用如下SQL，效果一样，需要该用户已存在。
       gaussdb=#ALTER USER u_monadmin01 MONADMIN;
       ```
       
     
     - **运维管理员**
       ```
       gaussdb=#CREATE USER u_opradmin WITH OPRADMIN password "xxxxxxxxx";
       --或者使用如下SQL，效果一样，需要该用户已存在。
       gaussdb=#ALTER USER u_opradmin01 OPRADMIN;
       ```
       
     
     - **安全策略管理员**
       ```
       gaussdb=#CREATE USER u_poladmin WITH POLADMIN password "xxxxxxxxx";
       --或者使用如下SQL，效果一样，需要该用户已存在。
       gaussdb=#ALTER USER u_poladmin01 POLADMIN;
       ```
       
      
   
   - **三权分立机制配置方式**
     此模式需要设置guc参数"enableSeparationOfDuty"的值为"on"，该参数为POSTMASTER类型参数，修改完之后需要重启数据库。
     ```
     gs_guc set -Z coordinator -Z datanode -N all -I all -c "enableSeparationOfDuty=on"
     gs_om -t stop
     gs_om -t start
     ```
     创建和配置相应的用户权限的语法和默认权限一致。
     
    
5. 角色权限配置
   ```
   --创建数据库test
   gaussdb=#CREATE DATABASE test;
   --创建角色role1，创建用户user1
   gaussdb=#CREATE ROLE role1 PASSWORD '********';
   gaussdb=#CREATE USER user1 PASSWORD '********';
   --赋予CREATE ANY TABLE权限角色role1
   gaussdb=#GRANT CREATE ON DATABASE test TO role1;
   --将角色role1赋予给用户user1,则用户user1属于组role1,继承role1的相应权限可以在test数据库中创建模式。
   gaussdb=#GRANT role1 TO user1;
   --查询用户和角色信息
   gaussdb=#\du role1|user1;
               List of roles
    Role name |  Attributes  | Member of 
   -----------+--------------+-----------
    role1     | Cannot login | {}
    user1     |              | {role1}
   ```
   
 
#### 实践效果
无。
