diff --git a/config/README.md b/config/README.md new file mode 100644 index 00000000..afbb150d --- /dev/null +++ b/config/README.md @@ -0,0 +1,155 @@ +# TFM aInventory Configuration Management (v1.12.0) + +This directory contains the centralized configuration for the TFM aInventory system. Starting from Phase 7, the application has moved away from scattered `.env` files and hardcoded values towards a structured, domain-specific YAML configuration approach. + +## Table of Contents + +1. [Overview](#overview) +2. [Quick Start](#quick-start) +3. [Configuration Files](#configuration-files) + - [backend.yaml](#backendyaml) + - [frontend.yaml](#frontendyaml) + - [network.yaml](#networkyaml) + - [docker.yaml](#dockeryaml) + - [secrets.yaml](#secretsyaml) +4. [Environment Variable Overrides](#environment-variable-overrides) +5. [Load Order](#load-order) +6. [Security Best Practices](#security-best-practices) +7. [Troubleshooting](#troubleshooting) + +--- + +## Overview + +The `config/` directory is the **single source of truth** for all application settings. By using YAML, we achieve: +- **Structure:** Hierarchical settings grouped by domain. +- **Documentation:** Inline comments explaining every variable. +- **Flexibility:** Easy overrides via environment variables. +- **Safety:** Clear separation between non-sensitive config and secrets. + +## Quick Start + +To set up your configuration for a new installation: + +1. **Clone the examples:** + ```bash + cp config/backend.yaml.example config/backend.yaml + cp config/frontend.yaml.example config/frontend.yaml + cp config/network.yaml.example config/network.yaml + cp config/docker.yaml.example config/docker.yaml + cp config/secrets.yaml.example config/secrets.yaml + ``` + +2. **Generate Secrets:** + Open `config/secrets.yaml` and fill in your API keys. Generate a strong JWT secret: + ```bash + python3 -c "import secrets; print(secrets.token_urlsafe(64))" + ``` + +3. **Verify YAML Syntax:** + Ensure your changes are valid YAML: + ```bash + python3 -c "import yaml; [yaml.safe_load(open(f)) for f in ['config/backend.yaml', 'config/frontend.yaml', 'config/network.yaml', 'config/docker.yaml', 'config/secrets.yaml']]" + ``` + +## Configuration Files + +### backend.yaml +Controls the FastAPI backend, database, AI integration, and logging. + +| Section | Variable | Description | Default | +|---------|----------|-------------|---------| +| database | `sqlite_path` | Path to the SQLite DB file | `data/inventory.db` | +| database | `wal_mode` | Enable Write-Ahead Logging | `true` | +| ai | `primary_ai_provider` | `gemini` or `claude` | `gemini` | +| auth | `jwt_secret_key` | Secret for JWT (use `secrets.yaml`) | - | +| logging | `log_level` | `DEBUG`, `INFO`, `WARNING`, `ERROR` | `INFO` | + +### frontend.yaml +Controls the Next.js frontend application behavior and PWA settings. + +| Variable | Description | Default | +|----------|-------------|---------| +| `api.backend_url` | Full URL of the backend API | `http://localhost:8916` | +| `features.offline_enabled` | Enable service worker caching | `true` | +| `pwa.app_name` | Display name of the PWA | `TFM aInventory` | + +### network.yaml +Defines host-side port mappings and SSL/CORS policies. + +| Variable | Description | Default | +|----------|-------------|---------| +| `ports.backend_port` | Host port for backend | `8916` | +| `ports.frontend_port` | Host port for frontend | `8917` | +| `ssl.ssl_enabled` | Enable HTTPS via Caddy | `true` | +| `cors.allowed_origins` | List of allowed origins | `*` | + +### docker.yaml +Resource limits and container orchestration settings. + +| Variable | Description | Default | +|----------|-------------|---------| +| `resources.backend_cpu_limit` | Max CPU cores for backend | `1.0` | +| `resources.backend_memory_limit` | Max RAM for backend | `1G` | +| `volumes.use_named_volumes` | Use named volumes vs bind | `true` | + +### secrets.yaml +**CRITICAL:** This file contains sensitive data. It is ignored by Git and must NEVER be committed. +It contains: +- `JWT_SECRET_KEY` +- `GEMINI_API_KEY` +- `CLAUDE_API_KEY` +- `DATABASE_PASSWORD` (optional) +- `LDAP_PASSWORD` (optional) + +## Environment Variable Overrides + +Any value in the YAML files can be overridden by a system environment variable. The naming convention is: +`DOMAIN_SECTION_VARIABLE` (all uppercase). + +**Examples:** +- `backend.yaml`: `database.sqlite_path` -> `BACKEND_DATABASE_SQLITE_PATH` +- `network.yaml`: `ports.backend_port` -> `NETWORK_PORTS_BACKEND_PORT` +- `secrets.yaml`: `GEMINI_API_KEY` -> `GEMINI_API_KEY` (Directly mapped for common secrets) + +Environment variables take **precedence** over YAML files. This is useful for Docker deployments where secrets are injected at runtime. + +## Load Order + +The application loads configuration in the following priority: +1. **System Environment Variables** (Highest) +2. **secrets.yaml** +3. **Domain YAML files** (`backend.yaml`, etc.) +4. **Code Defaults** (Lowest) + +## Security Best Practices + +1. **Permissions:** Set strict permissions on `secrets.yaml`: + ```bash + chmod 600 config/secrets.yaml + ``` +2. **Rotation:** Rotate your `JWT_SECRET_KEY` and API keys every 90 days. +3. **CORS:** In production, never use `allowed_origins: "*"`. List specific IPs or FQDNs. +4. **Volume Mounts:** In Docker, mount the `config/` directory as **read-only** (`:ro`) except for the `secrets.yaml` if needed by a management tool. + +## Troubleshooting + +### Invalid YAML Syntax +If the application fails to start with a configuration error: +- Check for tabs instead of spaces (YAML requires spaces). +- Check for missing colons or incorrect indentation. +- Use a linter: `python3 -m yaml.scanner config/backend.yaml`. + +### Configuration Not Applying +- Verify the variable name matches exactly (case-sensitive in YAML). +- Check if an environment variable is overriding the YAML value. +- Ensure the file is in the correct directory: `/app/config/` inside the container. + +### Secret Exposure +If you accidentally commit a YAML file containing secrets: +1. Delete the file from the repository. +2. **Immediately** rotate all exposed keys and secrets. +3. Purge the secret from Git history using `git-filter-repo` or BFG Repo-Cleaner. + +--- +*TFM aInventory - Centralized Configuration Management System*