The documented one-liner is
curl -fsSL https://install.socket.dev/patch | shinstall.socket.dev/patch serves a byte-for-byte copy of
scripts/install.sh — not a rendered template, not a
different script. The README says so, so it has to stay true.
The one-liner used to point 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
it stays stable if the artifacts ever move.
The GitHub URL still works and still serves the same bytes. Anyone who would rather not add a dependency on the Socket domain can keep using it.
By default the script downloads archives from the GitHub release. Point it
somewhere else with SOCKET_PATCH_BASE_URL — a releases base that answers
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/patch/SocketDev/socket-patch/releases shinstall.socket.dev relays those exact paths from the GitHub release, which is
why one template covers both origins and the script needs no branching. It also
exposes a cleaner shape for humans and for scripts that want the version:
| Endpoint | Serves |
|---|---|
install.socket.dev/patch/latest |
the latest version as plain text (3.4.0) |
install.socket.dev/patch/dl/v3.4.0/<asset> |
that release's asset, immutably cached |
install.socket.dev/patch/dl/latest/<asset> |
the same asset from whatever is latest |
A new release needs no publish for any of this. "Latest" is resolved per
request against the upstream release, so cutting 3.4.0 makes it installable from
install.socket.dev immediately — nothing runs at release time.
socket-patch --update can use the same host today, with no changes to the CLI,
via the endpoint override it already has:
SOCKET_UPDATE_BASE_URL=https://install.socket.dev/patch socket-patch --updateOne caveat worth knowing before standardizing on that: a non-default
SOCKET_UPDATE_BASE_URL intentionally downgrades the downloaded binary's
version self-check from hard-fail to a warning, because the override is meant
for 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.
Unchanged by the hosting move, and worth being precise about:
- The script is fetched over HTTPS from a Socket-controlled host. Its SHA-256
is published alongside it at
install.socket.dev/patch.sha256, and it can be diffed againstscripts/install.shin this repo. - The binary is fetched from the GitHub release and verified against that
release's
SHA256SUMSbefore it is unpacked. Neither the script nor the checksums are signed — this is checksum integrity rooted in HTTPS plus GitHub, the same model--updateand the gem/composer launchers use (see CLI_CONTRACT.md). - Nothing in the install path sends a Socket API token anywhere.
Hosting the script on a Socket domain moves who serves the script. It does not add a signature, and the docs should not imply that it does.
The publish path lives in depscan, which vendors this repository as
submodules/socket-patch:
- A change to
scripts/install.shmerges here. - depscan's
submodules/socket-patchpin is bumped to that commit. - depscan's prod deploy runs its Publish install.socket.dev site step,
which copies
submodules/socket-patch/scripts/install.shtogs://socket-install-prod/patch, publishes its sha256 and the landing page, then re-reads the object and fails the deploy if the bytes do not match. install-server(agcs-bucket-serverinstance,tanka/lib/depscan/install-server.libsonnet) serves that bucket atinstall.socket.dev.
So an installer change needs a depscan submodule bump plus a deploy. That
indirection is deliberate: this repository is public and needs no write
credentials into a Socket bucket, and a submodule bump is a reviewed change, so
nothing reaches a curl | sh endpoint without review on the depscan side too.
A new socket-patch release needs none of this. The script resolves the latest
release itself at run time (/releases/latest/download), so cutting 3.4.0
changes what the hosted installer installs without changing the hosted
installer. Only edits to the script itself require a publish.
.github/workflows/installer-drift.yml (weekly, plus workflow_dispatch)
fetches install.socket.dev/patch and diffs it against scripts/install.sh on
main.
- Different → the job fails. The fix is a depscan submodule bump + deploy (steps 2–3 above). Expect this to be red in the window between merging an installer change here and bumping the pin there.
- Host does not resolve → the job reports "not deployed yet" and passes, so the check is inert until the domain exists.
The check also runs shellcheck and sh -n against the fetched copy, so a
mangled publish is caught even when the hash somehow matches expectations.
- No Windows installer. The script is POSIX
sh; native Windows users go through a package manager or a release archive. Apatch.ps1object on the same host would be the natural addition — the hosting side already supports it, nothing here does yet. - Objects must stay flat — for the bucket-backed paths only (
patch,patch.sha256,index.html).gcs-bucket-serverinterpolates the object name into the GCS JSON API URL unencoded, so only bucket-root keys resolve. This does not affect/patch/dl/**, which is relayed by a separate service and never touches the bucket. - The default download origin is still GitHub. The
SOCKET_PATCH_BASE_URLmechanism ships first; flipping the default toinstall.socket.devis a one-line change, deliberately held until the relay is verified in prod. A script that defaults to a host which does not answer yet is a broken installer for everyone running it from a git checkout or the raw GitHub URL.