| name | env-config |
| description | Environment configuration and secrets management skill using UV for Python projects. Handles .env files, environment variables, secrets encryption, multi-environment setups, and secure configuration patterns. Use when setting up project environments, managing API keys, or implementing configuration best practices. |
Environment Configuration Skill
Overview
This skill provides comprehensive guidance for managing environment configurations, secrets, and environment variables in Python projects using UV (the modern Python package and project manager). It covers secure configuration patterns, multi-environment setups, .env file management, and secrets handling with encryption support.
Environment configuration is critical for separating configuration from code (12-factor app principles), managing secrets securely across environments, preventing credential leaks, and supporting team collaboration.
When to Use This Skill
Use this skill when you need to:
- Set up environment configuration for a new Python project
- Implement secure secrets management
- Configure multi-environment setups (dev/staging/prod)
- Migrate from hardcoded configs to environment variables
- Audit existing configuration for security issues
- Standardize configuration across team projects
- Set up UV-based Python project with proper config management
Core Principles
1. Never Hardcode Secrets
- All API keys, passwords, tokens go in environment variables or encrypted secrets
- Configuration files with secrets must be in .gitignore
- Use templates for sharing structure, not actual secrets
2. Separate by Environment
- Different configurations for development, staging, production
- Environment-specific .env files (.env.development, .env.production)
- Clear naming conventions for environment variables
3. Fail Securely
- Validate required environment variables on startup
- Provide clear error messages for missing configuration
- Use sensible defaults only for non-sensitive values
4. Use UV for Dependency Management
- UV provides fast, reliable Python package management
- Replaces pip, pip-tools, virtualenv, and more
- Ensures reproducible environments across machines
5. Document Everything
- Template files show structure without exposing secrets
- README explains required variables and how to set them
- Comments describe purpose and format of variables
UV Setup
Installing UV
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or with pip
pip install uv
# Verify installation
uv --version
Initialize UV Project
# Create new project
uv init my-project
cd my-project
# Create virtual environment
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Add dependencies
uv add python-dotenv cryptography pydantic
# Add dev dependencies
uv add --dev pytest pytest-env black ruff
Environment Configuration Workflow
Phase 1: Project Setup
1. Create Project Structure
# Initialize UV project
uv init your-project-name
cd your-project-name
uv venv
source .venv/bin/activate
2. Install Configuration Dependencies
uv add python-dotenv # For .env file loading
uv add cryptography # For secrets encryption (optional)
uv add pydantic # For config validation (optional)
uv add --dev pytest pytest-env
3. Create Configuration Files
Essential files to create:
.env.template- Template showing required variables (commit this).env- Actual secrets (add to .gitignore).env.development- Development-specific config.env.production- Production-specific configconfig.py- Configuration loading module
4. Update .gitignore
# Add to .gitignore
cat >> .gitignore << 'EOF'
# Environment files
.env
.env.local
.env.*.local
secrets.json
# UV
.venv/
__pycache__/
*.pyc
.pytest_cache/
.ruff_cache/
EOF
Phase 2: Create Configuration Templates
1. Create .env.template
# .env.template - Commit this file
# Copy to .env and fill in actual values
# Application Settings
APP_NAME=MyApp
APP_ENV=development
DEBUG=true
LOG_LEVEL=INFO
# Database Configuration
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
DATABASE_POOL_SIZE=5
# API Keys (Replace with actual keys)
ANTHROPIC_API_KEY=sk-ant-api03-xxx
OPENAI_API_KEY=sk-xxx
OPENROUTER_API_KEY=sk-or-v1-xxx
# Security
SECRET_KEY=generate-random-secret-key-here
JWT_SECRET=another-random-secret
# Feature Flags
ENABLE_ANALYTICS=false
ENABLE_CACHING=true
2. Create Config Loading Module
Create config.py - see references/api-reference.md for complete implementation:
import os
from pathlib import Path
from dotenv import load_dotenv
class ConfigError(Exception):
"""Raised when required configuration is missing."""
pass
class Config:
"""Application configuration from environment variables."""
def __init__(self, env: str = None):
self.env = env or os.getenv('APP_ENV', 'development')
self._load_env_file()
self._validate_required()
def _load_env_file(self):
"""Load appropriate .env file based on environment."""
env_file = Path(f'.env.{self.env}')
if env_file.exists():
load_dotenv(env_file, override=True)
if Path('.env').exists():
load_dotenv('.env', override=False)
@property
def app_name(self) -> str:
return os.getenv('APP_NAME', 'MyApp')
@property
def debug(self) -> bool:
return os.getenv('DEBUG', 'false').lower() in ('true', '1', 'yes')
# Add more properties as needed...
# Global config instance
config = Config()
For complete Config class with all properties and validation, see references/api-reference.md.
3. Use Config in Application
from config import config
def main():
print(f"Starting {config.app_name} in {config.app_env} mode")
if config.anthropic_api_key:
# Use API key
print("✓ API key loaded")
Phase 3: Multi-Environment Setup
1. Create Environment-Specific Files
.env.development:
APP_ENV=development
DEBUG=true
LOG_LEVEL=DEBUG
DATABASE_URL=postgresql://localhost:5432/myapp_dev
.env.production:
APP_ENV=production
DEBUG=false
LOG_LEVEL=WARNING
DATABASE_URL=postgresql://prod-host:5432/myapp_prod
SECRET_KEY=super-secure-random-key
2. Switch Between Environments
# Development (default)
uv run python main.py
# Production
export APP_ENV=production
uv run python main.py
Phase 4: Secrets Management
1. Using JSON Secrets (Alternative Pattern)
Create secrets_template.json:
{
"anthropic_api_key": "sk-ant-api03-xxx",
"openai_api_key": "sk-xxx",
"database_password": "your-password-here",
"comment": "Copy to secrets.json and fill in real values"
}
2. Load JSON Secrets
See references/api-reference.md for complete implementation:
import json
from pathlib import Path
def load_secrets(secrets_file: str = 'secrets.json') -> dict:
"""Load secrets from JSON with fallback to env vars."""
if Path(secrets_file).exists():
return json.load(open(secrets_file))
# Fallback to environment variables
return {
'anthropic_api_key': os.getenv('ANTHROPIC_API_KEY', '')
}
3. Encrypted Secrets
For encryption utilities and advanced secrets management, see:
references/advanced-topics.md- Encryption, rotation, auditingscripts/env_helper.py- Encryption/decryption utilities
Configuration Validation
Using Pydantic for Type-Safe Config
from pydantic import BaseSettings, Field, validator
class Settings(BaseSettings):
app_name: str = Field(default='MyApp', env='APP_NAME')
app_env: str = Field(default='development', env='APP_ENV')
database_url: str = Field(..., env='DATABASE_URL') # Required
@validator('app_env')
def validate_env(cls, v):
allowed = ['development', 'staging', 'production']
if v not in allowed:
raise ValueError(f'app_env must be one of {allowed}')
return v
class Config:
env_file = '.env'
settings = Settings()
For complete Pydantic configuration examples, see references/api-reference.md.
Security Best Practices
1. .gitignore Configuration
Always add to .gitignore:
.env
.env.local
.env.*.local
secrets.json
.env.production
.venv/
2. Secret Rotation
Implement regular API key rotation:
def rotate_api_key(old_key: str, new_key: str):
"""Rotate API key gracefully with backup."""
# Implementation in references/advanced-topics.md
3. Environment Auditing
Regular security audits:
def audit_environment():
"""Check for security issues in environment variables."""
# Implementation in references/advanced-topics.md
For complete security implementations, see references/advanced-topics.md.
Testing Configuration
Basic Test Setup
# conftest.py
import pytest
import os
@pytest.fixture
def test_env():
"""Set up test environment variables."""
original = os.environ.copy()
os.environ['APP_ENV'] = 'testing'
os.environ['DEBUG'] = 'true'
yield
os.environ.clear()
os.environ.update(original)
@pytest.fixture
def config(test_env):
from config import Config
return Config(env='testing')
Example Tests
def test_config_loading(config):
assert config.app_env == 'testing'
assert config.debug is True
def test_missing_required_var():
from config import ConfigError
with pytest.raises(ConfigError):
Config() # Missing required vars
For comprehensive testing guide, see references/testing-guide.md.
UV Commands Reference
# Dependency management
uv sync # Install all dependencies
uv add requests # Add dependency
uv add --dev pytest # Add dev dependency
uv remove requests # Remove dependency
# Environment management
uv venv # Create virtual environment
uv lock --upgrade # Update dependencies
# Running scripts
uv run python main.py # Run with UV environment
uv run pytest # Run tests
# Compatibility
uv pip compile pyproject.toml -o requirements.txt
Helper Scripts
This skill provides utility scripts in scripts/:
env_helper.py- Core utilities for env management- Parse and validate .env files
- Check for missing variables
- Encrypt/decrypt secrets files
- Compare environments
- Generate .env templates
Usage:
# Validate .env file
python scripts/env_helper.py validate .env
# Encrypt secrets
python scripts/env_helper.py encrypt secrets.json secrets.encrypted
# Compare environments
python scripts/env_helper.py compare .env.development .env.production
Quick Reference
Setup Checklist
- Install UV:
curl -LsSf https://astral.sh/uv/install.sh | sh - Create project:
uv init project-name - Create virtual env:
uv venv - Add dependencies:
uv add python-dotenv - Create
.env.templatefrom examples - Copy to
.envand fill in secrets - Add
.envto.gitignore - Create
config.pymodule - Test configuration loading
- Set up environment-specific configs
- Implement validation
- Add tests for configuration
Environment Variable Naming
Use consistent naming:
APP_*- Application settingsDATABASE_*- Database configuration*_API_KEY- API keys and tokens*_SECRET- Secret keysENABLE_*- Feature flags*_URL- Service endpoints
Security Checklist
- No secrets in version control
-
.envin.gitignore - Production secrets separate from dev
- Required variables validated on startup
- Secrets encrypted at rest (if needed)
- Regular secret rotation
- Team training on secure practices
Additional Resources
Documentation in This Skill
references/api-reference.md- Complete Config class implementation, Pydantic validation, JSON secrets loadingreferences/advanced-topics.md- Encryption, secret rotation, auditing, multi-tenant config, cloud integrationreferences/testing-guide.md- pytest setup, mocking, validation testing, CI/CD examplesreferences/troubleshooting.md- Common issues, environment-specific problems, debugging techniques
Examples Directory
.env.example- Comprehensive .env templatepyproject.toml- UV project configurationsecrets_template.json- JSON secrets template
External Resources
- UV Documentation: https://docs.astral.sh/uv/
- python-dotenv: https://github.com/theskumar/python-dotenv
- Pydantic: https://docs.pydantic.dev/
- 12-Factor App Config: https://12factor.net/config
Troubleshooting
For common issues and solutions, see references/troubleshooting.md:
- Environment variables not loading
- Wrong environment loaded
- UV sync failures
- Import errors
- Secrets decryption issues
- Performance optimization
- Security issues and remediation
- Docker integration problems
Quick debug:
from dotenv import load_dotenv
load_dotenv(verbose=True) # Shows loading process