Skip to content

Security: cartesi/setup-action

Security

SECURITY.md

Security Policy

Reporting a vulnerability

Please report security issues privately through GitHub security advisories rather than by opening a public issue.

Threat model

This action installs software onto a CI runner, so a compromise of the action is a compromise of every job that uses it. The design keeps that surface small:

  • Fixed sources. The repositories, the Homebrew tap and the npm registry the action downloads from are compile-time constants (src/constants.ts). No workflow input can point the action at a different host, so an attacker who controls an input cannot make a job install foreign software.
  • Verified downloads. The emulator Debian package is verified against the SHA-256 digest published by the GitHub releases API, or against the machine-checksum input when the workflow pins one. The kernel and rootfs images are verified against the digests in the emulator release's dependencies.lock. If no digest is available, the action reports the digest it computed and emits a warning instead of trusting the file silently.
  • Validated inputs. Versions, checksums and every value read from dependencies.lock are matched against strict patterns before they reach a URL, a filesystem path or a command line. Subprocesses are spawned with argument arrays, never through a shell, so input cannot be interpreted as shell syntax.
  • Narrow Homebrew trust. Homebrew requires third-party tap formulae to be trusted before it will load them. The action trusts the individual cartesi/tap formulae it installs rather than running brew trust cartesi/tap, so trust does not extend to formulae the tap may add in the future.
  • No lifecycle scripts. The Cartesi CLI is installed with npm install --ignore-scripts into a private prefix, so postinstall scripts anywhere in its dependency tree do not execute on the runner, and the install needs no elevated privileges.
  • Minimal privileges. Root is used only to install the Debian package with apt-get and to copy the images into /usr/share/cartesi-machine/images. sudo -n is used, so a runner without passwordless sudo fails immediately rather than waiting on a prompt.
  • Token handling. github-token is only sent to the GitHub API host, is registered as a secret so it is masked in logs, and is never passed to a subprocess. It needs no more than contents: read.

Recommendations for workflows using this action

  • Pin the action to a full commit SHA rather than a tag if your threat model requires it: uses: cartesi/setup-action@<sha>.
  • Pin machine-version and cli-version to exact versions for reproducible jobs, and set machine-checksum when you want the emulator package pinned by content as well.
  • Give the job the least privilege it needs, typically permissions: contents: read.

There aren't any published security advisories