一文读懂图数据库 Nebula Graph 访问控制实现原理
摘要:数据库权限管理对大家都很熟悉,然而怎么做好数据库权限管理呢?在本文中将详细介绍 Nebula Graph 的用户管理和权限管理。

本文首发 Nebula Graph 博客:https://nebula-graph.com.cn/posts/access-control-design-code-nebula-graph/
数据库权限管理对大家来说都已经很熟悉了。Nebula Graph 本身是一个高性能的海量图数据库,数据库的安全问题更是数据库设计的重中之重。目前 Nebula Graph 已支持基于角色的权限控制功能。在这篇文章中将详细介绍 Nebula Graph 的用户管理和权限管理。
Nebula Graph 架构体系

由上图可知,Nebula Graph的主体架构分为三部分:Computation Layer、Storage Layer 和 Meta Service。Console 、API 和 Web Service 被统称为 Client API。 账户数据和权限数据将被存储在 Meta Engine中,当Query Engine 启动后,将会初始 Meta Client,Query Engine 将通过 Meta Client 与 Meta Service 进行通信。
当用户通过 Client API 连接 Query Engine 时,Query Engine 会通过 Meta Client 查询 Meta Engine 的用户数据,并判断连接账户是否存在,以及密码是否正确。当验证通过后,连接创建成功,用户可以通过这个连接执行数据操作。当用户通过 Client API 发送操作指令后,Query Engine 首先对此指令做语法解析,识别操作类型,通过操作类型、用户角色等信息进行权限判断,如果权限无效,则直接在 Query Engine 阻挡操作,并返回错误信息至 Client API。 在整个权限检查的过程中,Nebula Graph 对 Meta data 进行了缓存,将在以下章节中介绍。
功能描述
在介绍功能之前,需要先描述一下 Nebula Graph 的逻辑结构:Nebula Graph 是一个支持多图空间(Space) 的图数据库,Space 中独立管理 Schema 和 Data,Space 和 Space 之间相互独立。另外,Nebula Graph 还提供了一系列高级命令用于全局管理 Cluster,Cluster 的操作命令和 Space 的操作命令将在下文中详细描述。
因此 Nebula Graph 的权限管理将会基于图空间(Space)、角色(Role)、操作(Operation) 三个维度进行。详细描述请看下列子章节。
角色划分
Nebula Graph 提供了五种操作角色,分别是 GOD、ADMIN、DBA、USER、GUEST,这五种操作角色基本覆盖了所有的数据安全控制的场景。一个登陆账户(Account)可以在不同的 Space 中拥有不同角色,但一个 Account 在同一个 Space 中只能拥有一种角色。角色讲解:
- GOD:相当于 Linux 操作系统中的 root 用户,拥有最高的管理权限。Nebula Graph Cluster 在初始化时会默认创建一个 GOD 角色的 Account,名为 root。
- ADMIN:基于 Space 的高级管理员,拥有此 Space 之内的所有管理权限,但对整个集群则没有管理权限。
- DBA:数据库管理员,可以对权限内的 Space 进行管理,例如对 Schema / Data 进行修改和查询。和 ADMIN 的区别是 DBA 不能对某个 Account 进行授权操作,但 ADMIN 可以。
- USER:普通的数据库使用角色。可读写 Data,可读 Schema 但没有写权限。
- GUEST:访问者角色,对权限内 Space 的 Schema 和 Data 有只读权限。
详细权限列表如下图所示:
| OPERATION | GOD | ADMIN | DBA | USER | GUEST |
|---|---|---|---|---|---|
| Read Space | Y | Y | Y | Y | Y |
| Write Space | Y | ||||
| Read Schema | Y | Y | Y | Y | Y |
| Write Schema | Y | Y | Y | ||
| Write User | Y | ||||
| Write Role | Y | Y | |||
| Read Data | Y | Y | Y | Y | Y |
| Write Data | Y | Y | Y | Y | |
| Special operation | Y | Y | Y | Y | Y |
注 : Special Operation 为特殊操作,例如 SHOW SPACE,每个角色都可以执行,但其执行结果只显示 Account 权限内的结果。
数据库操作权限细分
基于上边的角色列表,不同的角色拥有不同的操作许可,详细如下:
| OPERATION | STATEMENTS |
|---|---|
| Read Space | 1.USE 2.DESCRIBE SPACE |
| Write Space | 1.CREATE SPACE 2.DROP SPACE 3.CREATE SNAPSHOT 4.DROP SNAPSHOT 5.BALANCE |
| Read Schema | 1.DESCRIBE TAG 2.DESCRIBE EDGE 3.DESCRIBE TAG INDEX 4.DESCRIBE EDGE INDEX |
| Write Schema | 1.CREATE TAG 2.ALTER TAG 3.CREATE EDGE 4.ALTER EDGE 5.DROP TAG 6.DROP EDGE 7.CREATE TAG INDEX 8.CREATE EDGE INDEX 9.DROP TAG INDEX 10.DROP EDGE INDEX |
| Write User | 1.CREATE USER 2.DROP USER 3.ALTER USER |
| Write Role | 1.GRANT 2.REVOKE |
| Read Data | 1.GO 2.PIPE 3.LOOKUP 4.YIELD 5.ORDER BY 6.FETCH VERTEX 7.FETCH EDGE 8.FIND PATH 9.LIMIT 10.GROUP BY 11.RETURN |
| Write Data | 1.REBUILD TAG INDEX 2.REBUILD EDGE INDEX 3.INSERT VERTEX 4.UPDATE VERTEX 5.INSERT EDGE 6.UPDATE DEGE 7.DELETE VERTEX 8.DELETE EDGE |
| Special Operation | 1. SHOW,eg: SHOW SPACE、SHOW ROLES 2.CHANGE PASSWORD |
控制逻辑

Nebula Graph 的用户管理和权限管理和大多数数据库的控制相似,基于 meta server,对图空间(Space)、角色(Role)、操作(Operation)三个层面进行权限管理,当 Client 连接 Nebula Graph Server 的时候,Nebula Graph Server 首先会验证登陆账户(Account)是否存在,并验证密码是否有效。
登录成功后,Nebula Graph Server 会为此连接初始 Session ID,并将 Session ID、用户信息、权限信息和 Space 信息一起加载到 Session 结构中。后续的每次操作将基于 Session 结构中的信息进行权限判断。直到用户主动退出连接或 session timeout,Session 销毁。另外,Meta Client 对权限信息进行了缓存,并根据设置的时间频率进行缓存同步,有效降低了用户连接的过程的时间耗费。
控制逻辑代码片段
Permission Check
bool PermissionCheck::permissionCheck(session::Session *session, Sentence* sentence) {
auto kind = sentence->kind();
switch (kind) {
case Sentence::Kind::kUnknown : {
return false;
}
case Sentence::Kind::kUse :
case Sentence::Kind::kDescribeSpace : {
/**
* Use space and Describe space are special operations.
* Permission checking needs to be done in their executor.
* skip the check at here.
*/
return true;
}
...
Permission Check Entry
Status SequentialExecutor::prepare() {
for (auto i = 0U; i < sentences_->sentences_.size(); i++) {
auto *sentence = sentences_->sentences_[i].get();
auto executor = makeExecutor(sentence);
if (FLAGS_enable_authorize) {
auto *session = executor->ectx()->rctx()->session();
/**
* Skip special operations check at here. they are :
* kUse, kDescribeSpace, kRevoke and kGrant.
*/
if (!PermissionCheck::permissionCheck(session, sentence)) {
return Status::PermissionError("Permission denied");
}
}
...
}
示例
查看现有用户角色
(root@127.0.0.1:6999) [(none)]> SHOW USERS;
===========
| Account |
===========
| root |
-----------
Got 1 rows (Time spent: 426.351/433.756 ms)
创建用户
(root@127.0.0.1:6999) [(none)]> CREATE USER user1 WITH PASSWORD "pwd1"
Execution succeeded (Time spent: 194.471/201.007 ms)
(root@127.0.0.1:6999) [(none)]> CREATE USER user2 WITH PASSWORD "pwd2"
Execution succeeded (Time spent: 33.627/40.084 ms)
# 查看现有用户角色
(root@127.0.0.1:6999) [(none)]> SHOW USERS;
===========
| Account |
===========
| root |
-----------
| user1 |
-----------
| user2 |
-----------
Got 3 rows (Time spent: 24.415/32.173 ms)
为 Space 中的不同 Account 指定角色
# 创建图空间
(root@127.0.0.1:6999) [(none)]> CREATE SPACE user_space(partition_num=1, replica_factor=1)
Execution succeeded (Time spent: 218.846/225.075 ms)
(root@127.0.0.1:6999) [(none)]> GRANT DBA ON user_space TO user1
Execution succeeded (Time spent: 203.922/210.957 ms)
(root@127.0.0.1:6999) [(none)]> GRANT ADMIN ON user_space TO user2
Execution succeeded (Time spent: 36.384/49.296 ms)
查看特定 Space 的已有角色
(root@127.0.0.1:6999) [(none)]> SHOW ROLES IN user_space
=======================
| Account | Role Type |
=======================
| user1 | DBA |
-----------------------
| user2 | ADMIN |
-----------------------
Got 2 rows (Time spent: 18.637/29.91 ms)
取消特定 Space 的角色授权
(root@127.0.0.1:6999) [(none)]> REVOKE ROLE DBA ON user_space FROM user1
Execution succeeded (Time spent: 201.924/216.232 ms)
# 查看取消之后,user_space 现有角色
(root@127.0.0.1:6999) [(none)]> SHOW ROLES IN user_space
=======================
| Account | Role Type |
=======================
| user2 | ADMIN |
-----------------------
Got 1 rows (Time spent: 16.645/32.784 ms)
删除某个 Account 角色
(root@127.0.0.1:6999) [(none)]> DROP USER user2
Execution succeeded (Time spent: 203.396/216.346 ms)
# 查看 user2 在 user_space 的角色
(root@127.0.0.1:6999) [(none)]> SHOW ROLES IN user_space
Empty set (Time spent: 20.614/34.905 ms)
# 查看数据库现有 account
(root@127.0.0.1:6999) [(none)]> SHOW USERS;
===========
| Account |
===========
| root |
-----------
| user1 |
-----------
Got 2 rows (Time spent: 22.692/38.138 ms)
本文到此结束,如果你喜欢本文,可以给我们点个 star 哟 GitHub 传送门:https://github.com/vesoft-inc/nebula ;
想了解、交流图数据库技术的小伙伴,可以联系 Nebula Graph 官方小助手微信号:NebulaGraphbot 来群里和业内大牛聊聊哟~~
Hi,我是 bright-starry-sky,是图数据 Nebula Graph 研发工程师,对数据库存储有浓厚的兴趣,希望本次的经验分享能给大家带来帮助,如有不当之处希望你能在本文【评论】区留言,谢谢~
一文读懂图数据库 Nebula Graph 访问控制实现原理的更多相关文章
- 分布式图数据库 Nebula Graph 的 Index 实践
导读 索引是数据库系统中不可或缺的一个功能,数据库索引好比是书的目录,能加快数据库的查询速度,其实质是数据库管理系统中一个排序的数据结构.不同的数据库系统有不同的排序结构,目前常见的索引实现类型如 B ...
- 图数据库 Nebula Graph TTL 特性
导读 身处在现在这个大数据时代,我们处理的数据量需以 TB.PB, 甚至 EB 来计算,怎么处理庞大的数据集是从事数据库领域人员的共同问题.解决这个问题的核心在于,数据库中存储的数据是否都是有效的.有 ...
- 分布式图数据库 Nebula Graph 中的集群快照实践
1 概述 1.1 需求背景 图数据库 Nebula Graph 在生产环境中将拥有庞大的数据量和高频率的业务处理,在实际的运行中将不可避免的发生人为的.硬件或业务处理错误的问题,某些严重错误将导致集群 ...
- 初识分布式图数据库 Nebula Graph 2.0 Query Engine
摘要:本文主要介绍 Query 层的整体结构,并通过一条 nGQL 语句来介绍其通过 Query 层的四个主要模块的流程. 一.概述 分布式图数据库 Nebula Graph 2.0 版本相比 1.0 ...
- 图数据库 Nebula Graph 在 Boss 直聘的应用
本文首发于 Nebula Graph 官方博客:https://nebula-graph.com.cn/posts/nebula-graph-risk-control-boss-zhipin/ 摘要: ...
- 图数据库 Nebula Graph 的数据模型和系统架构设计
Nebula Graph:一个开源的分布式图数据库.作为唯一能够存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不仅能够在高并发场景下满足毫秒级的低时延查询要求,而且能够提供极高的 ...
- 图数据库 Nebula Graph 的安装部署
Nebula Graph:一个开源的分布式图数据库.作为唯一能够存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不仅能够在高并发场景下满足毫秒级的低时延查询要求,还能够实现服务高可 ...
- 图数据库 Nebula Graph 是什么
图数据库(英语:Graph Database)是一个使用图结构进行语义查询的数据库.该系统的关键概念是图,形式上是点 (Node 或者 Vertex) 和边 (Edge 或者 Relationship ...
- GraphX 在图数据库 Nebula Graph 的图计算实践
不同来源的异构数据间存在着千丝万缕的关联,这种数据之间隐藏的关联关系和网络结构特性对于数据分析至关重要,图计算就是以图作为数据模型来表达问题并予以解决的过程. 一.背景 随着网络信息技术的飞速发展,数 ...
- LC滤波器简单设计法 - 一文读懂LC滤波器简单设计方法及原理介绍,LC值计算方法
LC滤波器概述 LC滤波器也称为无源滤波器,是传统的谐波补偿装置.LC滤波器之所以称为无源滤波器,顾名思义,就是该装置不需要额外提供电源.LC滤波器一般是由滤波电容器.电抗器和电阻器适当组合而成,与谐 ...
随机推荐
- JavaScript一种新的数据结构类型Map
什么是map 它类似于对象,是键值对的集合,但键的范围不局限在于字符串.各种类型的值(包含对象)都可以作为键. 如果同一个键被多次赋值,后面的值将会覆盖其那面的值.如果读取一个未知的键,返回的是und ...
- 在Linux Ubuntu系统中部署C++环境与Visual Studio Code软件
本文介绍在Linux Ubuntu操作系统下,配置Visual Studio Code软件与C++代码开发环境的方法. 在文章VMware虚拟机部署Linux Ubuntu系统的方法中,我们介 ...
- .NET Core(C#) PadLeft和PadRight特定格式字符串长度补齐的方法和js中如何填充字符串
.NET Core(C#) 1、PadLeft和PadRight使用说明 两个方法都是对字符串格式化进行补齐填充,PadLeft是左边,而PadRight是右边 '1010'.PadLeft(10,' ...
- 通过Unity导出的Android Studio和Google安卓原生工程的结构图对比
使用Unity导出Android Studio工程前建议查看我之前的文章<Unity2019及Unity2020打包android的环境配置>,替换或修改Unity安装目录下的basePr ...
- 中文LLaMA模型和指令精调的Alpaca大模型:中文数据进行二次预训练
中文LLaMA模型和指令精调的Alpaca大模型:中文数据进行二次预训练,进一步提升了中文基础语义理解能力 以ChatGPT.GPT-4等为代表的大语言模型(Large Language Model, ...
- 推荐系统[三]:粗排算法常用模型汇总(集合选择和精准预估),技术发展历史(向量內积,Wide&Deep等模型)以及前沿技术
1.前言:召回排序流程策略算法简介 推荐可分为以下四个流程,分别是召回.粗排.精排以及重排: 召回是源头,在某种意义上决定着整个推荐的天花板: 粗排是初筛,一般不会上复杂模型: 精排是整个推荐环节的重 ...
- 10.5 认识XEDParse汇编引擎
XEDParse 是一款开源的x86指令编码库,该库用于将MASM语法的汇编指令级转换为对等的机器码,并以XED格式输出,目前该库支持x86.x64平台下的汇编编码,XEDParse的特点是高效.准确 ...
- 从嘉手札<2024-1-17>
昨天我以为 人生是一场体验 是一辆不会回头的列车 我们遇到了风景 感悟了风景 放下了风景 构成了自己 今天我以为 静水流深.光而不耀 可多思必多疑 思维是一种极为复杂的东西 我曾经觉得知行合一是对自我 ...
- Python中的UnboundLocalError是什么错误?如何解决?
在一个月黑风高的夜晚,我们满心欢喜地写出以下代码: money = 10000 # 当前的财产,单位为元 def add_money(value): money += value print('当 ...
- 小知识:解决EXP-00003的报错
客户有个需求:某用户程序(含exp导出任务)报错EXP-00003,这个错误并不会影响整个导出任务的结束,但由于是晚上的定时任务,该错误会触发夜间告警.客户想通过数据库层面来规避掉此错误. 事实上,这 ...