Publish and security
Package a plugin
Section titled “Package a plugin”yonto-plugin bundleBuilds the publishable file, dist/<id>-<version>.js, and a zip of it, dist/<id>-<version>.zip, and prints the zip’s size and its SHA-256.
The zip holds one entry, the same file, compressed.
Put the zip anywhere that serves it over HTTPS, such as a GitHub release. A viewer installs it with Settings, Plugins, Install from URL.
Published bytes never change
Section titled “Published bytes never change”Once a version is public, never replace the file at its address.
A repo pins each plugin by its SHA-256, so a file that changed under the same address is refused, correctly.
Fix a plugin by raising version, bundling again, and publishing a new address.
Make a repo
Section titled “Make a repo”A repo is one address that lists many plugins, so a viewer adds all of them at once. Put your plugins in one directory, one folder each, and run:
yonto-plugin index plugins --base-url https://plugins.example.com > index.jsonIt bundles each plugin and writes the index: for each, an entry whose address is <base-url>/<id>/<id>-<version>.zip#sha256=….
Upload the zips where the addresses say, and index.json at the address you will give viewers.
Then check what you published, from the outside, as a viewer’s Yonto will:
yonto-plugin index --check https://plugins.example.com/index.jsonIt downloads the index and every plugin it lists, and holds each to its SHA-256, manifest and the rules above. It reports every problem, not just the first.
A viewer adds the repo under Settings, Repos, Add a repo.
What a viewer is told
Section titled “What a viewer is told”The install dialog shows a plugin’s name, its version and where it can reach, which comes from the manifest. So the manifest is the plugin’s promise, and the viewer is the one who agrees to it.
- Reach as few hosts as you can, and write them as exact hosts. A wildcard that covers a host you do not need asks the viewer to trust more.
- A plugin that sets
hostsFromConfigasks the viewer a further question, and Yonto does not run it before the answer. Only the kind of plugin that reads addresses the viewer supplies can justify one. - Never send a viewer’s key, token or typed text to a host the viewer did not choose.
- A plugin can never reach a private address on its own, such as
localhost,192.168.x.xor*.local. Only an address the viewer typed into aurlfield is allowed. That is how a plugin for a server on the viewer’s own network works at all, and whyallowedHostsfor it is empty.
Plugins are code, and they run in a sandbox with no files, no sockets and no timers, which is why the only way out is yonto.fetch.
A viewer should still only install one from an address they trust, and you should write yours so that one who did not read it could not be hurt by it.
A checklist before you publish
Section titled “A checklist before you publish”lintanddoctor --replayare green.contractVersionis whatlintasks for, and no more.allowedHostsis as small as it can be.- Every
reasonyou throw names the part that failed, in one sentence, and the logs hold no URL, key or query. doctor.jsonandfixtures/contain no key and no cookie.versionis new.