存储在向量数据库中的数据通常是企业专有的,可能包含敏感信息,如客户记录、法律合同、电子健康记录 (EHR)、财务数据和知识产权。此外,强大的安全措施对于保护这些数据至关重要。如果存储在向量数据库中的数据未得到保护,可能会暴露一种称为“嵌入反演攻击”的漏洞,恶意行为者可能因此从嵌入本身重建原始数据。
严格的合规法规管理着各行业中存储在向量数据库中的数据。例如,医疗保健行业必须遵守 HIPAA,该法规规定了如何存储、传输和保护受保护的健康信息 (PHI)。同样,金融服务行业遵循 PCI DSS 以保护敏感财务数据。这些法规要求开发者确保数据存储和传输符合不同地区的行业特定法律框架。因此,支持数据隐私、安全和主权的功能是选择合适的向量数据库时的决定性因素。
本文探讨了在利用向量搜索优势的同时,确保关键数据安全的各种策略。实施其中一些安全方法可以帮助您构建增强隐私的相似性搜索算法,并将其集成到您的 AI 应用中。此外,您还将学习如何构建完全数据主权的架构,使您能够保留对数据的控制权,并遵守相关的数据法律法规。
要直接跳到代码实现部分,点击此处。
向量数据库安全:概述
向量数据库通常默认未加保护,以方便快速原型设计和实验。这种方法允许开发者快速导入数据、构建向量表示并测试相似性搜索算法,而无需最初考虑安全问题。然而,在生产环境中,未加保护的数据库会带来重大的数据泄露风险。
对于生产使用,强大的安全系统至关重要。身份验证,特别是使用静态 API 密钥,是控制访问和防止未经授权修改的常用方法。然而,简单的 API 身份验证不足以满足需要细粒度控制的企业数据需求。
静态 API 密钥的主要挑战在于其“全有或全无”的访问方式,这对于企业应用中基于角色的数据隔离来说是不够的。此外,泄露的密钥可能赋予攻击者完全的数据操作或窃取权限。为了增强向量数据库的安全性,开发者通常需要以下措施:
- 加密:这确保了敏感数据在应用程序和向量数据库之间传输时被混淆。这有助于防范中间人 (MitM) 攻击,在此类攻击中,恶意行为者可能试图在传输过程中拦截和窃取数据。
- 基于角色的访问控制:如前所述,传统的静态 API 密钥提供“全有或全无”的访问权限,这在企业环境中是一个重大的安全风险。RBAC 通过定义用户角色并根据这些角色分配特定的数据访问权限,提供了一种更细粒度的方法。例如,分析师可能对特定数据集只有只读访问权限,而管理员可能对整个数据库拥有完整的 CRUD(创建、读取、更新、删除)权限。
- 部署灵活性:数据驻留法规,如 GDPR(通用数据保护条例)以及行业特定的合规要求,规定了数据可以在何处存储、处理和访问。开发者需要选择提供符合这些法规的部署选项的数据库解决方案。这可能包括在公司私有云中的本地部署,或遵守数据驻留法律的地理分布式云部署。
Qdrant 如何处理数据隐私和安全
Qdrant 设计选择的基石之一是对安全功能的关注。我们内置了一系列功能,同时考虑到企业用户的需求,这些功能允许在完全数据主权的架构上构建细粒度的访问控制。
Qdrant 实例默认是未加保护的。然而,当您准备好在生产环境中部署时,Qdrant 提供了一系列安全功能,允许您控制数据访问、保护数据免遭泄露并遵守法规要求。使用 Qdrant,您可以构建细粒度的访问控制,隔离角色和权限,并创建完全数据主权的架构。
API 密钥和 TLS 加密
对于更简单的用例,Qdrant 提供了基于 API 密钥的身份验证。这包括常规 API 密钥和只读 API 密钥。常规 API 密钥授予对读取、写入和删除操作的完全访问权限,而只读密钥仅限制对数据检索操作的访问,阻止写入操作。
在 Qdrant 云上,您可以使用云控制面板创建 API 密钥。这使您能够生成可访问单个节点、集群或多个集群的 API 密钥。您可以在此处阅读相关步骤。
对于本地或本地部署,您需要配置 API 密钥身份验证。这需要在 Qdrant 配置文件或作为环境变量中指定一个密钥。这确保了发送到服务器的所有请求都必须在头部包含一个有效的 API 密钥。
使用简单的基于 API 密钥的身份验证时,您还应开启 TLS 加密。否则,您的连接将暴露于嗅探和 MitM 攻击。要使用 TLS 保护您的连接,您需要创建证书和私钥,然后在配置中启用 TLS。
API 身份验证结合 TLS 加密,为您的 Qdrant 实例提供了第一层安全保障。然而,要实现更细粒度的访问控制,建议的方法是利用 JSON Web Tokens (JWT)。
Qdrant 中的 JWT
JSON Web Tokens (JWT) 是一种紧凑、URL 安全且无状态的方式,用于表示在两方之间传输的声明。这些声明被编码为 JSON 对象,并经过加密签名。
JWT 由三部分组成:头部 (header)、载荷 (payload) 和签名 (signature),它们通过点 (.) 连接成一个字符串。头部包含令牌类型和使用的算法。载荷包含声明(稍后详细解释)。签名是加密哈希,确保令牌的完整性。
在 Qdrant 中,JWT 构成了构建强大访问控制的基础。让我们了解它是如何工作的。
通过在配置中指定 API 密钥并开启 jwt_rbac 功能(或者,它们可以设置为环境变量),可以在 Qdrant 实例上启用 JWT。对于任何后续请求,API 密钥用于编码或解码令牌。
JWT 的工作方式是,仅有 API 密钥就足以生成令牌,而无需与 Qdrant 实例或服务器进行任何通信。有几个库可以帮助通过编码载荷来生成令牌,例如 PyJWT(用于 Python)、jsonwebtoken(用于 JavaScript)和 jsonwebtoken(用于 Rust)。Qdrant 使用 HS256 算法对令牌进行编码或解码。
我们很快会查看载荷结构,但以下是如何使用 PyJWT 生成令牌。
import jwt
import datetime
# Define your API key and other payload data
api_key = "your_api_key"
payload = { ...
}
token = jwt.encode(payload, api_key, algorithm="HS256")
print(token)
生成令牌后,应将其包含在后续请求中。可以通过在 Authorization 头部或请求的 API Key 头部中提供作其为 bearer token 来实现。
以下是如何在 Python 中使用 QdrantClient 执行此操作的示例
from qdrant_client import QdrantClient
qdrant_client = QdrantClient(
"https://:6333",
api_key="<JWT>", # the token goes here
)
# Example search vector
search_vector = [0.1, 0.2, 0.3, 0.4]
# Example similarity search request
response = qdrant_client.search(
collection_name="demo_collection",
query_vector=search_vector,
limit=5 # Number of results to retrieve
)
为了方便起见,我们在 Qdrant Web UI 中添加了一个 JWT 生成工具,位于 🔑 选项卡下。对于您的本地部署,您可以在 https://:6333/dashboard#/jwt 找到它。
载荷配置
您可以在 JWT 载荷中使用几种不同的选项(声明),这些选项有助于控制访问和功能。让我们一一查看它们。
exp:此声明是令牌的过期时间,以秒为单位的 Unix 时间戳表示。过期时间过后,令牌将无效。
value_exists:此声明根据集合中存储的特定键值验证令牌。通过使用此声明,您可以简单地更改值来撤销访问权限,而无需使 API 密钥失效。
access:此声明定义了令牌的访问级别。访问级别可以是全局读取 (r) 或管理 (m)。它也可以特定于某个集合,甚至是集合的子集,使用读取 (r) 和读写 (rw) 权限。
让我们看几个 JWT 载荷配置示例。
场景 1:1 小时过期时间,以及对某个集合的只读访问权限
{
"exp": 1690995200, // Set to 1 hour from the current time (Unix timestamp)
"access": [
{
"collection": "demo_collection",
"access": "r" // Read-only access
}
]
}
场景 2:1 小时过期时间,以及对具有特定角色的用户的访问权限
假设您有一个“users”集合,并为每个用户定义了特定角色,例如“developer”、“manager”、“admin”、“analyst”和“revoked”。在这种场景下,您可以使用 exp 和 value_exists 的组合。
{
"exp": 1690995200,
"value_exists": {
"collection": "users",
"matches": [
{ "key": "username", "value": "john" },
{ "key": "role", "value": "developer" }
],
},
}
现在,如果您想撤销某个用户的访问权限,只需更改其角色的值即可。使用上述类型的令牌载荷进行的所有未来请求都将无效。
场景 3:1 小时过期时间,以及对集合子集的读写访问权限
您甚至可以指定特定于集合子集的访问级别。这在您利用多租户并希望隔离访问权限时特别有用。
{
"exp": 1690995200,
"access": [
{
"collection": "demo_collection",
"access": "r",
"payload": {
"user_id": "user_123456"
}
}
]
}
通过组合这些声明,您可以完全自定义用户或角色在向量存储中的访问级别。
使用 JWT 创建基于角色的访问控制 (RBAC)
如上所述,JWT 声明提供了强大的杠杆,您可以通过它们在 Qdrant 上创建细粒度的访问控制。让我们将所有这些结合起来,了解它如何帮助您创建基于角色的访问控制 (RBAC)。
在典型的企业应用中,您会根据用户的角色和权限对用户进行隔离。这些角色可能包括:
- 管理员或所有者:具有完全访问权限,并可以生成 API 密钥。
- 编辑者:对特定集合具有读写访问权限。
- 查看者:对特定集合具有只读访问权限。
- 数据科学家或分析师:对特定集合具有只读访问权限。
- 开发者:对开发或测试特定集合具有读写访问权限,但对生产数据访问受限。
- 访客:对公开可用的集合具有有限的只读访问权限。
此外,您可以在集合的某个部分内部创建访问级别。在使用了基于载荷的分区(payload-based partitioning)的多租户应用中,您可以为属于特定用户角色的集合子集创建只读访问权限。
您的应用需求最终将帮助您决定应该创建哪些角色和访问级别。例如,在管理客户数据的应用中,您可以创建额外的角色,例如:
客户支持代表:对客户服务相关数据具有读写访问权限,但无权访问账单信息。
账单部门:对账单数据具有只读访问权限,对支付记录具有读写访问权限。
营销分析师:对匿名客户数据具有只读访问权限,用于分析。
每个角色都可以分配一个 JWT,其中包含指定过期时间、集合的读写权限以及验证条件的声明。
在这样的应用中,客户支持代表角色的 JWT 载荷示例可能如下:
{
"exp": 1690995200,
"access": [
{
"collection": "customer_data",
"access": "rw",
"payload": {
"department": "support"
}
}
],
"value_exists": {
"collection": "departments",
"matches": [
{ "key": "department", "value": "support" }
]
}
}
如您所见,通过实施 RBAC,您可以确保角色及其权限的适当隔离,并避免应用中的隐私漏洞。
Qdrant 混合云与数据主权
数据治理因国家而异,特别是对于处理不同数据隐私、安全和访问法规的全球性组织。这通常需要在特定的地理范围内部署基础设施。
为了满足这些需求,您选择的向量数据库应支持在您控制的基础设施内部进行部署和扩展。Qdrant 混合云提供了这种灵活性,以及分片、副本、JWT 身份验证和监控等功能。
Qdrant 混合云将来自各种环境(云、本地或边缘)的 Kubernetes 集群集成到统一的托管服务中。这使得组织可以通过 Qdrant 云 UI 管理 Qdrant 数据库,同时将数据库保留在自己的基础设施内部。
结合 JWT 和 RBAC,Qdrant 混合云提供了一个安全、私有和主权的向量存储。企业可以按地域扩展其 AI 应用,遵守当地法律,并保持严格的数据控制。
结论
向量相似性正日益成为利用非结构化数据的 AI 应用的支柱。通过将数据转换为向量(即其数值表示),组织可以构建利用语义搜索的强大应用,范围涵盖更优的推荐系统、帮助实现个性化的算法或强大的客户支持聊天机器人。
然而,要在生产环境中充分发挥 AI 的力量,组织需要选择一个提供强大隐私和安全功能,同时帮助他们遵守当地法律法规的向量数据库。
Qdrant 提供了卓越的效率和性能,以及实现细粒度数据访问控制、基于角色的访问控制 (RBAC) 和构建完全数据主权架构的能力。
有兴趣掌握向量搜索安全和部署策略吗?加入我们的 Discord 社区,探索更高级的搜索策略,与行业内的其他开发者和研究人员联系,并了解最新的创新!