当我推送到 GitHub 时如何处理秘密 API 密钥,以便在克隆存储库时我的项目仍然有效?

Posted

技术标签:

【中文标题】当我推送到 GitHub 时如何处理秘密 API 密钥,以便在克隆存储库时我的项目仍然有效?【英文标题】:How do I handle a secret API Key when I push to GitHub so that my project is still functional when the repo is cloned? 【发布时间】:2019-03-18 00:10:52 【问题描述】:

我有一个简单的项目,它向 API 端点发出 HTTP 请求并使用我想保密的 API 密钥。最初我将密钥放在它自己的文件中,将密钥导入到使用它的文件中,然后将密钥文件添加到 .gitignore 中。问题是,如果有人克隆 GitHub 存储库,这种方法将不起作用。

所以我的问题是 - 我怎样才能让我的 API 密钥保密,但如果有人克隆了 repo,我的项目仍然可以运行吗?

非常感谢任何反馈。

【问题讨论】:

在未定义的情况下提供有用的错误消息?如果它需要你没有提供的东西来工作,我看不出如果不提供这些东西它是如何工作的...... 我想你可能想要一个不需要身份验证的本地开发环境,或者你有一些模拟本地 api。 如果您允许其他人使用该应用程序并且该应用程序以某种方式可以访问该密钥,因为他们可以修改存储库代码以记录 API 密钥,则无法保证 API 密钥的安全 这是一个公共回购。这是作为工作申请的一部分的编码分配,我想表明我关心保持 API 密钥的秘密。 Should server/database config files, including passwords, be stored in source control?的可能重复 【参考方案1】:

最重要的是,永远不要添加它。如果你添加了它,提交了它,然后又删除了它,你仍然可以通过检查旧的提交来将它恢复为一个可以访问你的仓库的陌生人。

除此之外,你可以做什么:

明确地告诉用户他们需要获取和设置自己的 API 密钥,甚至可能告诉用户如何这样做。 在您的软件启动时添加一个检查,如果 API 密钥丢失,它会提供有用的错误消息,否则会启动您的实际程序 添加一个虚拟文件以显示应如何设置。我为我的电报聊天机器人做到了这一点:永远不要提交 secret.config,但要提交 sample_secret.config,这样任何分叉你的存储库的人都可以看到他需要使用什么语法。软件从不使用sample_secret.config,而不是 API 密钥包含类似 this-is-4-dummy-API-key-3232 或任何有意义的密钥。 创建第二个 API 密钥,该密钥有效但可以被公众滥用而不会出现任何问题。设置所有内容,使其适用于任一 API 密钥,并且只提交第二个。

【讨论】:

在这种情况下,应用程序将无法按照问题运行 当存储库公开时,它的功能应有尽有。更多的问题是“我如何在将密码提供给陌生人的同时保密我的密码?”除非我误解了什么 我不反对,但您的回答没有回答应用程序提出的问题,没有 API 密钥,物理上无法正常运行 @matthew257 我明白你的意思并添加了另一个想法。如果您有更多建议,我鼓励您在另一个答案中添加它们:) sample_secret.configsecret.config.sample 可能是更有用的名称。【参考方案2】:

我可以想象两种情况,要么您只在有限的一组计算机上自己使用此代码,要么您想发布人们可以使用的程序的编译版本。

如果您只在有限数量的计算机上使用它,那么您可能应该在这些计算机上“安装”秘密。有一些地方可以安全地存储它们并绑定到您的凭据/登录而不是公开的(例如,加密目录,或者如果您相信计算机/操作系统是安全的,则只是一个私有目录) Windows 有一个“凭据管理器" 加密并绑定到只有当您以该用户身份运行时才能访问的用户(它使用它来存储网络密码等)

如果您想发布已编译的应用程序——那么您当前的解决方案并不是非常好,因为您可以反编译应用程序并检索秘密。最好有一个“密钥”下载来存储附加到其凭据的秘密,如上所述。

【讨论】:

【参考方案3】:

您永远不应将 API 密钥提交到 GitHub 存储库。如果你已经提交了它,你可以删除它,但是一旦有人检查了提交历史,你仍然可以恢复它。您应该检查如何删除敏感数据here。

以下是处理 API 密钥的方法:

您可以告诉存储库的用户/访问者获取他自己的 API 密钥。您可以在自述文件中描述要编辑的文件以及如何使用。 您可以添加一个虚拟文件来显示如何设置它。您不应提交 .env 或 secret.config,但应根据具体情况提交 .env.sample 或 secret_sample.config。您可以在示例文件中使用诸如“Your_API_Key”之类的东西来代替真正的 API 密钥,这样一读就知道该怎么做。

但是,如果您正在运行一些 GitHub 操作来构建项目,该操作肯定会失败,因为它无法获取 API 密钥。这是我的工作:

将 API 密钥添加到存储库的机密中。每个存储库都有秘密,即使它们在运行时不可用,它们也会被 Github 操作视为环境变量。 将密钥添加到机密后,您应该编辑使用 API 密钥从环境中调用密钥的代码部分。假设我在 GitHub 机密中添加并保存 API 密钥为 api_key,以下是我在 dart 中的调用方式:
import 'dart:io' show Platform;

String apiKey = Platform.environment['api_key'];

您应该像使用任何选择的编程语言读取环境变量一样处理它。

添加到 GitHub 机密的 api_key 对任何人都不可用。 只有 repo 的贡献者可以访问并且可以检查秘密 因此,密钥对其他人是隐藏的,但可供他人使用 存储库的所有者/贡献者。

【讨论】:

以上是关于当我推送到 GitHub 时如何处理秘密 API 密钥,以便在克隆存储库时我的项目仍然有效?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Azure 文本翻译 API 时如何处理限制?

单元测试时如何处理 API 调用速率限制?

从 API 接收时如何处理 blob 存储 url

调用 REST API 时如何处理 Google Ads API 速率限制?

快速导航页面时如何处理HTTP api请求 |颤振 |镖

当我的应用程序激活时如何处理推送通知?