![]() |
Inserting username and password directly into the source code is one of the most common causes of data leaks and security incidents.
When code is versioned with Git and published (even by mistake), the credentials become irrecoverable: even if removed, they remain in the history.
In this article, we will see the best techniques for managing credentials in Python securely, preventing them from ending up in commits.
Remember that the techniques described do not only apply to Python but to any software application
(client, frontend, API, backend, module, etc.)
❌ The problem: hardcoded credentials
Example to avoid absolutely:
DB_USER = "admin"
DB_PASSWORD = "supersegreta123"
connect(db_user=DB_USER, db_password=DB_PASSWORD)
Why it's dangerous
- Credentials end up in the repository Git
- Anyone with access to the code can read them
- Even old commits remain accessible
- More complex password rotation
✅ Technique 1: Environment Variables
Concept
Credentials are saved outside the code, in the operating system, and read at runtime.
Advantages
- No credentials in the repository
- Standard for cloud and CI/CD environments
- Natively supported by Python
Setting environment variables
Linux / macOS
export DB_USER="admin"
export DB_PASSWORD="supersegreta123"
Windows (PowerShell)
setx DB_USER "admin"
setx DB_PASSWORD "supersegreta123"
Read them in Python
import os
db_user = os.getenv("DB_USER")
db_password = os.getenv("DB_PASSWORD")
if not db_user or not db_password:
raise RuntimeError("Missing credentials")
connect(db_user=db_user, db_password=db_password)
Explanation
os.getenv()reads the variable without generating errors- The credentials do not appear in the code
- Each environment can have different values
✅ Technique 2: .env file + python-dotenv
Ideal for local development.
Concept
The credentials are saved in a unversioned .env file, loaded when the application starts.
Installation
pip install python-dotenv
File .env (NOT to commit)
DB_USER=admin
DB_PASSWORD=supersecret123
Add .env to .gitignore
.env
Python code
from dotenv import load_dotenv
import os
load_dotenv()
db_user = os.getenv("DB_USER")
db_password = os.getenv("DB_PASSWORD")
connect(db_user=db_user, db_password=db_password)
Explanation
load_dotenv()loads the.envfile into memory- The file remains local
- Excellent compromise between security and simplicity
✅ Technique 3: External configuration files (config.json / yaml)
Useful for complex configurations, less so for critical passwords.
Example config.json
{
"database": {
"user": "admin",
"password": "supersegreta123"
}
}
⚠️ The file must be excluded from the repository.
Reading in Python
import json
with open("config.json") as f:
config = json.load(f)
db_user = config["database"]["user"]
db_password = config["database"]["password"]
connect(db_user=db_user, db_password=db_password)
Best practices
- Use
config.example.jsonwithout secrets - Commit the example file only
✅ Technique 4: Manual insertion with getpass
Useful for CLI scripts or occasional logins.
Example
from getpass import getpass
username = input("Username: ")
password = getpass("Password: ")
connect(db_user=username, db_password=password)
Explanation
- The password is not displayed on the screen
- It is not saved to disk
- Ideal for administrative tools
✅ Technique 5: System Keyring (password manager OS)
Concept
Credentials are saved in the operating system password manager.
Advantages
- Very secure
- No clear text passwords
- Ideal for desktop applications
Installation
pip install keyring
Save the password (only once)
import keyring
keyring.set_password(
"my_app",
"admin",
"supersegreta123"
)
Recover it
import keyring
password = keyring.get_password("my_app", "admin")
connect(db_user="admin", db_password=password)
✅ Technique 6: Secret Manager (production / cloud)
For enterprise or cloud environments:
- AWS Secrets Manager
- Azure Key Vault
- HashiCorp Vault
- Google Secret Manager
Benefits
- Automatic rotation
- Audit and access control
- Maximum security
(This technique requires SDK and configuration specifications)
📋 Memo: Separate code and configuration
Universal best practice
- Code must not know secrets
- Secrets come from the environment
- The repository must be “safe by default”
🔐 Final security checklist
- ✔ No passwords in code
- ✔
.gitignoreconfigured correctly - ✔ Environment variables when needed
- ✔
.envlocally only - ✔ Example files without secrets
- ✔ Periodic credential rotation
Conclusion
Avoiding committing usernames and passwords is not optional, but a fundamental responsibility of the developer.
Python offers simple and powerful tools for managing secrets securely: it's up to us to use them correctly.
Don't forget that these techniques apply to any programming language and any type of software application 😉
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment
