资讯动态

ZenML Secrets 完整实战指南:集中式密钥管理与 LLM/Agent 凭证安全实践

发布时间:2026/9/18 14:31:58 来源:尧图企业网站定制
ZenML Secrets 完整实战指南集中式密钥管理与 LLM/Agent 凭证安全实践【免费下载链接】zenmlZenML : One AI Platform from Pipelines to Agents. https://zenml.io.项目地址: https://gitcode.com/GitHub_Trending/ze/zenmlZenML 的 Secrets密钥机制是 AI 平台安全体系中连接管道、Stack 组件与外部服务的核心环节它以「名称 键值对」的形式把数据库口令、模型注册中心访问令牌以及 LLM API Key、第三方 Agent 工具凭证统一存放到安全的密钥存储中并通过{{SECRET_NAME.SECRET_KEY}}引用语法与 Python SDK 让管道和 Agent 无需硬编码即可安全取用。读完本文你将掌握使用 CLI 与 Python SDK 创建、查看、更新、删除密钥的完整操作理解公开/私有密钥的访问控制与同名查找优先级并能把密钥安全地注入 Stack 组件属性和 Step 中为传统 ML 工作流与 AI Agent 应用建立可落地的凭证管理方案。什么是 ZenML SecretZenML 官方文档对 Secret 的定义非常明确Secret 是一组「键值对」key-value pairs的集合安全地存储在 ZenML 的 secrets store密钥存储中并且每个 Secret 都有一个名称name用于在管道pipeline和 Stack 中获取或引用它。# 一个 Secret 的逻辑结构 { name: openai_secret, values: { api_key: sk-proj-..., organization_id: org-... } }Secret 同时服务两类典型场景传统 ML 工作流数据库凭据、模型注册中心如 MLflow访问认证等敏感信息AI Agent 开发LLM API Key、第三方服务搜索 API、天气 API 等凭证。从源码实现看Client 层通过create_secret方法把名称、键值对和可见性封装为SecretRequest模型提交给zen_store见 client.py存储层则由部署的 secrets store 后端如本地 SQLite、云端托管服务等负责落盘与加密。需要特别说明的是集中式密钥管理依赖 ZenML Server 的 secrets store 能力如果目标 ZenML 部署不支持或显式禁用了该功能调用会抛出NotImplementedErrorcentralized secrets management is not supported or explicitly disabled...这是使用本机制的前提条件。如何创建 Secret创建 Secret 有 CLI 与 Python SDK 两条路径两者能力对齐可任意混用。方式一CLI 创建zenml secret create是创建密钥的入口命令支持三种传参方式1. 直接以--KEYVALUE传参zenml secret create SECRET_NAME \ --KEY_1VALUE_1 \ --KEY_2VALUE_22. 使用--values传入 JSON/YAML 键值对zenml secret create SECRET_NAME \ --values{key1:value2,key2:value2}3. 实战示例为 LLM 与多 Agent 系统创建凭证# 为 OpenAI 创建 API 密钥 Secret zenml secret create openai_secret \ --api_keysk-proj-... \ --organization_idorg-... # 为 Anthropic 创建 API 密钥 Secret zenml secret create anthropic_secret \ --api_keysk-ant-api03-... # 为多 Agent 系统创建一组工具凭证 zenml secret create agent_tools_secret \ --google_search_api_keyAIza... \ --weather_api_keyabc123 \ --database_urlpostgresql://user:passhost/db # 创建私有 Secret仅创建者本人可访问 zenml secret create my_private_secret --private \ --api_keysecret-value4. 交互式创建值比较多或不想留在 shell 历史中时可用--interactive/-i参数进入交互会话ZenML 会逐个询问密钥名与值zenml secret create SECRET_NAME -i5. 从文件读取大值或含特殊字符的值对于过大或含特殊字符、不便作为命令行参数直接传递的值可以使用语法让 ZenML 从文件读取zenml secret create SECRET_NAME \ --keypath/to/file.txt \ ... # 或者把 JSON/YAML 键值对写入文件用 --valuespath 传入 zenml secret create SECRET_NAME \ --valuespath/to/file.txt从 CLI 源码看cli/secret.pycreate命令还隐含了若干重要细节--private/-p是is_flagTrue的布尔开关用于创建私有 Secret交互模式下不允许再同时传入--keyvalue参数二者互斥密钥名不能是name键也不能命名为name否则直接报错创建前会对每个键调用validate_keys校验并调用pretty_print_secret(..., hide_secretTrue)隐藏值地打印将要注册的 Secret如果同名 Secret 已存在会抛出EntityExistsError并提示创建失败。方式二Python SDK 创建ZenML Client 提供了程序化创建接口适合在初始化脚本、Notebook 或自动化流程中使用from zenml.client import Client client Client() # 基础用法 client.create_secret( namemy_secret, values{ username: admin, password: abc123 } ) # 示例程序化创建 LLM API 密钥 client.create_secret( nameopenai_secret, values{ api_key: sk-proj-..., organization_id: org-... } ) # 创建私有 Secret仅创建者本人可访问 client.create_secret( namemy_private_secret, values{api_key: secret-value}, privateTrue, )对应 SDK 签名client.pydef create_secret( self, name: str, values: Dict[str, str], private: bool False, ) - SecretResponse:private默认为False公开置为True即创建仅创建者可访问的私有 Secret。其他管理操作CLI 与 Client 还提供完整的生命周期管理命令操作CLIPython SDK获取zenml secret get name/prefix/idclient.get_secret(...)列出zenml secret listclient.list_secrets(...)更新zenml secret updateclient.update_secret(...)删除zenml secret deleteclient.delete_secret(...)其中list_secrets支持丰富的过滤与排序条件get_secret可按名称、ID 或名称/ID 前缀获取详见下文「同名 Secret 的获取顺序」。Size limits大小限制一个 ZenML Secret 本质上就是「名称 一组键值对」其大小通常按所有键和值的 UTF-8 总字节数计算。不同 secrets store 后端对该上限的约束不同。如果超出限制官方给出的三种处理策略新增一个命名 Secret把键分散到多个 Secret 中拆分键将大值按逻辑切分到不同键/不同 Secret大文件不要存入 ZenML只把文件路径或引用存放在某个值里。这种设计把「存储敏感的小凭证」与「存储大文件」的职责分离让密钥库始终轻量、可审计。私有与公开 SecretPrivate and public secrets可见性规则ZenML 的 Secret 分为两种可见性私有 Secretprivate仅创建者本人可查看、使用和管理无论其他用户的角色或权限如何都无法访问公开 Secretpublic默认其他用户依据你的RBAC基于角色的访问控制配置决定能否访问。在 ZenML Pro 上公开 Secret 的访问由角色权限设置管控。关键提示private属性的优先级高于 RBAC。即使 RBAC 本来允许某用户访问只要 Secret 是私有的它仍然只对创建者可见。创建私有 Secret默认创建的 Secret 是公开的privateFalse。要创建私有 Secret# CLI使用 --private 或短参数 -p zenml secret create SECRET_NAME --private \ --KEY_1VALUE_1 \ --KEY_2VALUE_2 # 短参数形式 zenml secret create SECRET_NAME -p \ --KEY_1VALUE_1# Python SDK from zenml.client import Client client Client() client.create_secret( namemy_private_secret, values{api_key: ...}, privateTrue, # 使该 Secret 变为私有 )注意目前设置私有状态仅支持 CLI 与 Python SDK 两种途径Dashboard 界面尚不支持创建或修改私有 Secret。同名 Secret 的获取顺序由于私有与公开 Secret 存在于相互独立的命名空间你可以同时拥有一个私有 Secret 和一个公开 Secret 且名称相同。当不带可见性条件按名称获取时ZenML先搜索私有 Secret再搜索公开 Secret返回第一个匹配项。从源码client.py可以看到未指定private时的搜索顺序被显式定义为search_private_statuses [False, True]即先查私有再查公开与文档描述完全一致。要显式获取指定可见性的同名 Secret# 显式获取私有 Secret zenml secret get my_secret --privatetrue # 显式获取公开 Secret zenml secret get my_secret --privatefalsefrom zenml.client import Client client Client() # 显式获取私有 Secret private_secret client.get_secret(my_secret, privateTrue) # 显式获取公开 Secret public_secret client.get_secret(my_secret, privateFalse)更新 Secret 的可见性创建后也可以随时调整可见性# 把公开 Secret 改为私有 zenml secret update my_secret --privatetrue # 把私有 Secret 改为公开 zenml secret update my_secret --privatefalsefrom zenml.client import Client client Client() client.update_secret(my_secret, update_privateTrue) # 改为私有在 Stack 组件属性与设置中引用 SecretStack 中的部分组件如 experiment tracker、orchestrator、model deployer 等需要配置口令或令牌才能连接底层基础设施。**Secret 引用secret references**让你不必把敏感值直接写进配置而是通过引用语法把值与 Secret 解耦。引用语法为{{SECRET_NAME.SECRET_KEY}}例如为 MLflow experiment tracker 注册带认证信息的组件# 先创建名为 mlflow_secret 的 Secret包含连接 MLflow tracking server # 所需的 username 和 password # 使用集中式密钥管理 zenml secret create mlflow_secret \ --usernameadmin \ --passwordabc123 # 然后在 experiment tracker 组件中引用 username 和 password zenml experiment-tracker register mlflow \ --flavormlflow \ --tracking_username{{mlflow_secret.username}} \ --tracking_password{{mlflow_secret.password}} \ ...从源码层面看这个机制由 secret_utils.py 实现_secret_reference_expression re.compile(r\{\{\s*\S?\.\S\s*\}\})负责识别形如{{name.key}}的引用字符串is_secret_reference判断某个属性值是否为 Secret 引用parse_secret_reference则把引用解析为SecretReference(name, key)结构stack_component.py 中的required_secrets属性会遍历组件配置收集所有被引用的 Secret作为后续校验的依据。管道运行前的 Secret 预校验当 Stack 中使用 Secret 引用时ZenML 会在运行管道前验证 Stack 组件中引用的所有 Secret 和键都存在。这样做的目的是「快速失败」——避免管道运行一段时间后才因缺失 Secret 而失败白白消耗算力与时间。默认情况下该校验需要读取每一个 Secret以确认 Secret 本身和指定的键值对都真实存在。这带来两个副作用一是校验可能耗时较长二是如果运行环境没有读取 Secret 的权限校验本身就会失败。为此 ZenML 提供环境变量ZENML_SECRET_VALIDATION_LEVEL来控制校验强度常量定义见 constants.py枚举定义见 enums.py取值行为NONE完全禁用校验SECRET_EXISTS仅校验 Secret 是否存在。适合运行机器只有列出 Secret 的权限、但没有读取其值的权限的场景SECRET_AND_KEY_EXISTS默认值既校验 Secret 存在也校验具体的键值对存在实现位于 stack.py 的_validate_secrets它读取环境变量缺省为SECRET_AND_KEY_EXISTS遍历required_secrets逐一通过client.get_secret(secret_ref.name)拉取 Secret在校验级别为SECRET_AND_KEY_EXISTS时还会访问secret.values[secret_ref.key]确认键存在。无法解析的引用会累积成错误信息最终抛出StackValidationError或在非致命模式下仅打 warning。错误提示中还会建议你运行zenml stack register-secrets STACK_NAME补齐缺失的 Secret——这正是下面要讲的辅助命令。交互式补齐 Stack 缺失的 Secret如果你的 Stack 里存在带 Secret 引用的组件运行管道前必须保证所有被引用的 Secret 都已注册。为此 ZenML 提供了zenml stack register-secrets [STACK_NAME]该命令会解析 Stack 的required_secrets实现在 cli/stack.py对每个缺失或需要更新的 Secret 以交互方式询问键值若传入--skip_existing已存在值的键会被跳过避免重复输入。不传STACK_NAME时默认处理当前激活的 Stack。在 Step 中获取 Secret 值使用集中式密钥管理时可以直接在 Step 内部通过 ZenML Client API 访问 Secret从而在调用外部 API 时不再把访问密钥硬编码进代码。这对 LLM Agent 类工作流尤其关键——API Key 只存于密钥库Step 代码可以安全地提交到版本库。from zenml import step from zenml.client import Client import openai step def secret_loader() - None: Load the example secret from the server. # 从 ZenML 获取 Secret secret Client().get_secret(SECRET_NAME) # secret.secret_values 是一个包含该 Secret 所有键值对的字典 authenticate_to_some_api( usernamesecret.secret_values[username], passwordsecret.secret_values[password], ) ... step def run_llm_agent(prompt: str, query: str) - str: 使用安全存储的 API 密钥执行 LLM Agent。 # 从 ZenML Secrets 获取 LLM API 凭据 openai_secret Client().get_secret(openai_secret) # 使用凭据初始化 OpenAI 客户端 from openai import OpenAI client OpenAI( api_keyopenai_secret.secret_values[api_key], organizationopenai_secret.secret_values[organization_id] ) # 执行 Agent response client.chat.completions.create( modelgpt-4, messages[ {role: system, content: prompt}, {role: user, content: query} ] ) return response.choices[0].message.content要点说明Client().get_secret(...)返回的SecretResponse对象通过secret_values属性暴露键值字典可直接按secret_values[key]取值取回的密钥只存在于运行时的进程内存中不会写入代码或日志配合前面的可见性控制可以做到「代码无密、凭据可审计」若部署环境未启用集中式密钥管理get_secret同样会抛出NotImplementedError需要先确认 ZenML Server 的 secrets store 已正确配置。小结ZenML Secrets 提供了从「创建 → 引用 → 校验 → 消费」的完整凭证管理闭环创建CLIzenml secret create支持--values、-i交互、file文件读取与 Python SDKclient.create_secret双通道可见性默认公开受 RBAC 管控--private创建仅创建者可访问的私有 Secret私有优先级高于 RBAC且二者命名空间独立、可按需显式获取引用Stack 组件属性用{{SECRET_NAME.SECRET_KEY}}语法解耦敏感配置配合zenml stack register-secrets交互补齐校验ZENML_SECRET_VALIDATION_LEVELNONE/SECRET_EXISTS/SECRET_AND_KEY_EXISTS精确控制管道运行前的预检强度实现快速失败消费Step 内通过Client().get_secret(...)动态取用支撑传统 ML 管道的数据库/模型仓库认证也支撑 LLM 与多 Agent 系统的 API 密钥管理。相关实现与文档入口核心 SDK 实现见 client.pyCLI 命令见 cli/secret.pyStack 预校验见 stack.py引用解析工具见 utils/secret_utils.py本文完整出处为 docs/book/how-to/secrets/secrets.md。【免费下载链接】zenmlZenML : One AI Platform from Pipelines to Agents. https://zenml.io.项目地址: https://gitcode.com/GitHub_Trending/ze/zenml创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价