跳到主要内容
翻译页面

本页面由 AI 辅助从英文翻译而来。如两者存在差异,以英文版本为准。

Provider 会话与机密

另请参阅:
[SET] [UNSET] [ 会话变量 ] [ 全局标志 ]

会话可以将 Provider 绑定到一个别名下,该别名拥有自己的凭据、租户标签、参数默认值和请求并发限制,因此可以在一个会话中,并且在一条语句中,查询同一 Provider 的多个账号或租户。还可以在会话范围内覆盖凭据字段;机密可以保存在会话内存中,或在运维人员明确启用后保存在操作系统的机密存储中。以上各项均通过 SET 和 UNSET 配置,在 StackQL v1.0 及更高版本中可用。

此处描述的所有内容都限定在当前会话范围内。到 stackql srv 服务器的各个独立连接不共享绑定或机密,而每个 MCP 请求都是一个独立的会话,因此使用 MCP 服务器时,应在同一个语句批次中完成配置和查询。

Provider 别名​

SET "$.providers.<alias>" 将别名绑定到 Provider。其值是保存在字符串中的 JSON 文档:

键是否必需说明
provider是别名解析到的规范 Provider,例如 aws。
tenancy是分组标签,例如账号名称或租户名称。StackQL 不会对照 Provider 验证它。
authauth 与 auth_secret 二者之一身份验证文档,结构与该 Provider 在 --auth 对象中的条目相同。别名不会借用规范 Provider 的凭据。
auth_secretauth 与 auth_secret 二者之一保存身份验证文档的会话机密的名称。
params否已声明的 Provider 参数的默认值,包括已声明的服务器参数。查询中的谓词会覆盖默认值。
tuning否该别名的请求所适用的 max_concurrent 和 max_per_host 限制。Provider 和租户标签都相同的别名共用这些控制项,并且必须声明相同的调优设置。

下面的示例将 2 个 AWS 账号绑定到不同的别名下,每个别名从名称不同的环境变量中读取密钥,并在一条语句中查询这 2 个账号:

SET "$.providers.production" = '{
"provider": "aws",
"tenancy": "production-account",
"auth": {
"type": "aws_signing_v4",
"access_key_id_env_var": "PRODUCTION_AWS_ACCESS_KEY_ID",
"secret_access_key_env_var": "PRODUCTION_AWS_SECRET_ACCESS_KEY"
},
"params": {"region": "ap-southeast-2"},
"tuning": {"max_concurrent": 4, "max_per_host": 4}
}';

SET "$.providers.development" = '{
"provider": "aws",
"tenancy": "development-account",
"auth": {
"type": "aws_signing_v4",
"access_key_id_env_var": "DEVELOPMENT_AWS_ACCESS_KEY_ID",
"secret_access_key_env_var": "DEVELOPMENT_AWS_SECRET_ACCESS_KEY"
},
"params": {"region": "ap-southeast-2"},
"tuning": {"max_concurrent": 2}
}';

SELECT name, 'production' AS account FROM production.s3.buckets
UNION ALL
SELECT name, 'development' AS account FROM development.s3.buckets;

环境变量引用从 StackQL 进程环境中解析;不存在会话本地的环境。AWS 临时凭据还需要会话令牌字段或环境变量引用。

对于元数据语句和数据语句,别名的行为与其 Provider 相同:SHOW、DESCRIBE、SELECT、INSERT、UPDATE、DELETE 和 EXEC 都接受用别名代替 Provider 名称。别名不适用于原生内置关系,也不适用于预览版 IaC 关系。使用不同别名的 UNION ALL 分支按顺序执行。

每个查询都会获取别名凭据的独立快照。更改绑定会影响之后的查询,不影响已在运行的查询。UNSET "$.providers.<alias>" 移除该绑定。

覆盖凭据字段​

SET "$.auth.<provider>.<field>" 在当前会话中更改 Provider 身份验证上下文的一个字段,其中字段名是该 Provider 的 --auth 条目中的键:

SET "$.auth.github.credentialsenvvar" = 'GITHUB_TOKEN_READONLY';
SELECT name FROM github.repos.repos WHERE org = 'stackql';
UNSET "$.auth.github.credentialsenvvar";

与别名一样,更改适用于 SET 之后启动的查询。如果 Provider 的身份验证已被取消设置,或其别名没有可用的 auth,针对它的查询会在发送任何请求之前失败。

会话机密​

默认情况下,每个会话都有一个仅存在于内存中的机密存储,无需任何配置。SET "$.secrets.<name>" 存储一个字面量字符串,通常是 JSON 身份验证文档,Provider 别名通过 auth_secret 引用它:

SET "$.secrets.production" = '{"type":"aws_signing_v4","access_key_id_env_var":"PRODUCTION_AWS_ACCESS_KEY_ID","secret_access_key_env_var":"PRODUCTION_AWS_SECRET_ACCESS_KEY"}';
SET "$.providers.production" = '{"provider":"aws","tenancy":"production-account","auth_secret":"production","params":{"region":"ap-southeast-2"}}';

SELECT name FROM production.s3.buckets;

UNSET "$.secrets.production";

轮换机密会影响之后的查询;删除机密会使之后的使用失败。新会话会获得一个全新的空存储,会话结束时该存储被释放。UNSET "$.secret_store" 丢弃当前的存储绑定,并以空的会话内存重新开始。

正常的凭据使用,以及存储变量或配置的 SET 语句,都不会将机密写入 SQL 后端。将敏感数据放入普通变量或表中,由调用方自行负责。

持久化的操作系统机密存储​

持久化存储默认禁用,只能由运维人员使用 --allow-persistent-secrets 启动 StackQL 来启用;SQL 无法授予该能力。设置该标志后,会话通过以下语句选择操作系统存储:

SET "$.secret_store" = '{"backend": "os", "namespace": "stackql/provider-auth"}';

该存储是 macOS Keychain、Linux Secret Service(secret-tool,需要可用的会话服务)或 Windows Credential Manager。仅接受 os 后端:即使设置了该标志,平面文件存储、文件路径以及任何隐式的文件回退也会被拒绝;操作系统设施不可用时会失败,而不会回退到文件。

写入操作系统存储的值在 SQL 会话结束后仍然存在,需使用 UNSET "$.secrets.<name>" 显式删除。重置存储绑定不会删除已持久化的值。对该存储的访问由 StackQL 进程的操作系统身份决定;命名空间不是按用户的访问控制,因此不要把这项需明确启用的功能当作多用户保险库。

SQL 中的机密值​

除非运维人员使用 --allow-secret-dereference 启动 StackQL,否则机密值绝不会被解引用到 SQL 中。设置该标志后,"$secrets.production"、"$secrets.production.credentials"、"$auth.github.password" 和 "$providers.production.auth.credentials" 这样的引用可在表达式中解析:

SELECT upper("$secrets.production.credentials") AS credential;

/*
-- the same statement in a session started without --allow-secret-dereference
SELECT upper("$secrets.production.credentials") AS credential;
-- FAILS with secret variable dereferencing is disabled
*/

如果启动时未设置该标志,同一语句会在任何求值之前被拒绝,如注释掉的那条语句所示。设置该标志即表示确认:显式解引用的值可能进入 SQL 暂存区、结果、日志和持久化的查询产物。正常的 Provider 身份验证不需要它。

权限​

启用访问管理后,读取变量和机密需要 session/variables:read,SET 或 UNSET 需要 session/config:write。解析后的别名在执行前按其规范 Provider 进行授权。按变量和按机密的所有权与权限授予尚未实现。