4.3 KiB
4.3 KiB
Work Summary: .env Configuration Implementation
Date: 2026-01-12 Status: ✅ Complete
Overview
Updated the Attune API to use .env file-based configuration with support for JWT settings, making it easier to configure and run the service locally.
Changes Made
1. Updated SecurityConfig in Common Crate
File: crates/common/src/config.rs
- Split
jwt_expirationinto two separate fields:jwt_access_expiration- Access token lifetime (default: 3600s / 1 hour)jwt_refresh_expiration- Refresh token lifetime (default: 604800s / 7 days)
- Added default functions for both expiration settings
- Updated Default implementation for SecurityConfig
- Updated test cases to use new field names
2. Updated API Main Entry Point
File: crates/api/src/main.rs
Before:
- Read JWT settings from individual environment variables (
JWT_SECRET,JWT_ACCESS_EXPIRATION,JWT_REFRESH_EXPIRATION) - Manual fallback to defaults
After:
- Added
.envfile loading usingdotenvy(already a dependency) - Priority:
.env.local>.env> environment variables - Load JWT configuration from
Config.securitystruct - Use structured configuration instead of individual env vars
- Added informative logging showing token expiration times
Key changes:
// Load .env file automatically
if let Ok(_) = dotenvy::from_filename(".env.local") {
info!("Loaded configuration from .env.local");
} else if let Ok(_) = dotenvy::dotenv() {
info!("Loaded configuration from .env");
}
// Use config values instead of env vars
let jwt_secret = config.security.jwt_secret.clone().unwrap_or_else(|| {
tracing::warn!("JWT_SECRET not set in config, using default (INSECURE for production!)");
"insecure_default_secret_change_in_production".to_string()
});
let jwt_config = JwtConfig {
secret: jwt_secret,
access_token_expiration: config.security.jwt_access_expiration as i64,
refresh_token_expiration: config.security.jwt_refresh_expiration as i64,
};
3. Updated .env.example
File: .env.example
- Changed
ATTUNE__SECURITY__JWT_EXPIRATIONtoATTUNE__SECURITY__JWT_ACCESS_EXPIRATION - Added
ATTUNE__SECURITY__JWT_REFRESH_EXPIRATIONwith 7-day default - Updated comments to clarify access vs refresh tokens
4. Created Default .env File
File: .env (new)
Created a simple, ready-to-use configuration file with:
- Database connection to local PostgreSQL
- JWT secret for development
- Access token: 1 hour (3600s)
- Refresh token: 7 days (604800s)
- Server on 127.0.0.1:8080
- Pretty log format for development
- All essential settings for quick start
5. Created Quick Start Guide
File: docs/quick-start.md (new)
Comprehensive guide including:
- Step-by-step database setup
- Configuration instructions
- How to start the API
- Testing examples
- Common customizations
- Troubleshooting tips
- Production deployment checklist
Configuration Format
The API now uses the following environment variable format:
# Double underscore for nested config
ATTUNE__SECURITY__JWT_SECRET=your-secret-here
ATTUNE__SECURITY__JWT_ACCESS_EXPIRATION=3600
ATTUNE__SECURITY__JWT_REFRESH_EXPIRATION=604800
ATTUNE__DATABASE__URL=postgresql://user:pass@host:port/db
Benefits
-
Easier Local Development
- No need to export multiple environment variables
- Single
.envfile contains all configuration - Copy
.env.exampleto.envand start coding
-
Better Organization
- All config in one place
- Structured configuration with validation
- Type-safe with Rust's type system
-
Flexible Configuration
- Support for
.env.localfor personal overrides - Environment variables still work (higher priority)
- Config files via
ATTUNE_CONFIGenvironment variable
- Support for
-
Production Ready
- Clear separation of dev/prod settings
- JWT secrets properly configurable
- Validation ensures required settings are present
Usage
For Development
-
Quick Start:
cd attune ./scripts/setup-db.sh cargo run --bin attune-apiThat's it! The
.envfile is already configured. -
Custom Settings:
# Create personal overrides cp .env .env.local # Edit .env.local with your settings # .env.local takes priority
For Production
- Don't use .env files - Use