分发包时处理API密钥的pythonic方法是什么? [英] What is the pythonic way to deal with API keys when distributing a package?

查看:28
本文介绍了分发包时处理API密钥的pythonic方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

    thing = CreateThing(user_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa', api_key = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbb')

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

解决方案

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

即使是一个免费的api-key,您也不应该在您的代码中使用它,更不用说将您的代码与它一起分发给公众了.

我的建议是永远不要在您的代码中设置任何机密,甚至不要使用默认机密,因为许多开发人员喜欢在他们的调用中放入从环境变量、配置文件、数据库或任何他们从中检索值的调用中获取值.

处理秘密时,您必须始终在无法获得时引发异常……再次,不要使用代码中的默认值,即使借口仅在开发和/或期间使用它们也是如此测试.

我建议您阅读我写的这篇文章关于泄露代码中的秘密以了解这样做的后果,例如:

<块引用>

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

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

关于您提出的解决方案

<块引用>

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

    thing = CreateThing(user_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa', api_key = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbb')

数字 1 很好,你应该在这里使用 dot env 文件方法,也许使用像 这个.但请记住,如果值不存在,请引发异常,请不要使用代码中的默认值.

关于解决方案 2,对于使用您的库的开发人员来说更为明确,但您也应该向他们推荐 .env 文件并帮助他们了解如何正确管理它们.例如,用于 .env 文件的机密应该从保险库软件中检索.

安全警告

点 env 文件在任何时候都不能提交到源代码中,并且在将 .env.example 提交到您的 git 存储库时,它不能包含任何默认值.

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

<块引用>

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

>

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

记住我之前引用的内容我在 Amazon EC2 上犯了 2375 美元的错误,这是由于意外的 Github 提交导致凭据泄露.

I have created a Python module which I would like to distribute via PyPI. It relies on a third party API which in turn requires a free API key.

Yesterday I asked this question on how to reference a YAML file (which would contain the API keys) using the true path of the module. However that got me thinking of other ways;

  1. Ask the users to save the API key as an environment variable and have the script check for the existence of said variable
  2. Ask the user to pass in the API key as an **kwargs argument when creating a new instance of the object e.g.

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

I would like to see what the community thinks on this topic.

解决方案

I have created a Python module which I would like to distribute via PyPI. It relies on a third party API which in turn requires a free API key.

Even being a free api-key you should never have it in your code, even less have your code distributed to the public with it.

My advice is to never have any secrets on your code, not even default secrets as many developers like to put in their calls to get values from environment variables, configuration files, databases or whatsoever they retrieve them from.

When dealing with secrets you must always raise an exception when you fail to obtain one... Once more don't use default values from your code, not even with the excuse that they will be used only during development and/or testing.

I recommend you to read this article I wrote about leaking secrets in your code to understand the consequences of doing so, like this one:

Hackers can, for example, use exposed cloud credentials to spin up servers for bitcoin mining, for launching DDOS attacks, etc and you will be the one paying the bill in the end as in the famous "My $2375 Amazon EC2 Mistake"...

While the article is in the context of leaking secrets in the code a mobile app, must of the article applies to any type of code we write and commit into repositories.

About your proposed solution

  1. Ask the users to save the API key as an environment variable and have the script check for the existence of said variable
  2. Ask the user to pass in the API key as an **kwargs argument when creating a new instance of the object e.g.

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

The number 1 is a good one and you sould use here the dot env file approach, maybe using a package like this one. But remember to raise an exception if the values does not exist, please never use defaults from your code.

Regarding solution 2 it is more explicit for the developer using your library, but you should recommend also them the .env file and help them understand how to properly manage them. For example secrets used on .env files should be retrieved from a vault software.

A SECURITY CALL OF ATTENTION

Dot env files cannot be committed into the source code at any time and when committing the .env.example, into your git repo, it must not contain any default values.

Oh you may think if I commit it accidentally to Github I will just clean my commits, rewrite the history and do a force push. Well think twice and see why that will not solve the problem you have created:

Well I have bad news for you... it seems that some services cache all github commits, thus hackers can check these services or employ the same techniques to immediately scan any commit sent to github in a matter of seconds.

Source: the blog post I linked above.

And remember what I have quoted earlier "My $2375 Amazon EC2 Mistake, that was due to leaked credentials in an accidental Github commit.

这篇关于分发包时处理API密钥的pythonic方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆