Sync Repo-docs-CATALOG-TRUST-AND-LICENSING 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:0f1965ecc5bac2655f68195a -->
|
||||||
|
|
||||||
|
> 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, offline license
|
||||||
|
entitlements, and local artifact SHA-256 when artifact paths are supplied in an
|
||||||
|
install plan. Production-grade distribution still needs:
|
||||||
|
|
||||||
|
- remote registry/git artifact resolution before package-manager apply
|
||||||
|
- 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
|
||||||
Reference in New Issue
Block a user