Skip to content

feat(install): install from install.socket.dev/patch — trusted origin for the curl|sh installer - #145

Open
Mikola Lysenko (mikolalysenko) wants to merge 2 commits into
mainfrom
feat/hosted-installer
Open

feat(install): install from install.socket.dev/patch — trusted origin for the curl|sh installer#145
Mikola Lysenko (mikolalysenko) wants to merge 2 commits into
mainfrom
feat/hosted-installer

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

What

Points the documented one-liner at a Socket-controlled domain:

curl -fsSL https://install.socket.dev/patch | sh

install.socket.dev/patch serves a byte-for-byte copy of scripts/install.sh, with
its SHA-256 at /patch.sha256. The raw.githubusercontent.com URL keeps working and
serves the same bytes — the README keeps it as the alternative for anyone who would rather
not depend on the Socket domain.

The domain itself is stood up in the companion depscan PR, SocketDev/depscan#23840. Nothing here
breaks before that lands
— the drift workflow is inert until the host resolves, and the
README's alternative URL works today.

Why

The old URL asks a user to trust a third-party CDN for a script they pipe into a shell,
and it is the first URL a locked-down egress policy blocks. install.socket.dev is a name
Socket controls, already inside the trust boundary a customer grants socket.dev, and it
stays stable if the artifacts ever move.

The trust model is unchanged, and the docs are careful not to imply otherwise. Binaries
still come from the GitHub release and are still verified against its SHA256SUMS. Nothing
is signed. Hosting the script moved who serves the script, nothing more.

Commits

Commit Contents
feat(install): install from install.socket.dev/patch README one-liner + install.sh's own usage comment + docs/installer-hosting.md + CHANGELOG
ci(install): run the installer, pin its URL, and watch the hosted copy CI: end-to-end install, URL-consistency guard; new installer-drift workflow

CI additions

Three gaps around the artifact users are told to pipe into a shell:

  1. install.sh was only shellchecked, never run. CI now installs with it end to end
    and execs the result. It installs the latest release, not the checkout — on a
    version-bump PR that is deliberately the previous version. Verified the current release
    has the assets and SHA256SUMS format the script's awk expects
    (socket-patch-x86_64-unknown-linux-gnu.tar.gz matches on v3.3.0), so this step
    passes as written.
  2. Nothing kept the URL consistent across the README, the script's usage comment, and
    the runbook. A grep guard fails if any of them drifts.
  3. Nothing checked the hosted copy. installer-drift (weekly + workflow_dispatch)
    diffs the served bytes against scripts/install.sh, verifies the published checksum,
    and shellchecks what is actually served.

installer-drift is deliberately not part of CI: it tests a deployed artifact, so a
red run means "bump the submodule pin in depscan", not "this PR is broken". Two behaviors
keep it honest rather than noisy:

  • host does not resolve → reports "not deployed yet" and passes (inert pre-launch);
  • host answers non-200 → surfaces the specific failure this design is exposed to, a
    Cloudflare bot challenge, which would otherwise feed an HTML interstitial to sh.

Sequencing

The hosted copy is published from depscan's vendored submodules/socket-patch pin, so:

  1. this PR merges;
  2. depscan bumps submodules/socket-patch to that commit (its pin is currently 19 commits
    behind main, and install.sh does differ — main has the SC2144 detect_libc
    fix);
  3. depscan's prod deploy publishes it.

installer-drift will be red in the window between (1) and (3). That is the signal working
as designed — its error message says exactly which bump is missing.

A new socket-patch release needs none of this: the script resolves the latest release
itself at run time, so only edits to the script require a publish.

Verified locally

  • shellcheck --shell=sh scripts/install.sh and sh -n scripts/install.sh — clean
  • the URL-consistency loop passes across all three files
  • both workflow YAMLs parse
  • scripts/release-lint.sh version coherence OK (its CHANGELOG [3.3.0] complaint is
    pre-existing on main and only gates bump PRs)
  • release assets + SHA256SUMS line format confirmed against the live v3.3.0 release

Not run locally: the end-to-end install step (it installs into /usr/local/bin) — CI is
its first real execution.

Follow-up, not in scope

No Windows installer. install.sh is POSIX sh; native Windows users go through a
package manager or a release archive. A patch.ps1 object on the same host is the natural
addition and the hosting side already supports it — left out rather than shipped untested
from a macOS dev box.

    curl -fsSL https://install.socket.dev/patch | sh

The documented one-liner pointed at raw.githubusercontent.com. That asks
a user to trust a third-party CDN for a script they pipe into a shell,
and it is the first URL a locked-down egress policy blocks.
install.socket.dev is a name Socket controls, already inside the trust
boundary a customer grants socket.dev, and stable if the artifacts ever
move.

What the host serves is a byte-for-byte copy of scripts/install.sh, with
its SHA-256 alongside it at /patch.sha256 — the README tells people to
diff it, so that has to hold literally. The GitHub raw URL keeps working
and serves the same bytes, for anyone who would rather not depend on the
Socket domain.

The trust model is unchanged and the docs are careful not to imply
otherwise: binaries still come from the GitHub release and are still
verified against its SHA256SUMS, and nothing is signed. Hosting the
script moved who serves the script, nothing more.

docs/installer-hosting.md is the runbook for the part that is not
obvious from this repository: the copy is published out of depscan's
vendored submodules/socket-patch pin, so an installer change here goes
live on a submodule bump + deploy — while a new socket-patch release
needs no publish at all, since the script resolves the latest release
itself at run time.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three gaps around the thing users are told to pipe into a shell:

1. install.sh was only shellchecked, never run. CI now installs with it
   end to end and execs the result, so "downloads the latest release,
   verifies SHA256SUMS, produces a binary that starts" is asserted on
   every PR instead of discovered by a user. (It installs the latest
   RELEASE, not the checkout — on a bump PR that is deliberately the
   previous version.)

2. Nothing kept the URL consistent. The README, the script's own usage
   comment, and the hosting runbook all name it; a grep guard fails if
   any of them drifts.

3. Nothing checked the HOSTED copy. install.socket.dev/patch is
   published from depscan's submodule pin, so it can lag this repo
   silently. The new `installer-drift` workflow (weekly + dispatch)
   diffs the served bytes against scripts/install.sh, verifies the
   published checksum, and shellchecks what is actually served.

The drift job is deliberately not part of CI: it tests a deployed
artifact, so a red run means "bump the pin in depscan", not "this PR is
broken". Two behaviors keep it honest rather than noisy — if the host
does not resolve it reports "not deployed yet" and passes, so it is
inert until the domain exists; and if the host answers non-200 it
surfaces the specific failure this design is exposed to, a Cloudflare
bot challenge, which would otherwise feed an HTML interstitial to sh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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