Harden runtime distribution acceptance
This commit is contained in:
@@ -148,6 +148,16 @@ single-file deployer, its detached Ed25519 signature, and a signed, expiring
|
||||
distribution manifest. Evidence generation and signing run through the
|
||||
workflow's isolated release Python environment so their cryptographic tooling
|
||||
is explicit and independent of packages preinstalled in the Actions runner.
|
||||
Before publication, the exact amd64 and arm64 image manifests each run release
|
||||
migrations against the pinned PostgreSQL image, reach API and WebUI readiness
|
||||
as non-root/read-only processes, and complete a task through the pinned Redis
|
||||
image and packaged worker. Sanitized per-platform smoke receipts are retained
|
||||
as immutable release assets.
|
||||
|
||||
Ingress acceptance streams generated configuration into Docker-managed
|
||||
volumes before starting the read-only containers. It therefore also works when
|
||||
an Actions job reaches a host or remote Docker daemon through a mounted socket;
|
||||
the drill never assumes that a job-container path is visible to that daemon.
|
||||
|
||||
The manifest contract is
|
||||
[`runtime-distribution-manifest.schema.json`](runtime-distribution-manifest.schema.json),
|
||||
@@ -446,15 +456,27 @@ of the reviewed update recipe instead of a non-functional update button.
|
||||
|
||||
## Distribution Workflow
|
||||
|
||||
The downloadable entry point is a release asset. Obtain the zipapp, detached
|
||||
signature, checksum, and trusted public keyring through independently
|
||||
authenticated paths before execution:
|
||||
The downloadable entry point is a reproducible release asset: sorted source
|
||||
paths, fixed ZIP metadata, fixed compression settings, and identical source
|
||||
bytes produce an identical zipapp regardless of checkout timestamps. Obtain the
|
||||
zipapp, detached signature, checksum, and trusted public keyring through
|
||||
independently authenticated paths before execution:
|
||||
|
||||
```sh
|
||||
curl --proto '=https' --tlsv1.2 --fail --location \
|
||||
https://git.add-ideas.de/GovOPlaN/govoplan/releases/download/vX.Y.Z/govoplan-deploy.pyz \
|
||||
--output govoplan-deploy.pyz
|
||||
sha256sum --check govoplan-deploy.pyz.sha256
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
keyring = json.loads(Path("distribution-keyring.json").read_text())
|
||||
active = [key for key in keyring["keys"] if key["status"] == "active"]
|
||||
if len(active) != 1:
|
||||
raise SystemExit("expected exactly one active runtime release key")
|
||||
Path("runtime-release-public.pem").write_text(active[0]["public_key_pem"])
|
||||
PY
|
||||
openssl pkeyutl -verify -pubin -inkey runtime-release-public.pem -rawin \
|
||||
-in govoplan-deploy.pyz -sigfile govoplan-deploy.pyz.sig
|
||||
python3 govoplan-deploy.pyz init
|
||||
|
||||
Reference in New Issue
Block a user