diff --git a/Repo-docs-RELEASE-CATALOG-WORKFLOW.md b/Repo-docs-RELEASE-CATALOG-WORKFLOW.md new file mode 100644 index 0000000..4e61d8f --- /dev/null +++ b/Repo-docs-RELEASE-CATALOG-WORKFLOW.md @@ -0,0 +1,135 @@ + + +> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_CATALOG_WORKFLOW.md`. +> Origin: `repository`. +> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context. + +--- +# Release Catalog Workflow + +GovOPlaN release catalogs are published by `govoplan-web` as static JSON and +verified by `govoplan-core` before installer plans are accepted. + +Private signing keys must stay outside all git repositories. Public keyrings +are published with the website. + +## One-Time Key Setup + +Create the first catalog signing key on the release machine: + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +mkdir -p "$KEY_DIR" +./.venv/bin/python scripts/generate-catalog-keypair.py \ + --key-id release-key-1 \ + --private-key "$KEY_DIR/release-key-1.pem" \ + --public-key "$KEY_DIR/release-key-1.pub" \ + --keyring "$KEY_DIR/catalog-keyring.json" +``` + +Keep `release-key-1.pem` private. The generated keyring contains only public +material. + +## Publish Current Release Catalog + +Generate the signed catalog into `govoplan-web`: + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +scripts/publish-release-catalog.sh \ + --version 0.1.4 \ + --sequence 202607071340 \ + --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ + --build-web +``` + +This writes: + +- `/mnt/DATA/git/govoplan-web/public/catalogs/v1/channels/stable.json` +- `/mnt/DATA/git/govoplan-web/public/catalogs/v1/keyring.json` + +The wrapper validates the catalog with core using the generated public keyring. + +## Publish After A New Release + +For normal module/core releases, first tag and push the module/core repos. Then +publish the website catalog: + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +scripts/publish-release-catalog.sh \ + --version \ + --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ + --build-web \ + --commit \ + --tag \ + --push +``` + +The website tag is `catalog-v`. The public URL is: + +```text +https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json +``` + +The public keyring URL is: + +```text +https://govoplan.add-ideas.de/catalogs/v1/keyring.json +``` + +## Integrated Release Script + +`scripts/push-release-tag.sh` can publish the web catalog after module and core +tags have been pushed: + +```bash +cd /mnt/DATA/git/govoplan-core +KEY_DIR="$HOME/.config/govoplan/release-keys" +scripts/push-release-tag.sh \ + --bump subversion \ + --publish-web-catalog \ + --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \ + --build-web-catalog +``` + +Use `--catalog-signing-key` more than once during a key rotation window. The +catalog will contain multiple signatures and the public keyring will include the +corresponding public keys. + +## Consumer Configuration + +On a GovOPlaN installation that should consume the official stable catalog: + +```bash +GOVOPLAN_MODULE_PACKAGE_CATALOG_URL=https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/catalog-cache/stable.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true +GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable +GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/catalog-keyring.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json +GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true +``` + +For production, copy the public keyring into deployment configuration and pin it +locally. Do not rely on a URL-fetched keyring as the only trust root. + +## Core Updates + +`stable.json` includes a top-level `core_release` section for operator/update +tooling. Core is intentionally not listed as a normal module entry, because it +must not be added to saved enabled-module state. Core upgrades should remain an +operator-supervised package update with restart and health checks. + +## Key Rotation + +1. Generate the next private key outside git. +2. Run `publish-release-catalog.sh` with both signing keys. +3. Publish the web catalog/keyring. +4. Roll the new public keyring into installations. +5. Stop signing with the old key after the supported fleet trusts the new key. +6. Mark compromised keys as revoked in the public keyring and publish a higher + sequence catalog signed by a trusted uncompromised key. diff --git a/Repo-docs-RELEASE-DEPENDENCIES.md b/Repo-docs-RELEASE-DEPENDENCIES.md index 35b12d0..cc24994 100644 --- a/Repo-docs-RELEASE-DEPENDENCIES.md +++ b/Repo-docs-RELEASE-DEPENDENCIES.md @@ -1,4 +1,4 @@ - + > Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`. > Origin: `repository`. @@ -271,8 +271,11 @@ GOVOPLAN_LICENSE_ENFORCEMENT=true ``` See `docs/CATALOG_TRUST_AND_LICENSING.md` for key rotation, replay protection, -and licensing details. Unsigned catalogs remain usable for local development -when signature enforcement is off, but the admin UI labels them as unsigned. +and licensing details. See `docs/RELEASE_CATALOG_WORKFLOW.md` for the concrete +release-machine workflow that generates signing keys and publishes signed +catalogs through `govoplan-web`. Unsigned catalogs remain usable for local +development when signature enforcement is off, but the admin UI labels them as +unsigned. Install rows must use tagged package/git refs or registry packages, not local `file:` or workspace links. The installer daemon can run `npm install` and