📎 Unreleased docs. This is the next version (from main), features here may change or not be in a release yet.See the latest release →

Getting started

Install

On this page

Draugr is a single binary that orchestrates external scanners. Install Draugr first (below), then let it fetch the scanners its controls need. See Scanners. Once you're set up, head to the quickstart for your first scan.

One line, latest release, Linux and macOS:

curl -fsSL https://draugr.dev/install.sh | sh

It detects your OS and architecture, installs to ~/.local/bin, and tells you if that isn't on your PATH.

It verifies before it installs, says which checks ran, and installs nothing if one fails. Install cosign first to get the stronger of the two, which verifying releases covers along with how to run them yourself.

Piping a script into a shell means trusting the host that served it. If you'd rather not, the script is readable in the repo and the manual steps below do the same work.

Three knobs, all optional. They go on sh, not on curl, where they are silently ignored:

curl -fsSL https://draugr.dev/install.sh | DRAUGR_INSTALL_DIR=~/bin sh
VariableEffect
DRAUGR_VERSIONPin a release (vX.Y.Z) instead of tracking the latest
DRAUGR_INSTALL_DIRInstall somewhere other than ~/.local/bin
DRAUGR_REQUIRE_SIGNATURESet to 1 to refuse to install unless the signature verifies

Pick a version to pin from the releases page. In CI, pin the version and require the signature, a build runner shouldn't install anything it can't prove the origin of:

curl -fsSL https://draugr.dev/install.sh \
  | DRAUGR_VERSION=vX.Y.Z DRAUGR_REQUIRE_SIGNATURE=1 sh

Already have a draugr binary? Update it in place with draugr self-update.

From a release, by hand

The same thing without the script. Grabs the latest release, no version to look up:

tag=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
  https://github.com/draugr-dev/draugr/releases/latest | sed 's#.*/tag/##')
curl -fsSL "https://github.com/draugr-dev/draugr/releases/download/${tag}/draugr_${tag#v}_linux_amd64.tar.gz" \
  | tar -xz draugr
sudo mv draugr /usr/local/bin/       # or anywhere on your PATH
draugr version

Swap linux_amd64 for darwin_arm64, darwin_amd64, linux_arm64, or windows_amd64.

To pin a release, set tag=vX.Y.Z yourself (pick one from the releases page) and drop the first command.

This path doesn't verify anything on its own. See verifying releases for the checksum and signature steps.

From a release, GitHub CLI

If you already have gh, it handles the download and the platform suffix for you. Omit the tag to get the latest release, or pass a vX.Y.Z to pin:

gh release download --repo draugr-dev/draugr -p 'draugr_*_linux_amd64.tar.gz'
tar -xzf draugr_*_linux_amd64.tar.gz draugr
sudo mv draugr /usr/local/bin/
draugr version

Verify the download (recommended). Releases ship a cosign-signed checksums.txt and per-archive SBOMs:

gh release download --repo draugr-dev/draugr \
  -p 'checksums.txt' -p 'checksums.txt.sigstore.json'
# verify the signature came from Draugr's release workflow (needs cosign)
cosign verify-blob \
  --bundle checksums.txt.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/draugr-dev/draugr/\.github/workflows/release\.yml@refs/tags/v.*$' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  checksums.txt
# verify your archive matches
sha256sum --ignore-missing -c checksums.txt

For the full verification story (cosign, SLSA provenance, SBOMs) see verifying releases.

From source

Requires Go 1.26+.

git clone https://github.com/draugr-dev/draugr.git
cd draugr
make build
./bin/draugr version

make build produces ./bin/draugr. To install a verified release into ~/.local/bin instead of building, from the same checkout:

make install-latest

With Go

go install github.com/draugr-dev/draugr/cmd/draugr@latest

Scanners. The tools Draugr runs

With Draugr installed, add the scanners for the controls you use. The fastest way is to let Draugr fetch pinned, verified copies into ~/.draugr/bin (added to your PATH automatically):

draugr tools install --saga draugr.saga.yaml   # only what this descriptor's scan will run
draugr tools install --all      # everything Draugr can provision, pinned + verified
draugr tools list               # what's pinned, which controls it backs, and what's installed
draugr tools uninstall --all    # remove what install added; --caches also removes tool databases

The narrow one first because it is the one to reach for. A small service needs a few of the tools Draugr can fetch, and every other one is a binary to trust, patch and explain. Take everything when you are preparing a machine for several projects rather than scanning one.

Prefer your own install (Homebrew, package manager, an existing copy)? That works too. Then run draugr doctor to confirm everything's found:

  • Trivy, images, sca, iac and licenses controls.
  • Gitleaks, secrets control.
  • Semgrep, sast control (default; opt-in gosec for Go).
  • Grype, opt-in second scanner for sca and images.
  • retire.js, opt-in for sca, and the one that finds JavaScript no lockfile describes.
  • Nuclei, dast control.
  • kube-bench, opt-in for the kubernetes control's scored checks, which read a node's filesystem. Needs kubectl as well: its CIS checks are scripts that invoke it.
  • govulncheck, opt-in for sca, and what turns a list of known vulnerabilities into the ones this Go code can reach.
  • Syft, SBOM generation (config.sbom), which is not a control.
  • git, needed for any repository scan (sca, secrets, sast, licenses).

Two of these need a language runtime already present: Semgrep needs Python 3.10 or newer with pip, and retire.js needs Node 18 or newer with npm.

headers, tls and kubernetes are native by default and need nothing installed: the kubernetes control reads the cluster through the Kubernetes API unless you opt into kube-bench for the checks that need a node's filesystem. draugr doctor reports which of these your Saga requires, so the list you have to care about is usually shorter than this one.