Tags
It’s common to use Python script for device configuration, backup or automation. And to do that we usually put credentials, API Key in the script itself. It creates a whole lot of problem with sharing scripts with others; store/share it public repository. There are few options to overcome the issue like storing credentials, API Key’s in separate file and not share that file with others. We can also use “keyring” which will store the password in operating system’s credential store.
The keyring package is a library designed to let you access your operating system’s credential store. In summary, it let us to store and retrieve passwords in operating system, which allows you to avoid having a password in plaintext in the script.
“keyring
” is by default installed in our linux operating system. We need to install related python modules only. To check keyring installation try “keyring --help
” or “keyring --list-backends
” for list of supported backends. The common one is to use
keyrings.cryptfile - Encrypted text file storage.
Now install the keyring and keyrings.cryptfile python module. I am using python3
pip3 install keyring
pip3 install keyrings.cryptfile
We can use keyring set
command to store the credentials and keyring get
command to retrieve it. Lets store some credential and API key
keyring set meraki MERAKI_API_VALUE
keyring set meraki ORG_ID
First one is to capture the Meraki API Key and second one is the Meraki Organization ID.
Now lets see some python code; how we can use the keyring module. Following is a sample pyhton script which get all the Meraki Switch serial numbers from the organization. Here we are putting the API Key and ORG ID straight into the code:
import requests import json MERAKI_API_KEY = 'X-Cisco-Meraki-API-Key' MERAKI_API_VALUE = 'de300bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx4391c' ORG_ID='123456' url = 'https://api.meraki.com/api/v0/organizations/{}/inventory'.format(ORG_ID) response = requests.get(url=url, headers={MERAKI_API_KEY : MERAKI_API_VALUE, 'Content-type': 'application/json'}) switch_list = response.json() switch_serial = [] for i in switch_list: if i['model'][:2] in ('MS') and i['networkId'] is not None: switch_serial.append(i['serial']) print(switch_serial)
The output will look like ['QRST-BEAF-7999', 'QRST-BEAF-7123']
which is a python list.
Let’s try the same code; but this time I will retrieve the API key and ORD ID using keyring module:
import keyring import requests import json MERAKI_API_KEY = 'X-Cisco-Meraki-API-Key' MERAKI_API_VALUE = keyring.get_password("meraki", "MERAKI_API_VALUE") #API_KEY is stored in keyring ORG_ID = keyring.get_password("meraki", "ORG_ID") #ORG_ID is stored in keyring url = 'https://api.meraki.com/api/v0/organizations/{}/inventory'.format(ORG_ID) response = requests.get(url=url, headers={MERAKI_API_KEY : MERAKI_API_VALUE, 'Content-type': 'application/json'}) switch_list = response.json() switch_serial = [] for i in switch_list: if i['model'][:2] in ('MS') and i['networkId'] is not None: switch_serial.append(i['serial']) print(switch_serial)
The output will be same; only difference is that the API Key and ORG ID is not stored in the script.
The configuration is stored in a file named “keyringrc.cfg” found in a platform-specific location. To determine where the config file is stored, run the following:
python -c "import keyring.util.platform_; print(keyring.util.platform_.config_root())"
In my case it’s stored in /home/fakrul/.local/share/python_keyring and here is output
Pingback: Python Script – Credentials stored in Hashicorp Vault | http://blog.fakrul.com
Harry said:
This is my test script for setting and recalling an api code or account number . Two things. When run more than once on open console I get a default string of messages. i.e. script will only work one time.
Upon initial set_password requires a password entry. Then it requires password prior to recall. Any suggestions as to how to work around that as I need to automatically run some scripts as set times of day and can’t enter manually
import keyring
#keyring.set_password(‘test’,’api’,’25798’)
account_id = keyring.get_password(‘test’,’api’)
print (account_id)