DEV Community

Odd_Background_328
Odd_Background_328

Posted on

Verify a Self-Hosted Installer Before Running It as Root

Downloading an installer and immediately executing it as root collapses three operational decisions into one command:

Which artifact? -> Did these bytes arrive intact? -> Should this host execute them?
Enter fullscreen mode Exit fullscreen mode

Separate those decisions and the install becomes reviewable, reproducible, and recoverable.

A concrete source-review boundary

At commit c58bcd4, the MonkeyCode runner installation template selects x86_64 or aarch64, checks AVX on x86, requires root, and downloads an architecture-specific installer before executing it.

The reviewed template uses curl -4sSLk, so certificate verification is disabled by -k. It also downloads an unversioned path. I could not find a pinned version, digest, or signature check in that template.

That is a statement about controls visible in one pinned file—not a claim that the release service is compromised or that no external release control exists.

Put a manifest before execution

For each release artifact, publish immutable metadata through a separately protected release process:

{
  "version": "1.2.3",
  "architecture": "x86_64",
  "file": "runner-installer-1.2.3-x86_64",
  "sha256": "<64 lowercase hex characters>",
  "size": 18439210,
  "rollback": {
    "previous_version": "1.2.2",
    "artifact": "runner-installer-1.2.2-x86_64"
  }
}
Enter fullscreen mode Exit fullscreen mode

SHA-256 detects bytes that differ from the manifest. It does not prove who authored the manifest. Serve the manifest over validated TLS, pin it through deployment configuration, or sign it and verify the signature with a trusted offline public key.

Verify as an unprivileged staging step

The companion verify-installer.mjs checks filename, exact size, digest, version, architecture, and rollback metadata:

node verify-installer.mjs release-manifest.json fixture-installer.sh
node test-verifier.mjs
Enter fullscreen mode Exit fullscreen mode

Expected output uses the fixture's actual digest:

PASS 1.2.3-fixture sha256=<digest>
PASS verified fixture; rejected tampered artifact before execution
Enter fullscreen mode Exit fullscreen mode

The negative test appends a line to the artifact and requires both size and digest checks to fail. The verifier never executes the file.

A production flow should look like this:

set -euo pipefail
umask 077

curl --fail --show-error --location \
  --proto '=https' --tlsv1.2 \
  -o runner-installer "$ARTIFACT_URL"

node verify-installer.mjs release-manifest.json runner-installer

# Only after verification and an explicit maintenance decision:
sudo ./runner-installer --version "$EXPECTED_VERSION"
Enter fullscreen mode Exit fullscreen mode

Do not add -k to make certificate errors disappear. Fix the trust store, hostname, time, or certificate deployment that caused the error.

Make rollback an executable plan

“We can reinstall the old version” is not a rollback procedure. Record:

  • the exact prior artifact and its verified manifest;
  • configuration and data-format compatibility;
  • service stop/start commands;
  • health checks and maximum recovery time;
  • which migrations are reversible;
  • cleanup for partial installation.

Before promotion, install into a canary with the same architecture and kernel class, record service version and health output, inject a failed download and digest mismatch, then rehearse rollback. Keep the previous verified artifact available for the declared recovery window.

Acceptance gate

I would allow privileged execution only when:

  1. TLS verification succeeds without bypass;
  2. the URL names an immutable version and architecture;
  3. a trusted manifest matches file, size, and digest;
  4. signature verification succeeds when signatures are part of the release model;
  5. the canary health check passes;
  6. rollback bytes and procedure are already verified.

That gate does not make every installer safe. It turns an opaque network-to-root transition into evidence an operator can inspect and automate.

Disclosure: I contribute to the MonkeyCode project. The installation observations are limited to the linked template at commit c58bcd4; the standalone verifier and tamper test were run locally. No vulnerability claim is made.

Top comments (0)