Simple Password Management with Python
Many uses of python involve connections to APIs, databases, or hosted information. Embedding a password in a script is always a bad idea. You can easily forget it is there, and inadvertently share confidential information with others. This is especially important if you regularly are posting content to a public GitHub.
CSV files
Storing important content doesn’t need to be complicated. Simply creating a CSV file that has the information you need in tabular format will certainly do the job. Provided someone can’t access the file you need and you plan to keep the information packaged privately, there isn’t a need to get fancy.
Imagine you need to access multiple APIs, with keys and tokens, for various social media platforms to aggregate data. A simple way of doing this is to create the following CSV file:
Account | Pass | Key | SecKey | Token |
twitteraccount | pass1 | key1 | seck1 | tok1 |
redditaccount | pass2 | key2 | seck2 | tok2 |
Place the file in a ‘assets’ folder where your script resides and now the content is accessible with the following code:
import pandas as pd
access = pd.read_csv('access.csv')
twitter = access[access['Account']=='twitteraccount']
pass = twitter['Pass'].values[0]
Here, the data frame is filtered to the account we wish to use. Then we pull the series of that row, in this case the password. Finally we make it a string using “.values[0]”. Now we can easily pass the keys, tokens, and passwords into their correct place in the code.
SQLite
The next best thing to a CSV file, is creating a lightweight central database file that you can access with your code. Creating a simple relational database allows you not only to store the information you need, but know which scripts you are using it in.
First, let’s set up the database. You don’t need to install SQLite to create a .sqlite file and make use of this technique. A SQLite browser can be downloaded for free, and you can also make use of the sqlite3 python library. Here, I will use the browser to first set up a database. As you can see, the interface is extremely user friendly.
- Select “New Database” and save a .sqlite file in a secured location. The save type should be “SQLite database files”. Choose a name that won’t draw attention, or give someone a reason to open it. I’ll name mine “password_database”
2. Once you save the file you will be prompted with a table editor. You can use this, or you can do this the old fashioned way with the code below.
CREATE TABLE "accounts" (
"id" INTEGER,
"account_name" TEXT,
"pass" TEXT,
"key" TEXT,
"seckey" TEXT,
"token" TEXT,
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE "usage" (
"id" INTEGER,
"script_name" TEXT,
"script_location" TEXT,
"account_id" TEXT,
FOREIGN KEY("account_id") REFERENCES accounts(id) ,
PRIMARY KEY("id" AUTOINCREMENT)
);
3. Generate your values
insert into accounts (account_name, pass, key, seckey, token)
values('twitteraccount', 'pass1', 'key1', 'seck1', 'tock1'),
values('redditaccount', 'pass2', 'key2', 'seck2', 'tock2');
Once you have this set up, we will assume a script is using the twitter account, and this is stored at the following location: C:\Users\user\myscripts\project1\python.py. Let’s log this in our database.
insert into usage (script_name, script_location)
values('python.py', 'C:\Users\user\myscripts\project1');
update usage set account_id = (select id from accounts where account_name = 'twitteraccount')
where script_name = 'python.py';
Creating the account with the id as a serial primary key, which auto increments – will generate a unique value for each entry. We associate the foreign key to this field, so when we reference the table where the account record exists in ‘usage’, the id from the ‘accounts’ table will generate automatically. This makes our lives a lot easier for auditing our records later.
Make sure to write your changes to the data base with the “write changes” button after all these updates or your information will be lost!
Now that this is logged, how can we use the confidential information? We will need to have our script directly access the db file. So you will want to use os to create an absolute path.
import sqlite3
import os
database = os.path.abspath("C:/Users/user/password_database.db")
conn = sqlite3.connect(database)
Now that you’ve made a connection, you can just pull the information you need in your python script.
query = ("""
select account_name, pass, key
from accounts
where account_name = 'twitteraccount'
""")
access = pd.read_sql_query(query, conn)
pass = access['pass'].values[0]
github sql file
KeePass
Using Keepass is another effective way of not only managing your passwords, but sharing resource accounts with colleagues. You can load a single KeePass file on a server, that many people can access using os.path.abspath. For this method, we will be using the pykeepass library.
To effectively use this method, you should use getpass, for the KeePass master password. This will purge the password during multiple runs and mask it for other users if you need to share your screen. A great tool all around if you just want to mask your passwords when running data exploration jupyter notebooks.
from pykeepass import PyKeePass
import getpass
import os
keepasspassword = getpass.getpass('input')
database = os.path.abspath("C:/Users/user/keepassfile.kdbx")
kp = PyKeePass(database, password=keepassword)
twitter_user = kp.find_entries(title='twitteraccount', first=True)
twitter_pass = twitter_user.password
env Files
A .env file or dotenv file is a way for you to control application environment constants. They are easy to make and easy to use. Also a very effective password management platform as they make environmental variables.
The simplest way to make a .env file is to open a text editor like vscode or sublime. Save a new file as “all files” and change the type in the file properties. Or if the option is present, “.env”. In the file you will specify key-value pairs for the environmental controls:
twitter_user = 'twitteraccount'
twitter_pass = 'pass'
Save this file in C:/ and then extract the variables with the following python code.
from dotenv import load_dotenv
load_dotenv
twit_user = os.getenv('twitter_user')
twit_pass = os.getenv('twitter_pass')
While there are various methods to storing passwords, unless you need to encrypt them for distribution, the methods are fairly simple. I prefer utilizing a database file so that I know how many scripts are making use of an account. This is helpful during password resets, or to manage general access over time. Either way, choosing the best methods for you is important.
2 thoughts on “Simple Password Management with Python”
Another excellent write-up dude! Keep em coming!
Thanks! Password management can be complex at times, however if you are looking for simple solutions to keep your code modular these certainly do the trick!
Comments are closed.