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

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

问题描述

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



昨天我问此问题有关如何使用true引用YAML文件(其中包含API密钥)模块的路径。但是,这让我想到了其他方法;


  1. 请用户将API密钥保存为环境变量,并通过脚本检查所述变量的存在

  2. 让用户在创建对象的新实例时将API密钥作为** kwargs参数传递



    事物= CreateThing(user_key ='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa我想看看社区对此主题有何看法。

    解决方案


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


    即使是免费的 api -key ,则永远不要在代码中包含它,更不要将代码随它一起发布给公众。



    我的建议是不要在您的代码中包含任何秘密,甚至不要使用默认秘密,因为许多开发人员都喜欢通过调用从环境变量,配置文件,数据库或从中检索数据库的任何方式。



    在处理机密时,如果无法获取机密信息,则必须始终引发异常。再次,不要使用默认值



    我建议您阅读这篇文章我写过有关在代码中泄露机密的信息,以了解这样做的后果一个:


    例如,黑客可以使用公开的云凭据来启动服务器以进行比特币挖掘,发起DDOS攻击等,而您最终将成为支付账单的人,就像著名的我的$ 23 75 Amazon EC2错误 ...


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



    关于您建议的解决方案



    1. 要求用户将API密钥另存为环境变量,并让脚本检查该变量的存在

    2. 要求用户在创建对象的新实例时将API密钥作为** kwargs参数传递,例如



      thing = CreateThing( user_key ='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa是个不错的选择,您可以在此处使用点env文件方法,也许可以使用类似此版本的包。但是请记住,如果值不存在,请抛出一个异常,请不要使用代码中的默认值。



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



      安全呼叫注意



      在任何时候和提交 .env.example时都不能将env文件提交到源代码中,到您的git repo中,它不能包含任何默认值。



      哦,您可能会想,如果我不小心将其提交给Github,我会清理我的提交,重写历史记录并强制执行。好好三思,看看为什么这不能解决您创建的问题:


      好吧,我对您有坏消息……看来某些服务会缓存所有github提交,因此黑客可以检查这些服务或采用相同的技术在几秒钟内立即扫描发送到github的所有提交。


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



      还记得我之前引用的内容我的2375美元Amazon EC2错误 ,这是由于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天全站免登陆