# 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 **SINGLE SOURCE OF TRUTH (SSOT):** This is the master file for your server's network topology. All other domains (Backend CORS, Frontend API URL) are dynamically derived from these settings. | Variable | Description | Default | |----------|-------------|---------| | `application.server_ip` | **MASTER IP** of your server | `localhost` | | `application.cors_origins`| Extra allowed origins (Subnets/IPs) | - | | `ports.backend_port` | Host port for backend | `8916` | | `ports.frontend_port` | Host port for frontend | `8917` | | `ssl.ssl_enabled` | Enable HTTPS via Caddy | `true` | > **Note:** You only need to change the IP address in **this file**. The system will automatically update the frontend's API URL and the backend's CORS policies upon restart. ### 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*