| 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
curl -LsSf https://astral.sh/uv/install.sh | sh
pip install uv
uv --version
Initialize UV Project
uv init my-project
cd my-project
uv venv
source .venv/bin/activate
uv add python-dotenv cryptography pydantic
uv add --dev pytest pytest-env black ruff
Environment Configuration Workflow
Phase 1: Project Setup
1. Create Project Structure
uv init your-project-name
cd your-project-name
uv venv
source .venv/bin/activate
2. Install Configuration Dependencies
uv add python-dotenv
uv add cryptography
uv add pydantic
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 config
config.py - Configuration loading module
4. Update .gitignore
cat >> .gitignore << 'EOF'
.env
.env.local
.env.*.local
secrets.json
.venv/
__pycache__/
*.pyc
.pytest_cache/
.ruff_cache/
EOF
Phase 2: Create Configuration Templates
1. Create .env.template
APP_NAME=MyApp
APP_ENV=development
DEBUG=true
LOG_LEVEL=INFO
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
DATABASE_POOL_SIZE=5
ANTHROPIC_API_KEY=sk-ant-api03-xxx
OPENAI_API_KEY=sk-xxx
OPENROUTER_API_KEY=sk-or-v1-xxx
SECRET_KEY=generate-random-secret-key-here
JWT_SECRET=another-random-secret
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')
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:
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
uv run python main.py
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))
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, auditing
scripts/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')
@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."""
3. Environment Auditing
Regular security audits:
def audit_environment():
"""Check for security issues in environment variables."""
For complete security implementations, see references/advanced-topics.md.
Testing Configuration
Basic Test Setup
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()
For comprehensive testing guide, see references/testing-guide.md.
UV Commands Reference
uv sync
uv add requests
uv add --dev pytest
uv remove requests
uv venv
uv lock --upgrade
uv run python main.py
uv run pytest
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:
python scripts/env_helper.py validate .env
python scripts/env_helper.py encrypt secrets.json secrets.encrypted
python scripts/env_helper.py compare .env.development .env.production
Quick Reference
Setup Checklist
Environment Variable Naming
Use consistent naming:
APP_* - Application settings
DATABASE_* - Database configuration
*_API_KEY - API keys and tokens
*_SECRET - Secret keys
ENABLE_* - Feature flags
*_URL - Service endpoints
Security Checklist
Additional Resources
Documentation in This Skill
references/api-reference.md - Complete Config class implementation, Pydantic validation, JSON secrets loading
references/advanced-topics.md - Encryption, secret rotation, auditing, multi-tenant config, cloud integration
references/testing-guide.md - pytest setup, mocking, validation testing, CI/CD examples
references/troubleshooting.md - Common issues, environment-specific problems, debugging techniques
Examples Directory
.env.example - Comprehensive .env template
pyproject.toml - UV project configuration
secrets_template.json - JSON secrets template
External Resources
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)