Files
attune/work-summary/sessions/2026-01-12-env-config.md
2026-02-04 17:46:30 -06:00

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_expiration into 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 .env file loading using dotenvy (already a dependency)
  • Priority: .env.local > .env > environment variables
  • Load JWT configuration from Config.security struct
  • 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_EXPIRATION to ATTUNE__SECURITY__JWT_ACCESS_EXPIRATION
  • Added ATTUNE__SECURITY__JWT_REFRESH_EXPIRATION with 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

  1. Easier Local Development

    • No need to export multiple environment variables
    • Single .env file contains all configuration
    • Copy .env.example to .env and start coding
  2. Better Organization

    • All config in one place
    • Structured configuration with validation
    • Type-safe with Rust's type system
  3. Flexible Configuration

    • Support for .env.local for personal overrides
    • Environment variables still work (higher priority)
    • Config files via ATTUNE_CONFIG environment variable
  4. Production Ready

    • Clear separation of dev/prod settings
    • JWT secrets properly configurable
    • Validation ensures required settings are present

Usage

For Development

  1. Quick Start:

    cd attune
    ./scripts/setup-db.sh
    cargo run --bin attune-api
    

    That's it! The .env file is already configured.

  2. Custom Settings:

    # Create personal overrides
    cp .env .env.local
    # Edit .env.local with your settings
    # .env.local takes priority
    

For Production

  1. Don't use .env files - Use