This documentation outlines the procedures and code implementations used for managing and storing secrets in production within the moj-analytical-services/splink_demos
project.
Introduction
Effective secret management is critical for maintaining security and confidentiality in production environments. This documentation covers the step-by-step processes and code examples to illustrate how secrets are handled.
Procedures
1. Secret Storage
Secrets such as API keys, database credentials, and tokens should never be hardcoded directly in the application code. Instead, they should be stored securely and retrieved at runtime. Here’s an example of managing secrets using environment variables.
Setting Environment Variables:
In a shell environment, you can define your secrets:
export DATABASE_URL="your-database-url"
export API_KEY="your-api-key"
Accessing Environment Variables in Code:
In your application code, you can access these environment variables like this:
import os
database_url = os.getenv('DATABASE_URL')
api_key = os.getenv('API_KEY')
print(f"Connecting to database at {database_url} with API key: {api_key}")
2. Using Configuration Files
When additional flexibility is needed, consider using configuration files that are not included in version control. For example, use a config.json
file to store non-sensitive configuration and load it in your application.
Example config.json
:
{
"app_name": "Splink Demos",
"version": "1.0",
"api_endpoint": "https://api.yourservice.com"
}
Loading Configurations:
import json
with open('config.json') as config_file:
config = json.load(config_file)
print(config["app_name"])
3. Secret Management Tools
For organizations that require more robust solutions, leveraging secret management tools like HashiCorp Vault or AWS Secrets Manager is recommended. These tools allow secure storage, versioning, and access control of secrets.
Example with HashiCorp Vault:
First, set up your Vault server and store your secrets:
vault kv put secret/myapp api_key=your-api-key
Retrieving Secrets:
import hvac
client = hvac.Client(url='http://127.0.0.1:8200', token='your-token')
secret = client.secrets.kv.read_secret(path='secret/myapp')
api_key = secret['data']['data']['api_key']
print(api_key)
4. Minimizing Secret Exposure
To minimize secret exposure, ensure to:
- Limit the scope of secrets (only use what’s necessary).
- Use role-based access control (RBAC) for sensitive operations.
- Regularly rotate secrets and revoke compromised ones.
5. Auditing and Monitoring
Implement logging and monitoring of access to secrets. This can be achieved through built-in features of secret management systems or custom logging practices.
Example Logging:
import logging
logging.basicConfig(level=logging.INFO)
def access_secret(secret_name):
logging.info(f"Accessed secret: {secret_name}")
# Code to access the secret goes here
access_secret('API_KEY')
Conclusion
Managing secrets effectively is crucial for the security of your application. The methods described here provide a robust framework for handling secrets in production to ensure confidentiality and security compliance.
References
- HashiCorp Vault: Official documentation.
- OS Environment Variables: Documentation on using environment variables.