From aaa33ff1e7870a82d14fec109d6db5412026b884 Mon Sep 17 00:00:00 2001 From: Dennis <169400960+itsDNNS@users.noreply.github.com> Date: Sat, 23 May 2026 17:41:31 +0200 Subject: [PATCH] Document module config secrets in starter guide --- README.md | 26 +++++++++++++++++++++----- TEMPLATE/README.md | 5 ++++- TEMPLATE/manifest.json | 7 +++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 36995e6..1cc1944 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Every module needs a `manifest.json`: | `homepage` | string | URL to module documentation or repo | | `license` | string | SPDX license identifier (e.g., `MIT`) | | `config` | object | Default configuration values ([details](#config-defaults)) | +| `config_secrets` | array | Module-owned sensitive config keys ([details](#module-owned-secrets)) | | `menu` | object | Sidebar navigation entry ([details](#menu-entry)) | #### Menu Entry @@ -120,10 +121,16 @@ Add a sidebar link for your module: Declare default values and they are automatically registered in DOCSight's config system: ```json -"config": { - "mymodule_enabled": false, - "mymodule_api_url": "", - "mymodule_interval": 300 +{ + "config": { + "mymodule_enabled": false, + "mymodule_api_url": "", + "mymodule_api_token": "", + "mymodule_interval": 300 + }, + "config_secrets": [ + "mymodule_api_token" + ] } ``` @@ -132,6 +139,15 @@ Declare default values and they are automatically registered in DOCSight's confi - String values are stored as-is - Keys must not conflict with existing core config keys +#### Module-Owned Secrets + +Use `config_secrets` for module passwords, API tokens, and other sensitive settings: + +- Every key in `config_secrets` must also exist in the same manifest's `config` object. +- Secret keys are encrypted at rest and masked in Settings after they are saved. +- Community collectors can read only their own declared secret keys; they still cannot read DOCSight core secrets such as modem passwords or global API tokens. +- Settings templates should render secret fields as empty password/token inputs. Do not write saved secret values back into HTML `value` attributes. + --- ## Contribution Types @@ -200,7 +216,7 @@ class MyCollector(Collector): DOCSight passes `config_mgr`, `storage`, and `web` to every module collector. The base class provides exponential backoff on repeated failures (30s to 3600s max, auto-reset after 24h idle). -> **Note:** Community modules receive a `_ModuleConfigProxy` instead of the raw `ConfigManager`. This proxy hides DOCSight core secret keys such as modem passwords and API tokens. Module-owned sensitive settings should be kept out of rendered HTML values and handled through dedicated password/token fields. +> **Note:** Community modules receive a `_ModuleConfigProxy` instead of the raw `ConfigManager`. This proxy hides DOCSight core secret keys such as modem passwords and API tokens. Declare module-owned passwords or tokens in `config_secrets`; only those declared keys are readable by that module's collector. Keep saved secret values out of rendered HTML and handle them through dedicated password/token fields. ### `publisher` — Data Export (e.g., MQTT) diff --git a/TEMPLATE/README.md b/TEMPLATE/README.md index b61783a..ddf4b44 100644 --- a/TEMPLATE/README.md +++ b/TEMPLATE/README.md @@ -13,7 +13,10 @@ docker restart docsight ## Configuration -List any configuration keys here. +List any configuration keys here. If the module stores passwords or API tokens, +declare those keys in `config_secrets` in `manifest.json` and render the field as +an empty password/token input in Settings. Saved secret values must not be written +back into HTML `value` attributes. ## API Endpoints diff --git a/TEMPLATE/manifest.json b/TEMPLATE/manifest.json index 6aad76e..3a05bb3 100644 --- a/TEMPLATE/manifest.json +++ b/TEMPLATE/manifest.json @@ -10,6 +10,13 @@ "routes": "routes.py", "i18n": "i18n/" }, + "config": { + "example_api_url": "", + "example_api_token": "" + }, + "config_secrets": [ + "example_api_token" + ], "menu": { "label_key": "community.example.title", "icon": "puzzle",