Keeping credentials out of your project

Imaging you are working on a project that has database access, API access secured with tokens or uses other credentials that should not be stored in a version control system like git because it would allow everyone with access to get the credentials and access the systems. I’d like to show in a small example how to extract critical and confident information into a protected machine config that is managed by an administration team and how to access this information from the application. For this example I am using a simple Python script that accesses my Azure DevOps environment. I want to give away the generic code but not my internal URL, my collection and project names and for sure not my access credentials. So these files are exported into a file in my home directory which is stored in the defined path “%USERPROFILE%\.goasys\pythonex\credentials.json” (Windows) or “$HOME/.goasys/pythonex/credentials.json” (Linux). This file holds the token, URL and collection and project defintion:

{
	"token": "asdf",
	"url": "https://myserver.local",
	"localproj": "/MyCol/MyProj"
}

The generic script, which I could also publish to GitHub for example would then look like this:

import http.client, json, os, platform

def read_credentials():
	basebath = os.getenv('HOME')
	if platform.system() == "Windows":
		basebath = os.getenv('USERPROFILE')
	f = open(os.path.join(basebath, ".goasys", "pythonex", "credentials.json"))
	data = json.load(f)
	f.close()
	return data

if __name__ == "__main__":
	credentials = read_credentials()
	conn = http.client.HTTPSConnection(f"{credentials['url']}")
	payload = ''
	headers = {"Authorization": f"Basic {credentials['token']}"}
	conn.request("GET", f"{credentials['localproj']}/_apis/build/builds?api-version=6.0", payload, headers)
	res = conn.getresponse()
	data = res.read()
	print(data.decode("utf-8"))

With this method one could also define development, test and production systems and the same application deployed to these systems would use different services and resources. The big advantage is, that the configuration is per machine and the application does not need to be changed and because a generic format is used everything can be stored in this file and the user is not bound to certain predefined fields.

Another use case would be cron jobs running on a server in a certain users context. Other users who can connect to the server should not be able to read the credentials that are used by the service:

As always I hope this helps somebody and makes somebodies lives easier.