Encrypting secrets with python
- 2019-05-10
- π Python
- Python
0. Intro
While working at AM Managers
project we encountered some difficulties. We were a team of around 8 people and it was common to have internship every some months. So we regularly needed to help new people to set up all the tools needed at that project.
It was also common that we wanted to include new passwords when we started using new tools like new APIs or new DB. At the begining we were creating env vars for each password but every time someone added a new password all the time were forced to include it as a new env var.
1. Dictionary of passwords
Then we decided to create a dictionary of encrypted passwords that we could track with git along with one master password as an env var.
After starting to have some EC2 instances we discoverd that it was easier for us to have a file with the master password than an env var.
2. The v-crypt package
After having the same problem with more projects I decided that it was better to create a new python package that could help me dealing with that instead of copying the code from the AM Managers
repository all the time.
The idea behind this module is to be able to create a json
or yaml
with encrypted secrets. The keys will be public but the values wonβt. This way you can store the dictionary of secrets in git and easily share them with other people working in the same project. You will only need to share the master.password
once. And all the other passwords/secrets will be tracked with git.
It uses Fernet from the Cryptography module. This is a secure and tested way of encrypting information.
2.1 How it works
It is really easy to use:
from v_crypt import Cipher
# Create a cipher instance
cipher = Cipher()
# Create a new master password
cipher.create_password()
# Store a secret
cipher.save_secret("secret", "I like python")
# Retrive a secret
cipher.get_secret("secret")
2.2. Customization
There are three paramaters to customize the cipher:
- secrets_file: path of the file with secrets. Can be a
json
oryaml
. - filename_master_password: path of the file with the master password
- environ_var_name: if passed it allows to read the master password from an environ var.
For yaml
you need to install pyyaml
For example you could do:
cipher = Cipher(secrets_file="data/secrets.yaml", filename_master_password="data/master.secret")
This will allow you to store both the master.password
and secrets.yaml
in the folder data
.
There is not much more customization since the idea is to keep it simple.
2.3. How we use it
We usually have one or more python files with utilities, for example utilities.py
.
To use v_crypt we initiallize the cipher
there and then create a get_secret
dummy function that will call the cipher.
utilities.py
from v_crypt import Cipher
cipher = Cipher(secrets_file="data/secrets.yaml", filename_master_password="data/master.secret")
def get_secret(key):
return cipher.get_secret(key)
Then you can use it elsewhere with:
import utilities as u
u.get_secret("secret")
Remember to add master.password
to the gitignore. Or you can use the rule *.password
to ignore all files with password
extension.