Skip to content
Français
Cloud medium

Installing feint: verified release, Homebrew, mise or container

2 min de lecture

Read this page in French

Three paths lead to feint, and they do not serve the same need. The container image requires nothing to install and suits a CI; the verified binary is the recommended path on a workstation, and the only one that gives access to real machines; the GitHub action installs that binary in a pipeline, verifying its checksum before running it. This page covers all three, and the integrity verification that goes with them.

What you will get

By the end of this page, feint version will answer v0.13.0 on your machine, installed through the channel matching your verification requirements, and you will know how to run it as a service in a pipeline.

  • Choose the installation channel that fits your use.
  • Verify who published the binary before trusting it.
  • Run the emulator as a service in GitHub Actions or GitLab CI.
  • Know when a new version is out, with no forced network call.

Which path to choose

NeedPathReal machines
Try it in one commandContainer imageno
CI pipeline with a serviceContainer imageno
GitHub Actions without containerssetup-feint actionno
Personal workstation, one commandBinary through Homebrewyes, with Incus
Tools pinned per projectBinary through miseyes, with Incus
Sensitive or shared machineBinary from the verified releaseyes, with Incus
Real machines, SSH, OVN isolationBinary, whichever channelyes

The image runs no machines, and that is stated rather than hidden: it runs feint serve --vm off, because real machines are a property of the binary on an Incus host. An image claiming otherwise would be the half-truth this project refuses elsewhere.

Installing the binary

Three paths lead to the same binary, and they do not verify the same thing. The table below states what each one checks before letting you run the program, because that is the only criterion that truly separates them: they all install the same published version.

PathWhat is verifiedFor whom
Verified releaseSigstore signature of the list, then checksum of the bytesa sensitive machine, a shared one, a runner
Homebrewthe SHA-256 sum the formula carries, not the signaturea personal workstation, in one command
misethe GitHub provenance attestations, verified at install timeanyone already pinning tools per project

Download the version's binary, verify who published it, then verify the bytes. The order matters: a checksum proves nothing if you do not know who produced the list containing it.

  1. Fetch the version's artefacts.

    Fenêtre de terminal
    base=https://github.com/stephrobert/feint/releases/download/v0.13.0
    curl -fsSLO "$base/feint-linux-amd64"
    curl -fsSLO "$base/checksums.txt"
    curl -fsSLO "$base/checksums.txt.cosign.bundle"
  2. Verify the signature of the checksum list, before trusting a single line of its content.

    Fenêtre de terminal
    cosign verify-blob --bundle checksums.txt.cosign.bundle \
    --certificate-identity-regexp '^https://github\.com/stephrobert/feint/\.github/workflows/release\.yml@refs/tags/v' \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    checksums.txt

    The expected output is two words: Verified OK. Any other answer must stop the installation. Note the precision of the identity pattern: it names the release workflow and the tag prefix, where a loose pattern would accept any workflow in the repository. A compromised repository whose secondary workflow signed a binary would not pass this check.

  3. Verify the bytes against the signed list.

    Fenêtre de terminal
    sha256sum -c checksums.txt --ignore-missing

    The expected result is feint-linux-amd64: OK. Without --ignore-missing, the command fails on every platform you did not download, which wrongly looks like a corrupted binary.

  4. Install the binary and confirm the version.

    Fenêtre de terminal
    install -m 0755 feint-linux-amd64 ~/.local/bin/feint
    feint version

    The output must print v0.13.0.

If you prefer provenance to the signature, gh verifies which workflow and which commit produced the binary:

Fenêtre de terminal
gh attestation verify feint-linux-amd64 --repo stephrobert/feint

Running the emulator in a container

An image is published with every version, and it serves the control plane alone. This is the shortest path: one service, one port, no binary to install on the machine.

Fenêtre de terminal
docker run --rm -p 127.0.0.1:4599:4599 \
ghcr.io/stephrobert/feint:v0.13.0@sha256:d46639ac7c7a0fa2b6b69d0c5d74bdca0757e3124675563209e8ada58e6a6040
curl -s http://127.0.0.1:4599/_feint/health | jq -c '{status, machines}'
{"status":"ok","machines":"none"}

In a pipeline, the image is declared as an ordinary service, and no secret needs adding: that is the whole point for a team refusing to put cloud credentials in its CI.

services:
feint:
image: ghcr.io/stephrobert/feint:v0.13.0@sha256:d46639ac7c7a0fa2b6b69d0c5d74bdca0757e3124675563209e8ada58e6a6040
ports:
- 4599:4599

The runner holds the steps until the image's healthcheck answers, so the first step can talk to the emulator immediately.

The image is verified like the binaries, with the same workflow identity:

Fenêtre de terminal
cosign verify ghcr.io/stephrobert/feint:v0.13.0 \
--certificate-identity-regexp '^https://github\.com/stephrobert/feint/\.github/workflows/release\.yml@refs/tags/v' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com

Knowing when a new version is out

feint version --check asks GitHub whether a newer version exists, and prints the command to install it. Two principles govern that command: nothing goes on the network until the flag is typed, and the binary never updates itself.

Fenêtre de terminal
feint version --check

When a newer version is published, the output gives the installation command pinned to that exact version. It names the version, never latest: a mutable reference downloads whatever is newest at call time, and that content can no longer be held against the checksum printed just below it. If you are already up to date, the command recalls your version then concludes in one line:

v0.13.0
this is the latest release

A binary built from source carries dev, and an installation through go install carries a timestamped pseudo-version. Neither compares to a version tag, so the tool announces the latest release without claiming your copy is out of date.

Key takeaways

  • Three paths: the image to try it and for CI, the binary for a workstation, the action for GitHub Actions.
  • The image runs no machines: real machines stay a property of the binary on an Incus host.
  • Verification precedes execution: signature of the list, then checksums, then installation.
  • The identity pattern names the release workflow, not merely the repository.
  • No latest: pin the tag, and the digest in a pipeline.
  • feint version --check only goes on the network when you ask, and never updates by itself.

Next steps

Is this site useful to you?

Fewer than 1% of readers support this site.

I maintain more than 700 free guides, with no ads and no tracking. Any support, even a symbolic one, helps cover hosting and keeps these resources free. Thank you for the help.

The form does not show? Open Ko-fi in a new tab.

Subscribe and follow my DevSecOps work on LinkedIn