Giter Site home page Giter Site logo

envkey / envkey-python Goto Github PK

View Code? Open in Web Editor NEW
24.0 5.0 6.0 77.24 MB

EnvKey's python library. Protect API keys and credentials. Keep configuration in sync.

Home Page: https://www.envkey.com

License: MIT License

Python 97.52% Makefile 2.48%
python python2 python3 configuration configuration-management secrets security-tools devops devops-tools developer-tools security encryption django environment-variables secret-management

envkey-python's Introduction

envkey-python

Integrate EnvKey with your Python projects to keep API keys, credentials, and other configuration securely and automatically in sync for developers and servers.

Compatible with Python 2 and 3.

v2

Now that EnvKey v2 has been released, you can find version 2 of this package here.

Using v2 requires an EnvKey v2 organization (it won't work with ENVKEYs generated in a v1 org).

Here's a guide on migrating from v1 to v2.

To continue using version 1 of this package, make sure you specify ==1.* when installing with pip so that you don't accidentally install v2.

Installation

$ pip install envkey==1.*

Then at the entry point of your application:

import envkey

For Django, you should put the above in manage.py and wsgi.py. Also see the note on casting below if you're migrating from django-environ.

Usage

Generate an ENVKEY in the EnvKey App. Then set ENVKEY=..., either in a gitignored .env file in the root of your project (in development) or in an environment variable (on servers).

Now all your EnvKey variables will be available in os.environ.

Or as a bit of syntactic sugar to avoid needing to always import os alongside envkey, you can call envkey.get, which delegates to os.environ.get. For example:

import envkey

my_var = envkey.get("SOME_ENVKEY_VAR")

Errors

The package will throw an error if an ENVKEY is missing or invalid.

Example

Assume you have STRIPE_SECRET_KEY set for the development environment in the EnvKey App. You generate a local development ENVKEY.

In your project's gitignored .env file:

# .env
ENVKEY=GsL8zC74DWchdpvssa9z-nk7humd7hJmAqNoA

In app.py:

stripe.api_key = os.environ['STRIPE_SECRET_KEY']

Or using the envkey.get sugar:

stripe.api_key = envkey.get('STRIPE_SECRET_KEY')

Now STRIPE_SECRET_KEY will stay automatically in sync for all the developers on your team.

For a server, generate a server ENVKEY in the EnvKey App, then set the ENVKEY as an environment variable instead of putting it in a .env file.

Now your servers will stay in sync as well. If you need to rotate your STRIPE_SECRET_KEY you can do it in a few seconds in the EnvKey App, restart your servers, and you're good to go. All your team's developers and all your servers will have the new value.

Overriding Vars

This package will not overwrite existing environment variables or additional variables set in a .env file. This can be convenient for customizing environments that otherwise share the same configuration. You can also use sub-environments in the EnvKey App for this purpose.

Working Offline

This package caches your encrypted config in development so that you can still use it while offline. Your config will still be available (though possibly not up-to-date) the next time you lose your internet connection. If you do have a connection available, envkey will always load the latest config. Your cached encrypted config is stored in $HOME/.envkey/cache

For caching purposes, it's assumed you're in development mode when a .env file exists in the root of your project.

Disabling autoload

If you'd like to have more control over how your config is loaded, you can prevent the package from auto-loading on import by setting ENVKEY_DISABLE_AUTOLOAD=1 either in your .env file or as an environment variable.

You can then load your config explicitly like this:

import envkey

envkey.load(cache_enabled=True, dot_env_enabled=True, dot_env_path=".env")

For even more flexibility, you can just fetch your config as a dict (without setting it on os.environ) like this:

import envkey
import os

config = envkey.fetch_env(os.environ['ENVKEY'], cache_enabled=True)

django-environ casting

If you happen to be migrating from django-environ to EnvKey, watch out for the fact that EnvKey does not cast variables to booleans or any other non-string types as django-environ does. All variables set by EnvKey will be strings in accordance with the cross-platform environment variable standard. See: https://twitter.com/manishsinhaha/status/1265746057377361921

envkey-fetch binaries

If you look in the ext directory of this package, you'll find a number of envkey-fetch binaries for various platforms and architectures. These are output by the envkey-fetch Go library. It contains EnvKey's core cross-platform fetching, decryption, verification, web of trust, redundancy, and caching logic. It is completely open source.

x509 error / ca-certificates

On a stripped down OS like Alpine Linux, you may get an x509: certificate signed by unknown authority error when this package attempts to load your config. envkey-fetch tries to handle this by including its own set of trusted CAs via gocertifi, but if you're getting this error anyway, you can fix it by ensuring that the ca-certificates dependency is installed. On Alpine you'll want to run:

apk add --no-cache ca-certificates

Further Reading

For more on EnvKey in general:

Read the docs.

Read the integration quickstart.

Read the security and cryptography overview.

Need help? Have questions, feedback, or ideas?

Post an issue or email us: [email protected].

envkey-python's People

Contributors

danenania avatar drcongo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

envkey-python's Issues

envkey-fetch_X.X.X_linux_arm64 missing from `ext/`

Hello.

Now that I finally have an Apple silicon Mac, I've been experimenting with trying to get various projects running on it. For projects where we build an arm64 Ubuntu Docker container, and install the EnvKey Python package, running the project / tests fails with this stacktrace:

Traceback (most recent call last):
  File "manage.py", line 6, in <module>
    import envkey  # NOQA
  File "/usr/local/lib/python3.8/dist-packages/envkey/__init__.py", line 7, in <module>
    load(is_init=True)
  File "/usr/local/lib/python3.8/dist-packages/envkey/loader.py", line 26, in load
    fetch_res = fetch_env(key, cache_enabled=cache_enabled)
  File "/usr/local/lib/python3.8/dist-packages/envkey/fetch.py", line 55, in fetch_env
    res = subprocess.check_output(args).decode(encoding="utf-8").rstrip()
  File "/usr/lib/python3.8/subprocess.py", line 415, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/usr/lib/python3.8/subprocess.py", line 493, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.8/subprocess.py", line 858, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1704, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/envkey/ext/envkey-fetch_1.2.9_linux_arm64/envkey-fetch'

I've experimented a little, and found that I can install and run envkey-fetch manually inside the container (presumably this installs the linux_arm64 version), but the python package doesn't use the one on the path. Obviously the easiest fix here is to include the linux_arm64 envkey-fetch inside ext/ - if that's a bad idea for reasons that I'm unaware of, I'd be happy to open a PR that tries to fall back to an envkey-fetch executable on the path.

Multiple envkeys on the same server

What would be the correct way of running multiple envkeys on the same server and avoiding environment variable clashes?
For example, APP1 uses ENVKEY_APP1 and APP2 uses ENVKEY_APP2. I don't have any problems running the apps in isolation, however, once there are ENVKEY variable clashes between these two apps there is the problem of precedence when importing envkey.
The same variable, say DATABASE_NAME gets rewritten if the APP1 is still running and APP2 imports ENVKEY_APP2 with a different value for DATABASE_NAME.

envkey does not work in AWS Lambda

We are using Chalice to package a Hello World + ENVKEY app and run it as a lambda function. The deployment goes fine. I confirmed that the Lambda function has a correct ENVKEY value:

image

I also confirmed that Chalice successfully bundles envkey into our zip file which is used to create the lambda function. However, when I invoke the function, I get this exception:

  File \"/var/lang/lib/python3.7/imp.py\", line 234, in load_module\n    return load_source(name, filename, file)
  File \"/var/lang/lib/python3.7/imp.py\", line 171, in load_source\n    module = _load(spec)
  File \"<frozen importlib._bootstrap>\", line 696, in _load
  File \"<frozen importlib._bootstrap>\", line 677, in _load_unlocked
  File \"<frozen importlib._bootstrap_external>\", line 728, in exec_module
  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed
  File \"/var/task/app.py\", line 14, in <module>\n    import envkey
  File \"/var/task/envkey/__init__.py\", line 4, in <module>\n    load(is_init=True)
  File \"/var/task/envkey/loader.py\", line 25, in load\n    fetch_res = fetch_env(key, cache_enabled=cache_enabled)
  File \"/var/task/envkey/fetch.py\", line 46, in fetch_env\n    res = subprocess.check_output(args).decode().rstrip()
  File \"/var/lang/lib/python3.7/subprocess.py\", line 395, in check_output\n    **kwargs).stdout
  File \"/var/lang/lib/python3.7/subprocess.py\", line 472, in run\n    with Popen(*popenargs, **kwargs) as process:
  File \"/var/lang/lib/python3.7/subprocess.py\", line 775, in __init__\n    restore_signals, start_new_session)
  File \"/var/lang/lib/python3.7/subprocess.py\", line 1522, in _execute_child\n    raise child_exception_type(errno_num, err_msg, err_filename)

It appears as though envkey wants to do some caching on the local filesystem? This is not possible as Lambda does not allow it.

Yet, the nodejs envkey library deploys to AWS Lambda flawlessly on the first attempt. Is it possible for the python implementation do function the same way?

Feature suggestion: add a get function to the main envkey module

I find in my projects I'm using a pattern like this to access the vars from envkey...

import os
import envkey  # NOQA

FOO = os.environ.get('FOO')

Two things bother me about this, one is that I need to add # NOQA so that Flake8 doesn't get upset about an unused import, and the other is that there's an extra import of os or os.environ. It feels like it would make sense to be able to do this instead...

import envkey

FOO = envkey.get('FOO')

with envkey just passing on the call to os.environ's get.

Happy to do this as a PR if you like the idea.

ValueError: ENVKEY invalid. Couldn't load vars.

Hello,
I am using python 3.6 and I have my file in the root folder of my Django project. I have the ENVKEY="" inside the .env and this file's name is inside .gitignore. I do try running my server or doing ipython, everytime i do import envkey the following error trace pops up.

/opt/bitnami/python/lib/python3.6/site-packages/envkey/loader.py in load(is_init, cache_enabled, dot_env_enabled, dot_env_path)
     23     raise ValueError("ENVKEY missing - must be set as an environment variable or in a gitignored .env file in the root of your project. Go to https://www.envkey.com if you don't know what an ENVKEY is.")
     24 
---> 25   fetch_res = fetch_env(key, cache_enabled=cache_enabled)
     26 
     27   vars_set = dict()

/opt/bitnami/python/lib/python3.6/site-packages/envkey/fetch.py in fetch_env(key, cache_enabled)
     45 
     46   if res.startswith("error: "):
---> 47     raise ValueError("ENVKEY invalid. Couldn't load vars.")
     48 
     49   return json.loads(res)

ValueError: ENVKEY invalid. Couldn't load vars.
```
I have Django 2.1, python3.6, Ubuntu 16.04. My project is hold by an Apache2 server .

AWS glue job instance :[Errno 20] Not a directory

Hi,

I am trying to use envkey in my AWS Glue script. AWS sets up the running environment as a container. The ETL job only accepts one python file defining the job contents to be run so I have to pass the envkey + python-dotenv libraries contents as a zip. I am passing the envkey value as a param to the script and using the following function to load the envkey variables:

def load_envkey_values(envkey_value):
    import os
    os.environ['ENVKEY'] = envkey_value
    import envkey
    print("TESTING BQ_DATASET_TABLE:{}".format(os.environ['BQ_DATASET_TABLE']))

I am encountering [Errno 20] Not a directory:

Traceback (most recent call last):
File "script_2019-04-02-08-21-59.py", line 564, in <module>
main()
File "script_2019-04-02-08-21-59.py", line 491, in main
load_envkey_values(args['envkey'])
File "script_2019-04-02-08-21-59.py", line 151, in load_envkey_values
import envkey
File "/mnt/yarn/usercache/root/appcache/application_1554193162735_0001/container_1554193162735_0001_01_000001/libraries.zip/envkey/__init__.py", line 4, in <module>
File "/mnt/yarn/usercache/root/appcache/application_1554193162735_0001/container_1554193162735_0001_01_000001/libraries.zip/envkey/loader.py", line 25, in load
File "/mnt/yarn/usercache/root/appcache/application_1554193162735_0001/container_1554193162735_0001_01_000001/libraries.zip/envkey/fetch.py", line 46, in fetch_env
File "/usr/lib64/python2.7/subprocess.py", line 567, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
OSError: [Errno 20] Not a directory

Any help or explanation/insights into why this error occurred would be greatly appreciated.
... I am not even sure if I can even use envkey with AWS glue...

Does this work with EnvKey v2?

I see some references to envkey v1 in the readme, I tried to use it on v2 and it kinda works. But the API is different for loading. Where should I look for documentation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.