Skip to content

feat: pin #sha256= on catalog downloads and verify all plugins against OpenWA 0.20.0 - #104

Merged
rmyndharis merged 1 commit into
mainfrom
feat/openwa-0.20-catalog-pins
Aug 16, 2026
Merged

feat: pin #sha256= on catalog downloads and verify all plugins against OpenWA 0.20.0#104
rmyndharis merged 1 commit into
mainfrom
feat/openwa-0.20-catalog-pins

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

OpenWA 0.20.0 makes a plugin install from a URL fail closed in production unless the URL carries a #sha256=<64 hex> content pin. The dashboard installs straight from the catalog's download link, so every catalog entry shipped an install that a production host now refuses. This pins the catalog and cuts the releases that carry it.

The catalog now publishes pinned URLs. catalog.mjs builds each plugin through package.mjs and pins the artifact digest into the download URL. The build is byte-deterministic (a local build of gsheets-logger 0.3.4 hashes identically to its published release asset), so the digest computed at catalog time is the digest the release will attach. catalog:check regenerates from a fresh build, which makes a stale pin a hard failure instead of a silently wrong one.

The release path guards the pin. After building the artifact, the workflow compares its digest against the catalog's pin and fails before the Release is created if they disagree, so a build that diverges from the catalog tree never publishes a pin that cannot verify. The release notes now tell URL installs to append the digest the same notes print.

All ten plugins cut a PATCH release. testedOpenWAVersion moves 0.19.0 → 0.20.0 across the catalog; no plugin code changed, because none of the 0.20.0 breaking changes reach the plugin runtime: the loader, sandbox, manifest validation and capability surface are untouched between the tags, and the pin requirement lives in the download funnel. Pinned URLs are backward compatible: 0.19.0 already parsed and verified the fragment, so older hosts gain the verification rather than a rejection.

Compatibility was verified against a running 0.20.0 host, not just the tags: all ten plugins install, take config, enable and register their hooks; supabase-otp-hook receives a signed ingress delivery through the full verify, dedup, enqueue and worker-dispatch path; and pinned install-url and update both succeed under PLUGIN_INSTALL_REQUIRE_PIN=true, while unpinned and wrongly pinned URLs are rejected. The vendored contract header records the 0.20.0 alignment: the diff over the six vendored host files is empty.

Verification

  • 587 tests pass, typecheck clean, catalog regenerated and drift-free (catalog:check), all ten bundles build and pass the loader contract.
  • Live host at 0.20.0: install, config and enable for all ten plugins, hook registration, signed ingress round trip, and pinned install-url and update through the production pin requirement.

Release

Ten tags, each pushed on its own so its release run triggers: after-hours-v0.2.3, chat-flow-v1.1.4, chatwoot-adapter-v0.9.3, faq-bot-v0.2.3, group-translate-v1.3.3, gsheets-logger-v0.3.5, http-action-v0.2.4, supabase-otp-hook-v0.3.2, typebot-connector-v0.2.4, voice-transcription-v1.2.5. Push the tags before merging so the pinned URLs resolve from the moment the catalog goes live on main.

…t OpenWA 0.20.0

OpenWA 0.20.0 refuses a plugin install from a URL in production unless the
URL carries a #sha256=<64 hex> content pin, and the dashboard installs
straight from the catalog's download link, so every catalog entry shipped an
install a production host now rejects. catalog.mjs now builds each plugin and
pins the artifact digest into the download URL (the build is
byte-deterministic, verified against a published release asset), and the
release workflow compares the built artifact against the pin before creating
the Release, so a diverging build fails loudly instead of shipping a pin that
can never verify.

All ten plugins cut a PATCH release carrying testedOpenWAVersion 0.20.0; no
plugin code changed, since the 0.20.0 breaking changes do not reach the
plugin runtime. Verified against a running 0.20.0 host: install, config,
enable and hook registration for all ten, a signed ingress delivery through
verify, dedup, enqueue and worker dispatch, and pinned install-url and update
under the production pin requirement.

after-hours 0.2.3 · chat-flow 1.1.4 · chatwoot-adapter 0.9.3 · faq-bot 0.2.3 ·
group-translate 1.3.3 · gsheets-logger 0.3.5 · http-action 0.2.4 ·
supabase-otp-hook 0.3.2 · typebot-connector 0.2.4 · voice-transcription 1.2.5
@rmyndharis
rmyndharis merged commit 3570e0f into main Aug 16, 2026
11 checks passed
@rmyndharis
rmyndharis deleted the feat/openwa-0.20-catalog-pins branch August 16, 2026 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant