feat(cli): install without Node.js and upgrade from signed releases - #141
Merged
Merged
Conversation
Users without Node.js had no way to install the CLI, and no install ever learned about a newer release. A standalone install now upgrades itself only after a signed release manifest verifies, and an npm install prints the command for its package runner.
Contributor
🤖 MERGED
GitHub merged this pull request. No material findings were recorded. 3688a912-9b12-4a9a-988e-00d41290d0ba |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
❓ Type of change
📚 Description
Using skilld without Node.js wasn't possible, and no install ever heard about a newer release.
install.shandinstall.ps1now install one native binary from the GitHub release. That install upgrades itself in the background, and the command prints "Restart skilld to use it". An npm install prints the upgrade command for its runner:npx skilld@latest,pnpm add --global skilld, and so on.A digest file downloaded from the same release protects nothing: whoever can change the release can change both files. So release CI signs a release manifest with an Ed25519 key that exists only as a secret in the one signing step. The CLI checks the signature, the exact version, and the binary digest before it writes a file beside the executable. It never downgrades, and a build without a compiled release key never upgrades itself.
Upgrades only run for a person at a terminal: not in CI, not under an Agent, and not with
SKILLD_NO_UPGRADE=1.Open questions:
install.shchecks the signature only where OpenSSL supports Ed25519, and macOS LibreSSL doesn't. There it falls back to HTTPS plus the digest, as rustup and bun do.install.ps1always does. Worth servinginstall.shfrom skilld.dev too, so the script and the binaries come from two different origins?CLI upgradeandrelease manifestto GLOSSARY.md. "Upgrade" keeps it apart fromskilld update, which updates Skills.📝 Migration
Before the next release tag, create the release key. Run this once, then store the printed seed somewhere offline:
It sets the
SKILLD_RELEASE_SIGNING_KEYsecret and theSKILLD_RELEASE_PUBLIC_KEYvariable. The release workflow fails without them. If the seed is lost, installs on older versions cannot verify newer releases, and those users must run the install script again.