# Configuration Steward uses a two-layer configuration system. Only the bare minimum needed to boot lives in files or environment variables. Everything else is stored in the database and managed through the Settings UI. --- ## Bootstrap Config (File / Env Vars) These three values are read at startup from `config.yaml` and/or environment variables: | Key | Env var | Default | Description | |---|---|---|---| | `database.url` | `STEWARD_DATABASE_URL` | — | PostgreSQL async URL. **Required.** | | `secret_key` | `STEWARD_SECRET_KEY` | auto-generated | Flask/Quart session signing key. Auto-generated and saved to `/data/secret.key` if not set. | | `plugin_dir` | `STEWARD_PLUGIN_DIR` | `plugins` | Path to the plugins directory. | **Resolution order for `database_url`:** env var `STEWARD_DATABASE_URL` → env var `STEWARD_DATABASE__URL` (legacy double-underscore) → `database.url` in `config.yaml`. **Resolution order for `secret_key`:** env var `STEWARD_SECRET_KEY` → `secret_key` in `config.yaml` → `/data/secret.key` file → auto-generate and write to `/data/secret.key`. ### Minimal config.yaml ```yaml database: url: "postgresql+asyncpg://user:password@localhost/steward" ``` ### Minimal env-only setup (Docker) ```bash STEWARD_DATABASE_URL=postgresql+asyncpg://user:password@db/steward ``` A `.env` file is loaded automatically if present. --- ## App Settings (Database-backed) All runtime settings are stored in the `app_settings` table and editable through the web UI at `/settings/`. They are loaded into `app.config` at startup. ### All Settings and Defaults | Key | Default | Description | |---|---|---| | `session.lifetime_hours` | `8` | How long a login session lasts | | `data.retention_days` | `90` | How many days of ping/DNS/metric/ansible history to keep | | `monitors.poll_interval_seconds` | `60` | How often ping and DNS checks run | | `smtp.host` | `""` | SMTP server hostname | | `smtp.port` | `587` | SMTP server port | | `smtp.tls` | `true` | Use STARTTLS | | `smtp.username` | `""` | SMTP login username | | `smtp.password` | `""` | SMTP login password | | `smtp.recipients` | `[]` | List of email addresses to notify | | `webhook.url` | `""` | Webhook POST destination URL | | `webhook.template` | see below | Jinja2 JSON template for webhook body | | `ansible.sources` | `[]` | List of playbook source definitions | | `ping.threshold.good_ms` | `50` | Latency below this is shown green in the ping UI | | `ping.threshold.warn_ms` | `200` | Latency below this is shown yellow; above is orange | Default webhook template: ``` {"content": "**{{ alert.state }}** — {{ alert.resource }} — {{ alert.rule_name }} ({{ alert.metric }} = {{ alert.value }})"} ``` ### Reading and Writing Settings in Code ```python from steward.core.settings import get_setting, set_setting # Read async with current_app.db_sessionmaker() as session: host = await get_setting(session, "smtp.host") # Write (must be inside a transaction) async with current_app.db_sessionmaker() as session: async with session.begin(): await set_setting(session, "smtp.host", "mail.example.com") ``` `get_setting()` returns the stored value or the default from `DEFAULTS` if the key has never been set. ### The DEFAULTS Dict `steward/core/settings.py` contains the `DEFAULTS` dict — the canonical list of all recognised settings and their default values. Add new settings here to make them recognised by `get_all_settings()` and the settings UI. --- ## app.config Keys After startup, `app.config` contains these additional keys (in addition to standard Quart keys): | Key | Type | Source | |---|---|---| | `DATABASE_URL` | str | Bootstrap | | `PLUGIN_DIR` | str | Bootstrap | | `SESSION_LIFETIME_HOURS` | int | DB settings | | `DATA_RETENTION_DAYS` | int | DB settings | | `MONITORS_POLL_INTERVAL` | int | DB settings | | `SMTP` | dict | DB settings, via `to_smtp_cfg()` | | `WEBHOOK` | dict | DB settings, via `to_webhook_cfg()` | | `ANSIBLE` | dict | DB settings, via `to_ansible_cfg()` | | `PLUGINS` | dict | DB settings + plugin.yaml defaults, keyed by plugin name |