相关动态
如何在命令行中安全存取密钥信息:以 OpenAI API 密钥为例
2024-12-26 10:21

AI 的持续火热带动了很多人尝鲜的兴趣。而要使用目前大量涌现的 AI 项目,一个非常普遍的前提条件就是填入自己的 API 密钥,从而调用 OpenAI 等商业服务提供的模型。

如何在命令行中安全存取密钥信息:以 OpenAI API 密钥为例

这就产生了如何有效管理和取用 API 密钥的问题。由于密钥都是随机而冗长的,当然不可能像密码那样凭记忆输入。网页端工具倒是可以用浏览器或第三方软件的密码管理功能填写;但很多 AI 工具都需要在命令行下运行。例如,OpenAI 的官方命令行工具、以及很多调用 GPT 的 Docker 项目,都要求将 OpenAI API 密钥作为环境变量才能运行。

对此,如果每次都临时复制粘贴,不仅非常麻烦,还会在终端历史记录中留下明文密钥内容,不符合安全原则。

OpenAI 的一篇帮助文档谈及了这个问题,指出可以将密钥内容存储在终端配置文件(例如 )中;类似地,Docker 也支持通过 等外部文件传入环境变量。但这只能解决问题的一半,仍然会导致密钥内容的明文存储。这种问题做法导致的安全隐患,正是 GitHub 提供仓库密文扫描功能的背景。

实际上,通过合理利用内置功能或借助第三方工具,就能用加密存储代替明文密钥,达到兼顾安全和便捷的目的。下面,我们就以存储和调用 OpenAI API 密钥为例,说明不同平台上的解决方案。当然,这些方法也适用于在命令行环境中存取任何登录密码或其他凭据信息。

如果你是苹果「全家桶」用户,习惯用系统自带的密码管理功能,大概知道可以通过内置的「钥匙串访问」(Keychain Access,位于 目录下)查看和管理密码。

所谓「钥匙串」,是指 macOS 用来加密存储凭据信息的容器,除了网站密码,还包括已登录 WiFi 的密码、第三方证书等。

但较少有人知道的是,并不是只有 Safari 浏览器或适配了钥匙串的第三方应用可以写入钥匙串,用户自己也可以手动添加任何想要加密保存的信息。

其中,、 和 三个必填项分别用来指定服务名称、用户名和密码。 是可选的,指该钥匙串项目的类型。

例如,如果想添加一条存储 OpenAI API 密钥的安全备注,可以运行:

这里,我们用 选项指定类型为 secure note,即安全备注(填写用户名对于安全备注其实是多余的,只是因为 不够灵活的语法要求才不得不填一个)。

就会返回密钥的原文。

你可能会疑问为什么这个操作不需要任何授权。其实,根据钥匙串的规则,访问其内容一般确实需要密码,但一个程序访问它自己添加的内容除外。我们之前就是通过 命令添加的钥匙串,因此再用 命令来搜索和获取其内容,可以免输密码。

进一步延伸,但凡需要用到 OpenAI API 密钥的地方,都可以换成包含上述命令的subshell,即 。

例如,如果要为终端添加环境变量 ,只用在 (或你所用其他终端的配置文件)中加入:

这就避免了在配置文件中包含明文密钥。

类似地,在运行 Docker 等需要传递 API 密钥作为环境变量的场合,也可以用上述 subshell 代替密钥明文,例如

就会将密钥内容作为 变量传给将要运行的 。

与 macOS 不同,常见的 Linux 发行版没有统一的内置凭据管理工具,但绝大多数发行版的官方软件源都收录了 (全称为 password-store)这款命令行工具。这也是被广泛推荐、符合 UNIX 简洁风格的解决方案。因此,本文也选择它作为 Linux 下的推荐方案来演示。

使用 之前需要先安装:

(更多发行版的安装方式参见官网说明。)

使用 GPG 密钥对来加密存储的信息。为此,需要首先生成一个 GPG 密钥:

(如果你不清楚自己是否已经为别的用途生成过 GPG 密钥,可以运行 来确认。)

根据界面提示选择密钥类型和有效期等设置(都可以回车直接使用默认值),并输入用户名、邮箱和口令等信息,看到如下输出即表明创建成功。

然后用如下命令初始化 的存储库:

这里的 可以是之前生成密钥时使用的邮箱地址,也可以是 Key ID,即上述输出信息第二行(称为 fingerprint)的最后 8 个(或 16 个,分别称为 Short ID 和 Long ID)字符,即 。因为一个邮箱可以创建多个密钥,为了避免混淆,建议优先使用 Key ID。

这时,就可以通过如下命令存储 OpenAI API 密钥:

根据提示输入 API 密钥并回车确认。

实际上将凭据加密后存储在 路径,而上面的 指的就是凭据在该目录中的存储路径,一般可以使用 的结构,便于后续查询,但你当然也可以用自己习惯的结构来整理。

你可以通过运行 命令来确认添加完成,输出应该类似于:

与上面 macOS 的例子类似,此后就可以通过运行 来获得 API 密钥内容,或者用 来代替对密钥的明文引用。

我不太确定这段是不是多此一举,因为……可能没有多少人有闲情雅致去直接用 PowerShell 折腾 Python 和 Docker?总之,这里只简单说明可行方案,供有兴趣的读者自行探索。

首先,Windows 上确实有类似于 macOS「钥匙串访问」的功能,称为「凭据管理器」(Credential Manager)。当年,IE 浏览器的密码保存功能就是调用凭据管理器存储的。

此外,微软后来又开发了一个 PowerShell 模块 SecretManagement,功能非常类似于上面介绍的 ,而且可以通过插件支持 1Password、KeePass 等大量第三方格式的密码库,目前一直保持开发。

这篇文章介绍了如何安装和使用:PowerShell SecretManagement Module: Securely Manage Credentials and Secrets (WindowsOSHub)。

上面介绍的方案仍然有一个缺点:不支持同步。其中, 命令只能访问 macOS 本地的钥匙串,而不支持 iCloud 钥匙串。 虽然在设计上就考虑了用户使用 git 等工具同步的需求,但对于大多数人显然还是麻烦了。

其实,如果你正好在用 1Password 作为密码管理工具,使用它的命令行版本 1Password CLI 就可以兼顾安全和同步。这个工具不仅可以访问云端同步的 1Password 密码库,而且有很多考虑到开发环境实际需要的细节功能,比 和 用起来更方便。

(虽然 1Password 之前转订阅制被普遍批评不厚道,但好歹是把收入继续投入在了持续开发上。)

1Password CLI 支持多个平台。在 macOS 上,可以用 安装;Linux 可以直接下载预编译的可执行文件到 中,也可以添加 1Password 维护的软件源,然后通过 apt 或 dnf 安装(具体参考 1Password 文档)。

从 1Password CLI 读取密码主要有两种方法。第一种是使用 子命令,例如:

这种方法比较像搜索,好处是语法简单,但不太精确,在有多个类似名称账户的场合容易混淆。

因此,对于 API 密钥这种需要准确引用的场合,建议使用 子命令结合「密文引用链接」(secret reference)来读取。Secret reference 在形式上类似于自动化玩家熟悉的 URL Scheme,其结构为:

获取 API 密钥的内容。

但与上述 macOS 的例子不同,注意尽量不要直接在配置文件中用 subshell 的形式调用 命令,即不要在 ZSH 配置文件中这样写:

这是因为 1Password CLI 访问密码库有数秒的延迟,隔一段时间还需要重新验证一次;将其放在终端启动阶段执行是毫无必要的拖慢。

作为替代,我们可以利用 命令的另一功能,换成这样的写法:

也就是直接将引用链接作为环境变量。

这样,每逢遇到需要调用 OpenAI API 密钥的命令时,只要在其之前添加 ,1Password 就会 (1) 先将引用链接解析为实际密钥内容,然后 (2) 作为同名环境变量的值传递给要运行的命令。

例如,如果要使用 OpenAI 官方命令行工具列举当前可用的模型列表,就可以运行:

除了填充环境变量, 命令还可以用来解析配置文件或脚本中的引用链接。

例如,你准备部署一个提供了 Docker Compose 文件的项目,使用说明要求在外部文件 中提供 OpenAI 密钥。那么,你可以不用在其中填写实际密钥内容,而是填写:

然后,在部署时运行:

    以上就是本篇文章【如何在命令行中安全存取密钥信息:以 OpenAI API 密钥为例】的全部内容了,欢迎阅览 ! 文章地址:http://yybeili.xhstdz.com/quote/85640.html 
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 物流园资讯移动站 http://yybeili.xhstdz.com/mobile/ , 查看更多   
发表评论
0评