Sync wiki from project files
191
Repo-docs-CATALOG-TRUST-AND-LICENSING.md
Normal file
191
Repo-docs-CATALOG-TRUST-AND-LICENSING.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
<!-- codex-wiki-sync:36e407f77dd59c0601fa5063 -->
|
||||||
|
|
||||||
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/CATALOG_TRUST_AND_LICENSING.md`.
|
||||||
|
> Origin: `repository`.
|
||||||
|
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
|
||||||
|
|
||||||
|
---
|
||||||
|
# Module Catalog Trust And Licensing
|
||||||
|
|
||||||
|
GovOPlaN module install and uninstall must remain operator-controlled. The
|
||||||
|
running server may plan and validate package changes, but package mutation is
|
||||||
|
performed by the separate installer daemon or an operator shell during
|
||||||
|
maintenance mode.
|
||||||
|
|
||||||
|
## Roles
|
||||||
|
|
||||||
|
`govoplan-web` is the public static distribution surface for official catalog
|
||||||
|
resources:
|
||||||
|
|
||||||
|
- signed module package catalogs, grouped by release channel
|
||||||
|
- public catalog keyrings
|
||||||
|
- public license verification keyrings
|
||||||
|
- examples and operator-facing download paths
|
||||||
|
|
||||||
|
`govoplan-core` is the verifier and orchestrator:
|
||||||
|
|
||||||
|
- fetches a local or remote module catalog
|
||||||
|
- verifies catalog signatures against configured trusted keys
|
||||||
|
- enforces approved release channels
|
||||||
|
- rejects expired or not-yet-valid catalogs
|
||||||
|
- records accepted catalog sequence numbers for replay protection
|
||||||
|
- checks catalog entry license feature requirements before planning installs
|
||||||
|
- writes installer plans and request records
|
||||||
|
|
||||||
|
Feature and platform modules own their package artifacts, manifests, migration
|
||||||
|
metadata, retirement providers, and optional lifecycle behavior.
|
||||||
|
|
||||||
|
## Catalog Source
|
||||||
|
|
||||||
|
Core accepts either a local catalog file or a remote URL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG=/srv/govoplan/catalogs/stable.json
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_URL=https://govoplan.example/catalogs/v1/channels/stable.json
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/catalog-cache/stable.json
|
||||||
|
```
|
||||||
|
|
||||||
|
If both file and URL are set, the URL wins. The cache is used when a remote
|
||||||
|
fetch fails, so an operator can still inspect the last known catalog. A cached
|
||||||
|
catalog must still pass signature, freshness, channel, and replay validation.
|
||||||
|
|
||||||
|
## Catalog Shape
|
||||||
|
|
||||||
|
An official catalog is a JSON object with:
|
||||||
|
|
||||||
|
- `catalog_version`
|
||||||
|
- `channel`
|
||||||
|
- `sequence`
|
||||||
|
- `generated_at`
|
||||||
|
- `not_before` when delayed activation is needed
|
||||||
|
- `expires_at`
|
||||||
|
- `modules`
|
||||||
|
- `signatures`
|
||||||
|
|
||||||
|
Each module entry can declare:
|
||||||
|
|
||||||
|
- backend package name and pinned install reference
|
||||||
|
- WebUI package name and pinned install reference
|
||||||
|
- display metadata and tags
|
||||||
|
- `license_features`, the feature entitlements required to plan that install
|
||||||
|
|
||||||
|
The signature is Ed25519 over canonical JSON with both `signature` and
|
||||||
|
`signatures` removed. Core accepts the legacy single `signature` field and the
|
||||||
|
new `signatures` array.
|
||||||
|
|
||||||
|
## Keyrings And Rotation
|
||||||
|
|
||||||
|
Trusted catalog keys are configured locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/catalog-keyring.json
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS='{"release-key-1":"<base64 public key>"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
For development or tightly controlled deployments, a keyring can be read from a
|
||||||
|
URL and cached:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_URL=https://govoplan.example/catalogs/v1/keyring.json
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_CACHE=/srv/govoplan/runtime/catalog-cache/keyring.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Production installations should pin the trusted keyring locally or ship it
|
||||||
|
through deployment configuration. Fetching trusted keys from the same public
|
||||||
|
origin as the catalog is convenient, but that origin must not become the only
|
||||||
|
trust root.
|
||||||
|
|
||||||
|
Keyring entries support:
|
||||||
|
|
||||||
|
- `key_id`
|
||||||
|
- `public_key` or `public_key_base64`
|
||||||
|
- `status`: `active`, `next`, `retired`, `revoked`, or `disabled`
|
||||||
|
- `not_before`
|
||||||
|
- `not_after`
|
||||||
|
|
||||||
|
Rotation process:
|
||||||
|
|
||||||
|
1. Add the next public key to the local trusted keyring with status `next`.
|
||||||
|
2. Publish catalogs signed by both current and next keys.
|
||||||
|
3. Upgrade installations so the next key is locally trusted.
|
||||||
|
4. Promote the next key to `active`.
|
||||||
|
5. Retire the old key only after every supported installation trusts the new
|
||||||
|
key.
|
||||||
|
6. Mark a compromised key `revoked` and publish a higher sequence catalog
|
||||||
|
signed by an uncompromised key.
|
||||||
|
|
||||||
|
## Replay And Freshness
|
||||||
|
|
||||||
|
Use replay state in production:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true
|
||||||
|
```
|
||||||
|
|
||||||
|
Core records the accepted sequence per channel after a catalog entry is planned
|
||||||
|
from the admin interface. With strict sequence enforcement, a previously
|
||||||
|
accepted sequence is rejected; without strict enforcement, only older sequences
|
||||||
|
are rejected.
|
||||||
|
|
||||||
|
Catalogs should always expire. Long-lived catalogs make rollback and key
|
||||||
|
compromise harder to reason about.
|
||||||
|
|
||||||
|
## Release Channels
|
||||||
|
|
||||||
|
Approved channels are deployment policy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable,lts
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true
|
||||||
|
```
|
||||||
|
|
||||||
|
The admin UI can display other catalog metadata, but core rejects catalogs from
|
||||||
|
unapproved channels when validation is configured.
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
Catalog entries can require license features:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"license_features": ["module.mail", "support.standard"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Core checks those requirements against an offline license file before allowing
|
||||||
|
the entry into the install plan.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_LICENSE_FILE=/srv/govoplan/license.json
|
||||||
|
GOVOPLAN_LICENSE_ENFORCEMENT=true
|
||||||
|
GOVOPLAN_LICENSE_TRUSTED_KEYS_FILE=/srv/govoplan/trust/license-keyring.json
|
||||||
|
```
|
||||||
|
|
||||||
|
License files are JSON objects with:
|
||||||
|
|
||||||
|
- `license_id`
|
||||||
|
- `subject`
|
||||||
|
- `features`
|
||||||
|
- `valid_from`
|
||||||
|
- `valid_until`
|
||||||
|
- `signature`
|
||||||
|
|
||||||
|
License enforcement can run in observe-only mode by leaving
|
||||||
|
`GOVOPLAN_LICENSE_ENFORCEMENT` unset. In that mode, missing or invalid license
|
||||||
|
data is surfaced as a warning but does not block planning.
|
||||||
|
|
||||||
|
Licensing is intentionally separate from open-source code licensing. The
|
||||||
|
catalog/license mechanism can govern support channels, official release
|
||||||
|
eligibility, hosted update access, professional support, or commercial
|
||||||
|
entitlements without changing the source license of the repositories.
|
||||||
|
|
||||||
|
## Production Gaps
|
||||||
|
|
||||||
|
The current implementation validates signed catalog metadata and offline
|
||||||
|
license entitlements. Production-grade distribution still needs:
|
||||||
|
|
||||||
|
- artifact digest verification for package archives or registry artifacts
|
||||||
|
- SBOM/provenance fields and verification workflow
|
||||||
|
- hardened catalog publishing pipeline in `govoplan-web`
|
||||||
|
- automated key rotation runbook and emergency revocation procedure
|
||||||
|
- license issuance and renewal tooling
|
||||||
|
- tests for remote catalog cache fallback and replay-state upgrades
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:97f252ae80996d8ee236fd44 -->
|
<!-- codex-wiki-sync:24b67ceb3231203599e59944 -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -31,6 +31,7 @@ The kernel target owns:
|
|||||||
- the server entry point and platform configuration
|
- the server entry point and platform configuration
|
||||||
- module discovery, manifest validation, registry validation, route aggregation, and platform metadata APIs
|
- module discovery, manifest validation, registry validation, route aggregation, and platform metadata APIs
|
||||||
- database engine/session lifecycle and module migration orchestration
|
- database engine/session lifecycle and module migration orchestration
|
||||||
|
- module install-plan validation, signed catalog verification, license entitlement checks, and installer request orchestration
|
||||||
- capability registry, command/event contracts, and lifecycle hooks
|
- capability registry, command/event contracts, and lifecycle hooks
|
||||||
- shared WebUI shell contracts, generic WebUI components, and module route/nav rendering
|
- shared WebUI shell contracts, generic WebUI components, and module route/nav rendering
|
||||||
- centralized mapping from serializable icon names to renderable frontend icons
|
- centralized mapping from serializable icon names to renderable frontend icons
|
||||||
@@ -160,6 +161,7 @@ A module owns:
|
|||||||
- module migrations and migration metadata
|
- module migrations and migration metadata
|
||||||
- module permissions and role templates
|
- module permissions and role templates
|
||||||
- module-specific schemas, policies, and domain rules
|
- module-specific schemas, policies, and domain rules
|
||||||
|
- module package metadata and retirement providers used by install/uninstall preflight
|
||||||
- WebUI pages, feature-specific components, API clients, route contributions, and navigation metadata
|
- WebUI pages, feature-specific components, API clients, route contributions, and navigation metadata
|
||||||
|
|
||||||
A module should not own generic platform UI. If a component is useful outside one module, move it to `@govoplan/core-webui` and parameterize it there before reusing it.
|
A module should not own generic platform UI. If a component is useful outside one module, move it to `@govoplan/core-webui` and parameterize it there before reusing it.
|
||||||
@@ -215,6 +217,34 @@ Rules:
|
|||||||
should compare the database heads to the configured script heads instead of
|
should compare the database heads to the configured script heads instead of
|
||||||
assuming one linear revision when multiple modules are enabled.
|
assuming one linear revision when multiple modules are enabled.
|
||||||
|
|
||||||
|
## Install, Uninstall, And Catalogs
|
||||||
|
|
||||||
|
Core owns the install plan, signed catalog validation, license entitlement
|
||||||
|
check, maintenance-mode guard, replay state, and installer request queue.
|
||||||
|
Package mutation is performed by `govoplan-module-installer` outside the
|
||||||
|
FastAPI request process.
|
||||||
|
|
||||||
|
Official catalogs can be served as static JSON from `govoplan-web`, but core
|
||||||
|
does not trust the website by location alone. A catalog must pass the configured
|
||||||
|
signature, channel, freshness, and replay rules before a catalog entry can be
|
||||||
|
planned. Catalog entries may declare `license_features`; core checks those
|
||||||
|
against the configured offline license before adding the entry to the install
|
||||||
|
plan.
|
||||||
|
|
||||||
|
Modules should provide:
|
||||||
|
|
||||||
|
- pinned backend and WebUI package refs for official catalog entries
|
||||||
|
- compatibility metadata in the module manifest
|
||||||
|
- lifecycle hooks when a runtime enable/disable action needs module-specific
|
||||||
|
work
|
||||||
|
- uninstall guards for persistent data, active workers, schedulers, or external
|
||||||
|
bindings
|
||||||
|
- retirement providers when destructive uninstall can safely drop or retire
|
||||||
|
module-owned data
|
||||||
|
|
||||||
|
Uninstall remains non-destructive unless the operator explicitly requests
|
||||||
|
`destroy_data` and the module provides a retirement provider that supports it.
|
||||||
|
|
||||||
## WebUI Contract
|
## WebUI Contract
|
||||||
|
|
||||||
A WebUI module exports a `PlatformWebModule` from its package. The object contributes local/fallback metadata and route render functions.
|
A WebUI module exports a `PlatformWebModule` from its package. The object contributes local/fallback metadata and route render functions.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!-- codex-wiki-sync:874f18ab843f9c893d212d76 -->
|
<!-- codex-wiki-sync:e178a363f47dd4c65d49cb2c -->
|
||||||
|
|
||||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`.
|
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/RELEASE_DEPENDENCIES.md`.
|
||||||
> Origin: `repository`.
|
> Origin: `repository`.
|
||||||
@@ -198,19 +198,30 @@ govoplan-module-installer --cancel-request <request-id> --format json
|
|||||||
govoplan-module-installer --retry-request <request-id> --format json
|
govoplan-module-installer --retry-request <request-id> --format json
|
||||||
```
|
```
|
||||||
|
|
||||||
Package catalogs are file-backed. Set `GOVOPLAN_MODULE_PACKAGE_CATALOG` to a
|
Package catalogs can be local files or remote static resources, for example
|
||||||
JSON file matching `docs/module-package-catalog.example.json`; the admin UI will
|
served by `govoplan-web`. Set `GOVOPLAN_MODULE_PACKAGE_CATALOG` for a local file
|
||||||
show those entries and can save them into the install plan. This keeps the
|
or `GOVOPLAN_MODULE_PACKAGE_CATALOG_URL` for a remote catalog matching
|
||||||
release approval decision outside the running server while avoiding hand-typed
|
`docs/module-package-catalog.example.json`; the admin UI will show those entries
|
||||||
package refs. Validate the catalog before handing it to operators:
|
and can save them into the install plan. This keeps the release approval
|
||||||
|
decision outside the running server while avoiding hand-typed package refs.
|
||||||
|
Remote catalogs can be cached for offline inspection:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_URL=https://govoplan.example/catalogs/v1/channels/stable.json
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/catalog-cache/stable.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Validate the catalog before handing it to operators:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
govoplan-module-installer --validate-package-catalog docs/module-package-catalog.example.json --format json
|
govoplan-module-installer --validate-package-catalog docs/module-package-catalog.example.json --format json
|
||||||
```
|
```
|
||||||
|
|
||||||
Release catalogs should be signed and channel-gated. The supported signing
|
Release catalogs should be signed, channel-gated, expiring, and sequence
|
||||||
format is an Ed25519 signature over the canonical catalog JSON object with the
|
tracked. The supported signing format is an Ed25519 signature over the
|
||||||
`signature` field removed. Sign a catalog with:
|
canonical catalog JSON object with the `signature` and `signatures` fields
|
||||||
|
removed. Core accepts the legacy single `signature` field and the newer
|
||||||
|
`signatures` array used during key rotation. Sign a catalog with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
govoplan-module-installer \
|
govoplan-module-installer \
|
||||||
@@ -238,10 +249,30 @@ GOVOPLAN_MODULE_PACKAGE_CATALOG=/path/to/catalog.json
|
|||||||
GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true
|
||||||
GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable
|
||||||
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS='{"release-key-1":"<base64-ed25519-public-key>"}'
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS='{"release-key-1":"<base64-ed25519-public-key>"}'
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json
|
||||||
|
GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true
|
||||||
```
|
```
|
||||||
|
|
||||||
Unsigned catalogs remain usable for local development when signature
|
Trusted keys can also be loaded from
|
||||||
enforcement is off, but the admin UI labels them as unsigned.
|
`GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE`. A URL-backed keyring is
|
||||||
|
supported for development and tightly controlled deployments through
|
||||||
|
`GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_URL` plus
|
||||||
|
`GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_CACHE`, but production systems
|
||||||
|
should pin trusted keys locally.
|
||||||
|
|
||||||
|
Catalog entries can declare `license_features`. If
|
||||||
|
`GOVOPLAN_LICENSE_ENFORCEMENT=true`, core blocks planning catalog installs
|
||||||
|
whose required features are not present in the configured offline license:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOVOPLAN_LICENSE_FILE=/srv/govoplan/license.json
|
||||||
|
GOVOPLAN_LICENSE_TRUSTED_KEYS_FILE=/srv/govoplan/trust/license-keyring.json
|
||||||
|
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.
|
||||||
|
|
||||||
Install rows must use tagged package/git refs or registry packages, not local
|
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
|
`file:` or workspace links. The installer daemon can run `npm install` and
|
||||||
|
|||||||
Reference in New Issue
Block a user