π From Dev to Prod: Secure Password Generation Across Environments
From Dev to Prod: Secure Password Generation Across Environments
Password generation in development, staging, and production environments serves different purposes and requires different configurations. Using the same generation strategy across all environments creates security risks in production and friction in development. For production-grade credential management across all environments, 1Password provides secure vaults that work seamlessly from local development to production deployment.
Environment-Specific Requirements
Development: Passwords must be deterministic and reproducible for testing. Use a seeded PRNG for test fixtures, not production-level CSPRNG.
Staging: Production-like password generation but with lower entropy requirements. Good for integration testing with IAM systems.
Production: Maximum cryptographic strength. No shortcuts, no determinism, no debugging conveniences.
Configuration Management
Use environment variables to control password generation parameters:
import os
import secrets
class PasswordConfig:
@staticmethod
def from_env():
env = os.getenv('APP_ENV', 'development')
if env == 'production':
return {
'min_length': 16,
'use_special': True,
'csp_source': 'os_entropy'
}
elif env == 'staging':
return {
'min_length': 12,
'use_special': True,
'csp_source': 'os_entropy'
}
else: # development / testing
return {
'min_length': 8,
'use_special': False,
'csp_source': 'deterministic'
}
The Password Service Abstraction
Decouple password generation logic from environment-specific details using an interface:
from abc import ABC, abstractmethod
import secrets
import random
class PasswordService(ABC):
@abstractmethod
def generate(self, length: int) -> str:
pass
class ProductionPasswordService(PasswordService):
def generate(self, length: int) -> str:
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*'
return ''.join(secrets.choice(chars) for _ in range(length))
class TestPasswordService(PasswordService):
def __init__(self):
self._counter = 0
def generate(self, length: int) -> str:
self._counter += 1
return f'TestPassword-{self._counter:04d}-{length}chars'
CI/CD Pipeline Integration
In your CI/CD pipeline, validate that production is never running dev-grade password generation:
# .github/workflows/security.yml
- name: Check password generation quality
run: |
python3 -c "
import secrets
# Verify CSPRNG is being used
pwd = ''.join(secrets.choice('abcdefghijklmnopqrstuvwxyz') for _ in range(100))
entropy = len(pwd) * 4.7 # log2(26) β 4.7
assert entropy > 400, f'Low entropy: {entropy}'
print(f'Password entropy check passed: {entropy:.0f} bits')
"
The ability to generate appropriate passwords at each stage of the pipeline β deterministic for testing, strong for production β is a hallmark of a mature security engineering practice.