分发包时处理 API 密钥的 pythonic 方式是什么?

问题描述 投票:0回答:2

我创建了一个 Python 模块,我想通过 PyPI 分发它。它依赖于第三方 API,而第三方 API 又需要免费的 API 密钥。

昨天我问了这个问题关于如何使用模块的真实路径引用 YAML 文件(其中包含 API 密钥)。然而,这让我想到了其他方式;

  1. 要求用户将 API 密钥保存为环境变量,并让脚本检查该变量是否存在
  2. 在创建对象的新实例时,要求用户将 API 密钥作为 **kwargs 参数传入,例如

    thing = CreateThing(user_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', api_key = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')

我想看看社区对这个话题的看法。

python-3.x environment-variables yaml api-key
2个回答
2
投票

我创建了一个 Python 模块,我想通过 PyPI 分发它。它依赖于第三方 API,而第三方 API 又需要免费的 API 密钥。

即使是免费的

api-key
你也不应该在你的代码中使用它,更不用说将你的代码与它一起分发给公众。

我的建议是永远不要在你的代码中有任何秘密,甚至是默认秘密,因为许多开发人员喜欢在他们的调用中从环境变量、配置文件、数据库或他们从中检索它们的任何东西中获取值。

在处理秘密时,如果您未能获得秘密,则必须始终提出异常...再次不要使用代码中的默认值,即使以仅在开发和/或测试期间使用它们为借口也是如此。

我建议你阅读 这篇文章 我写了一篇关于在你的代码中泄露秘密的文章,以了解这样做的后果,就像这篇文章一样:

黑客可以,例如,使用暴露的云凭据来启动服务器以进行比特币挖掘、发起 DDOS 攻击等,而您将成为最终买单的人,就像著名的“我的 2375 美元亚马逊 EC2 错误”一样。 .

虽然这篇文章是在移动应用程序代码中泄露秘密的上下文中,但本文必须适用于我们编写并提交到存储库中的任何类型的代码。

关于您提出的解决方案

  1. 要求用户将 API 密钥保存为环境变量,并让脚本检查该变量是否存在
  2. 在创建对象的新实例时,要求用户将 API 密钥作为 **kwargs 参数传入,例如

    thing = CreateThing(user_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', api_key = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')

数字 1 是一个很好的,你应该在这里使用点环境文件方法,也许使用像 this one 这样的包。但请记住,如果值不存在,请引发异常,请不要使用代码中的默认值。

关于解决方案 2,对于使用您的库的开发人员来说更明确,但您也应该向他们推荐

.env
文件并帮助他们了解如何正确管理它们。例如,
.env
文件中使用的秘密应该从保险库软件中检索。

安全注意事项

Dot env 文件在任何时候都不能提交到源代码中,并且在提交

.env.example
到你的 git 仓库时,它不能包含任何默认值。

哦,你可能会想,如果我不小心将它提交到 Github,我只会清理我的提交,重写历史并强制推送。那么请三思而后行,看看为什么这不能解决您创建的问题:

我有个坏消息要告诉你……似乎有些服务缓存了所有 github 提交,因此黑客可以检查这些服务或使用相同的技术在几秒钟内立即扫描发送到 github 的任何提交。

来源:我在上面链接的博客文章。

并记住我之前引用的内容“我的 2375 美元 Amazon EC2 错误,这是由于 Github 意外提交中的凭据泄露。


1
投票

来自this answer:建议使用OS keyring。在我的 lib

odsclient
中,我最终实现了一系列替代方案,从最安全的(密钥环)到不太安全的(操作系统环境变量、git 忽略的文本文件、arg 传递的 apikey 可能被
getpass()
混淆) .

您可能希望寻找灵感,请特别参阅文档的这一部分

© www.soinside.com 2019 - 2024. All rights reserved.