Encrypt Configuration
Configuration
Method 1: Encrypt and decrypt with key file and Fernet
When you work in multiple environments: local, dev, testing, production... you must set critical configuration in your variables, such as:
config.yml, for local propose:
pyms:
  config:
    DEBUG: true
    TESTING: true
    APPLICATION_ROOT : ""
    SECRET_KEY: "gjr39dkjn344_!67#"
    SQLALCHEMY_DATABASE_URI: mysql+mysqlconnector://user_of_db:user_of_db@localhost/my_schema
config_pro.yml, for production environment:
pyms:
  config:
    DEBUG: true
    TESTING: true
    APPLICATION_ROOT : ""
    SECRET_KEY: "gjr39dkjn344_!67#"
    SQLALCHEMY_DATABASE_URI: mysql+mysqlconnector://important_user:****@localhost/my_schema
We strongly recommend this way of encrypting/decrypting your configuration, but if you don't want a vendor locking option, or you don't have the resources to use these methods, we provide a way to encrypt and decrypt your variables.
1. Generate a key
PyMS has a command line option to create a key file. This key is created with AES. You can run the next command in the terminal:
pyms create-key
Then, type a password and it will create a file called key.key. This file contains a unique key. If you loose this file
and re-run the create command, the key hash will be different and your code encrypted with this key won't be able to be decrypted.
Store this key in a secure site, and DO NOT COMMIT it to your repository.
2. Add your key to your environment
Move your key, for example, to mv key.key /home/my_user/keys/myproject.key
then, store the key in a environment variable with:
export PYMS_KEY_FILE=/home/my_user/keys/myproject.key
3. Encrypt your information and store it in config
Do you remember the example file config_pro.yml? Now you can encrypt and decrypt the information, you can run the command
pyms encrypt [string] to generate a crypt string, for example:
pyms encrypt 'mysql+mysqlconnector://important_user:****@localhost/my_schema'
>>  Encrypted OK: b'gAAAAABeSwBJv43hnGAWZOY50QjBX6uGLxUb3Q6fcUhMxKspIVIco8qwwZvxRg930uRlsd47isroXzkdRRnb4-x2dsQMp0dln8Pm2ySHH7TryLbQYEFbSh8RQK7zor-hX6gB-JY3uQD3IMtiVKx9AF95D6U4ydT-OA=='
And store this string in your config_pro.yml:
pyms:
  crypt:
    method: "fernet"
  config:
    DEBUG: true
    TESTING: true
    APPLICATION_ROOT : ""
    SECRET_KEY: "gjr39dkjn344_!67#"
    ENC_SQLALCHEMY_DATABASE_URI: gAAAAABeSwBJv43hnGAWZOY50QjBX6uGLxUb3Q6fcUhMxKspIVIco8qwwZvxRg930uRlsd47isroXzkdRRnb4-x2dsQMp0dln8Pm2ySHH7TryLbQYEFbSh8RQK7zor-hX6gB-JY3uQD3IMtiVKx9AF95D6U4ydT-OA==
Do you see the difference between ENC_SQLALCHEMY_DATABASE_URI and SQLALCHEMY_DATABASE_URI? In the next step you
can find the answer
4. Decrypt from your config file
Pyms knows if a variable is encrypted if this var start with the prefix enc_ or ENC_. PyMS searches for your key file
in the PYMS_KEY_FILE env variable and decrypts this value to store it in the same variable without the enc_ prefix, 
for example, 
ENC_SQLALCHEMY_DATABASE_URI: gAAAAABeSwBJv43hnGAWZOY50QjBX6uGLxUb3Q6fcUhMxKspIVIco8qwwZvxRg930uRlsd47isroXzkdRRnb4-x2dsQMp0dln8Pm2ySHH7TryLbQYEFbSh8RQK7zor-hX6gB-JY3uQD3IMtiVKx9AF95D6U4ydT-OA==
Will be stored as
SQLALCHEMY_DATABASE_URI: mysql+mysqlconnector://user_of_db:user_of_db@localhost/my_schema
And you can access this var with current_app.config["SQLALCHEMY_DATABASE_URI"]
Method 2: Encrypt and decrypt with AWS KMS
1. Configure AWS
Pyms knows if a variable is encrypted if this var start with the prefix enc_ or ENC_. PyMS uses boto3 and
aws cli to decrypt this value and store it in the same variable without the enc_ prefix.
First, configure aws your aws account credentials:
aws configure
2. Encrypt with KMS
Cypher a string with this command:
aws kms encrypt --key-id alias/prueba-avara --plaintext "mysql+mysqlconnector://important_user:****@localhost/my_schema" --query CiphertextBlob --output text
>>  AQICAHiALhLQv4eW8jqUccFSnkyDkBAWLAm97Lr2qmdItkUCIAF+P4u/uqzu8KRT74PsnQXhAAAAoDCBnQYJKoZIhvcNAQcGoIGPMIGMAgEAMIGGBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDPo+k3ZxoI9XVKtHgQIBEIBZmp7UUVjNWd6qKrLVK8oBNczY0CfLH6iAZE3UK5Ofs4+nZFi0PL3SEW8M15VgTpQoC/b0YxDPHjF0V6NHUJcWirSAqKkP5Sz5eSTk91FTuiwDpvYQ2q9aY6w=
3. Decrypt from your config file
And put this string in your config_pro.yml:
pyms:
  crypt:
    method: "aws_kms"
    key_id: "alias/your-kms-key"
  config:
    DEBUG: true
    TESTING: true
    APPLICATION_ROOT : ""
    SECRET_KEY: "gjr39dkjn344_!67#"
    ENC_SQLALCHEMY_DATABASE_URI: "AQICAHiALhLQv4eW8jqUccFSnkyDkBAWLAm97Lr2qmdItkUCIAF+P4u/uqzu8KRT74PsnQXhAAAAoDCBnQYJKoZIhvcNAQcGoIGPMIGMAgEAMIGGBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDPo+k3ZxoI9XVKtHgQIBEIBZmp7UUVjNWd6qKrLVK8oBNczY0CfLH6iAZE3UK5Ofs4+nZFi0PL3SEW8M15VgTpQoC/b0YxDPHjF0V6NHUJcWirSAqKkP5Sz5eSTk91FTuiwDpvYQ2q9aY6w=
"
Method 3: Encrypt and decrypt with GCP KMS
At this moment, PyMS not support Google KMS encryption, this issue is in TODO