Skip to content

feat(install): install from install.socket.dev, optionally without github.com - #145

Merged
Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
feat/hosted-installer
Aug 14, 2026
Merged

feat(install): install from install.socket.dev, optionally without github.com#145
Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
feat/hosted-installer

Conversation

@mikolalysenko

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

Copy link
Copy Markdown
Collaborator

Points the documented one-liner at a Socket-controlled domain, and lets the archives come
from Socket too:

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

The old URL was raw.githubusercontent.com — a third-party CDN serving a script users pipe
into a shell, and the first URL a locked-down egress policy blocks.

Companion PR: SocketDev/depscan#23840, which serves the host. Nothing here breaks before
that lands
: the drift workflow and the Socket-origin CI step are both inert until the
host resolves, and the README's alternative URL works today.

What the host serves

A byte-for-byte copy of scripts/install.sh, with its SHA-256 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.

Installing without reaching github.com

New SOCKET_PATCH_BASE_URL points the archive downloads at any releases base answering
GitHub's two asset paths:

curl -fsSL https://install.socket.dev/patch \
  | SOCKET_PATCH_BASE_URL=https://install.socket.dev/patch/SocketDev/socket-patch/releases sh

install.socket.dev relays exactly those paths from the GitHub release, which is why one
template covers both origins and the script needs no branching.

A new release needs no publish for this. The origin resolves "latest" per request
against the upstream release, so cutting 3.4.0 makes it installable from Socket's host
immediately — nothing runs at release time.

socket-patch --update can use the same host today with no CLI changes, via the
SOCKET_UPDATE_BASE_URL override it already has. One caveat documented rather than papered
over: a non-default value intentionally downgrades the downloaded binary's version
self-check from hard-fail to a warning, because that knob targets mirrors that may
repackage. Making Socket's host a first-class endpoint set that keeps the strict check is a
CLI change, not a hosting one — deliberately not here.

Also adds SOCKET_PATCH_INSTALL_DIR, which wins over both existing defaults: what
unprivileged installs into a toolchain-managed prefix need, and what makes the script
testable without writing to a system path.

Trust model: unchanged, and the docs say so

Binaries still come from the GitHub release and are still verified against its
SHA256SUMS. Nothing is signed. Whichever origin serves the bytes, the checksums come from
that same origin. Hosting moved who serves the script, nothing more.

The default origin is still GitHub, on purpose

Flipping it is one line, held until the relay is verified in prod. A script defaulting to a
host that does not answer yet is a broken installer for everyone running it from a git
checkout or the raw URL — and CI's end-to-end install step would fail on main
immediately. Sequence: this merges → depscan#23840 deploys → flip the default.

Four gaps closed around a curl | sh artifact

  1. install.sh was only shellchecked, never run. CI now installs with it end to end
    and execs the result — twice, once with the default origin and once through
    SOCKET_PATCH_BASE_URL, so the URL template is covered too.
  2. A third step installs through install.socket.dev and asserts the installed version
    matches what that host reports as latest. Skips itself with a notice until the host
    resolves.
  3. Nothing kept the URL consistent across the README, the script's usage comment, and
    the runbook; a grep guard fails if any drifts.
  4. Nothing checked the hosted copy. New installer-drift workflow (weekly + dispatch)
    diffs the served bytes against scripts/install.sh, verifies the published checksum, and
    shellchecks what is served. 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". It also names the
    specific failure this design is exposed to: a Cloudflare bot challenge, which would
    otherwise feed an HTML interstitial to sh.

docs/installer-hosting.md is the runbook for the non-obvious part: the hosted copy is
published from depscan's vendored submodule pin, so an installer change here goes live on a
submodule bump plus a deploy.

Verified

CI green on the pre-squash commits — all six Shell steps in lint-ecosystems passed,
including both end-to-end installs, and the Socket-origin step correctly emitted
install.socket.dev/patch/latest does not answer yet — skipping. Locally, against the real
relay: latest and pinned installs both succeeded and were checksum-verified, and
socket-patch --update worked through the same host (--dry-run resolved latest;
--update 3.2.0 downloaded and swapped).

The only failing check is hosted-e2e / gem_bundler_hosted_redirect_and_known_install_defect
— the known gem/Bundler marshal data too short defect against rubygems.org, unrelated to
this change.

Sequencing note

depscan's submodule pin is 19 commits behind main, and scripts/install.sh does
differ (main has the SC2144 detect_libc fix). So: merge this → bump the pin → deploy.
installer-drift is red in that window by design, and its error message says which bump is
missing.

Not in scope

  • Flipping the default origin (one-line follow-up after prod verification).
  • patch.ps1 for native Windows — the hosting side already supports it; left out rather
    than shipped untested from a macOS box.

…thub.com

The documented one-liner becomes

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

replacing a raw.githubusercontent.com URL that asked users to trust a
third-party CDN for a script they pipe into a shell, and that 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.

What the host serves is a byte-for-byte copy of scripts/install.sh, with its
SHA-256 alongside 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.

Archives can come from Socket too. New SOCKET_PATCH_BASE_URL points the
downloads at any releases base answering GitHub's two asset paths,
`<base>/latest/download/<file>` and `<base>/download/v<ver>/<file>`:

    curl -fsSL https://install.socket.dev/patch \
      | SOCKET_PATCH_BASE_URL=https://install.socket.dev/SocketDev/socket-patch/releases sh

install.socket.dev relays exactly those paths from the GitHub release
(SocketDev/depscan#23840), which is why one template covers both origins and
the script needs no branching. A new socket-patch RELEASE needs no publish
for any of this: the origin resolves "latest" per request against the
upstream release, so nothing runs at release time.

The default origin stays GitHub here. Flipping it is one line, held until the
relay is verified in prod — a script defaulting to a host that does not answer
yet is a broken installer for everyone running it from a git checkout or the
raw URL, and CI's end-to-end install step would fail on main immediately.

Also adds SOCKET_PATCH_INSTALL_DIR, which wins over both existing defaults:
what unprivileged installs into a toolchain-managed prefix need, and what
makes the script testable without writing to a system path.

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. Whichever origin serves the bytes, the
checksums come from that same origin. Hosting moved who serves the script,
nothing more.

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

* install.sh was only shellchecked, never run. CI now installs with it end to
  end and execs the result — twice, once with the default origin and once
  through SOCKET_PATCH_BASE_URL, so the URL template is covered too.
* A third CI step installs through install.socket.dev and asserts the
  installed version matches what that host reports as latest. It skips itself
  with a notice until the host resolves, so it is inert until the relay ships
  rather than red from merge.
* Nothing kept the URL consistent across the README, the script's own usage
  comment, and the runbook; a grep guard fails if any of them drifts.
* Nothing checked the HOSTED copy. 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. 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". It also names the
  specific failure this design is exposed to — a Cloudflare bot challenge,
  which would otherwise feed an HTML interstitial to sh.

docs/installer-hosting.md is the runbook for the part that is not obvious from
this repository: the hosted copy is published out of depscan's vendored
submodule pin, so an installer change here goes live on a submodule bump plus
a deploy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) changed the title feat(install): install from install.socket.dev/patch — trusted origin for the curl|sh installer feat(install): install from install.socket.dev, optionally without github.com Aug 6, 2026

@jdalton John-David Dalton (jdalton) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three things, all inline. The big one: pointing SOCKET_PATCH_BASE_URL at the host adds Socket's stack to the trust set rather than dropping GitHub, and SHA256SUMS rides the same origin as the archive. docs/installer-hosting.md says the trust model is unchanged, which holds for the default only.

One not inline, since the file is not in the diff: SOCKET_UPDATE_BASE_URL drops the https-only redirect rule in update/release.rs too.

Comment thread scripts/install.sh
Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
Comment thread docs/installer-hosting.md
Comment thread docs/installer-hosting.md
Comment thread README.md
Comment thread scripts/install.sh
Assisted-by: Claude Code:claude-fable-5
install.socket.dev reserves its root for other Socket components, so the
GitHub-shaped relay routes live under /patch/... — update every example
base URL and the CI Socket-origin step to match what the relay answers,
and give the SOCKET_UPDATE_BASE_URL example the /patch base it needs.

Assisted-by: Claude Code:claude-fable-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit a77bb1c into main Aug 14, 2026
63 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the feat/hosted-installer branch August 14, 2026 21:17
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.

3 participants