# Draugr

**Category:** 🔒 Security  
**Repository:** https://github.com/draugr-dev/draugr  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/draugr

## Description
Answers what to fix first, from your committed security descriptor rather than an invented scope.

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "draugr": {
    "command": "npx",
    "args": ["-y","draugr"]
  }
}
```

## Documentation & README

# Draugr

> Run Trivy, Semgrep, Gitleaks and more from one file. Get one SARIF report and one verdict.

[![CI](https://github.com/draugr-dev/draugr/actions/workflows/ci.yml/badge.svg)](https://github.com/draugr-dev/draugr/actions/workflows/ci.yml)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/draugr-dev/draugr/badge)](https://scorecard.dev/viewer/?uri=github.com/draugr-dev/draugr)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/13631/badge)](https://www.bestpractices.dev/projects/13631)
[![Latest release](https://img.shields.io/github/v/release/draugr-dev/draugr?sort=semver)](https://github.com/draugr-dev/draugr/releases)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue)](LICENSE)

**Describe your app. Draugr figures out the rest.**

Wiring SAST, SCA, secret, IaC and container scanners into a pipeline by hand means five
tools to configure, five outputs to read, and no answer to "can this ship?". Draugr
consolidates them: one descriptor, one **SARIF** report, one pass/fail gate.

You declare what you *know* about your software — where the repos are, what container
images it builds, what endpoints it exposes, what infrastructure it runs on — in a single
descriptor (`draugr.saga.yaml`). Draugr infers which checks apply, runs the right tool for
each, and produces pass/fail evidence you can trust. Swap scanners freely — use the tools
you already pay for, or Draugr's open-source defaults.

Findings are **ranked**, not just listed: the same CVE is act-now on an internet-facing
service and backlog on an internal tool, because Draugr knows which is which. And
[`draugr diff`](docs/guides/pr-diff.md) gates a pull request on **new** findings only, so
inheriting a repository with two hundred existing ones does not block every change.

Both questions asked before a release ships, from the same descriptor and the same gate:
the **security** one — SAST, SCA, secrets, IaC, DAST, TLS, headers — and the **compliance**
one, starting with a Software Bill of Materials of everything you actually ship.

This is the open-source core engine.

**[Quickstart](#quickstart)** · [See it in action](#see-it-in-action) · [Status](#status) ·
[Use in CI](#use-in-ci-github-actions) · [From an AI assistant](#use-from-an-ai-coding-assistant) ·
[Documentation](#documentation) · [What Draugr doesn't promise](#what-draugr-doesnt-promise) ·
[Security](#security--supply-chain) · [Development](#development)

## See it in action

![Terminal output from `draugr scan .`: a FAIL verdict, counts across priorities P1 to P4, a per-control table of severities, and a ranked fix-first list giving each finding's priority, severity, score, rule, control, scanner and file location.](contrib/demo/scan.png)

The verdict, priorities and severities are color-coded on a terminal (disable with `NO_COLOR`).
Findings are ranked by **priority (P1–P4)** = severity × the component's exposure & criticality;
**severity** (critical/high/medium/low) comes from the CVSS score when a scanner provides one,
else from the finding's level. The gate and `--format json`/`sarif` still use SARIF levels.

**[draugr-dev/draugr-demo](https://github.com/draugr-dev/draugr-demo)** is an intentionally
vulnerable sample app wired to Draugr. Every control lights up, the findings are prioritized
P1–P4, and results land in the repo's **Security → Code scanning** tab — a safe sandbox to see
exactly what Draugr delivers before pointing it at your own code. The example PRs there also show
the **new-vs-fixed PR diff** and the sticky comment.

## Status

🚧 **Early, and moving fast.** Working today:

- **Controls:** `images` (Trivy), `sca` (Trivy fs), `licenses` (Trivy licence scanner),
  `secrets` (Gitleaks), `sast` (Semgrep, plus opt-in gosec for Go), `iac` (Trivy config),
  `headers` (native HTTP-header analyzer), `dast` (Nuclei), `tls` (native TLS/certificate probe),
  `threats` (abuse.ch URLhaus — whether your hosts are already known to serve malware),
  `infrastructure` (CIS Kubernetes Benchmark — read through the Kubernetes API by default, with
  kube-bench and an in-cluster Job available for the node sections).
  See the [integrations catalog](docs/reference/catalog.md).
- **Pipeline:** end-to-end `scan` (plan → scan → judge → report), content-hash caching,
  tunable parallelism (`-j`), results normalized to SARIF.
- **Prioritization:** declare a component's `exposure` and `criticality` and Draugr ranks
  every finding P1–P4 (`--min-priority` to focus, `--fail-on-priority` to gate);
  optional KEV/EPSS enrichment for real-world exploitability.
- **Policy:** `config.gate.controls` holds each control to its own threshold, and
  `config.exclude` suppresses a finding **with a required reason** — it stays in the report,
  marked, rather than disappearing.
- **Evidence:** `config.sbom` emits an SBOM per repository and image (SPDX or CycloneDX, via
  Syft); reports render as console, Markdown, HTML, JUnit, JSON or SARIF. The HTML report is
  self-contained and carries its own SARIF and TSV downloads.
- **Discovery:** `survey` for Kubernetes images, the cluster itself, and GitHub org repositories
  — and the descriptor it writes enables the controls for what it found.
- **Zero-config & scaffolding:** `scan .` uses the `draugr.saga.yaml` there, or scans the repo
  with sensible defaults when there is none
  (sca/secrets/sast/iac); `init` scaffolds a stack-detected `draugr.saga.yaml` to customize.
- **Preflight & tooling:** `validate` (schema-check a Saga), `doctor` (which scanner tools are
  present/missing), `tools install` (fetch pinned, checksum- and cosign-verified scanners —
  and cosign itself — into `~/.draugr/bin`), and `self-update` (update draugr itself, verified).

`threats` (threat intelligence) is on the roadmap. See
[controls & scanners](docs/concepts/controls-and-scanners.md) for what maps to what.

## Quickstart

**Requirements:** the external scanners for the controls you use —
[Trivy](https://github.com/aquasecurity/trivy) (`images`, `sca`, `iac`, `licenses`),
[Gitleaks](https://github.com/gitleaks/gitleaks) (`secrets`),
[Semgrep](https://semgrep.dev) (`sast`),
[Nuclei](https://github.com/projectdiscovery/nuclei) (`dast`),
[kube-bench](https://github.com/aquasecurity/kube-bench) with `kubectl` (`infrastructure`);
`git` for repo scans, and [Syft](https://github.com/anchore/syft) for `config.sbom`. `headers`
and `tls` need no external tool. `threats` needs no tool either, but does need a free
[abuse.ch](https://auth.abuse.ch/) key in `URLHAUS_AUTH_KEY` — and their free tier is
non-commercial, so read [their terms](https://abuse.ch/terms-of-use/) first.

`draugr doctor` tells you which of these your Saga actually needs and whether they are present;
`draugr tools install` fetches pinned, verified copies of the ones Draugr packages. Go 1.26+ only
to build from source.

**Install (recommended):**

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

Detects your OS and architecture and installs to `~/.local/bin` — no `sudo`. It **verifies before
it installs and says which checks ran**: the archive's SHA-256 against the release's
`checksums.txt` always, plus the cosign signature on `checksums.txt` when
[cosign](https://docs.sigstore.dev/cosign/) is on your `PATH`. Nothing is installed if a check
fails.

Piping a script into a shell means trusting the host that served it. The script is
[readable in the repo](install.sh), and
[install & verifying downloads](docs/getting-started/install.md) has the manual steps, the
`DRAUGR_*` knobs, and Homebrew. Once installed, update in place with **`draugr self-update`**.

**Or build from source:**

```bash
git clone https://github.com/draugr-dev/draugr.git
cd draugr && make build      # produces ./bin/draugr
./bin/draugr version
```

**Fastest path — zero config.** Point Draugr at a repo and go; no descriptor needed:

```bash
draugr scan .        # scans the current repo: sca, secrets, sast, iac
draugr init          # or scaffold a draugr.saga.yaml (stack-detected) to customize
```

For full control, write a Saga — any `*.saga.yaml` file (see [`examples/`](examples/draugr.saga.yaml)):

```yaml
release:
  name: my-app
  version: "1.0"
config:
  controllers:
    images:
      enabled: true
components:
  - name: web
    images:
      - image: alpine:3.19
```

Scan it:

```bash
draugr scan draugr.saga.yaml            # console summary; exits non-zero on fail
draugr scan draugr.saga.yaml -o out/    # also writes out/report.json + out/results.sarif
draugr scan draugr.saga.yaml --fail-on warning
draugr scan draugr.saga.yaml --format markdown   # or html, junit, json, sarif
```

**Your editor already knows this file.** Draugr's
[JSON Schema](https://draugr.dev/schema/draugr.saga.schema.json) is registered with
[SchemaStore](https://www.schemastore.org/), which VS Code's YAML extension and JetBrains IDEs
consult by default — so any `*.saga.yaml` gets completion, hover docs and typo warnings on open,
with nothing to configure. For an editor that doesn't use the catalog, `draugr init` also writes:

```yaml
# yaml-language-server: $schema=https://draugr.dev/schema/draugr.saga.schema.json
```

`draugr schema -o .saga.schema.json` writes the copy embedded in your binary instead, if you'd
rather validate offline or pin to exactly the version you run. See
[editor support](docs/reference/saga-schema.md#editor-support-autocomplete-hover-docs-validation).

Compare two scans to see what a change introduced (and gate a PR on *new* findings only):

```bash
draugr diff base/results.sarif head/results.sarif                     # new / fixed / unchanged
draugr diff base/results.sarif head/results.sarif --fail-on-new-priority P1
```

Let discovery write the descriptor for you:

```bash
draugr survey github repos --org my-org -o draugr.saga.yaml
draugr survey k8s images --namespace prod -o draugr.saga.yaml
```

Full walkthrough: [`docs/getting-started/quickstart.md`](docs/getting-started/quickstart.md).

## Use in CI (GitHub Actions)

Add Draugr to a repository's CI and code scanning with the first-party action. It downloads a
cosign-verified Draugr release, runs the scan, and hands the merged SARIF to GitHub code
scanning — one clean **Draugr** tool in the Security tab:

```yaml
permissions:
  contents: read
  security-events: write   # upload SARIF to code scanning

steps:
  - uses: actions/checkout@v4
  - id: draugr
    uses: draugr-dev/draugr@v0     # latest v0.x; pin @vX.Y.Z for reproducible CI (installs Draugr for you)
    with:
      saga: draugr.saga.yaml
      tools: true                       # provision the scanners the controls need
      fail-on: warning                  # optional gate (default: error)
  - if: always()                        # publish findings even when the gate fails
    uses: github/codeql-action/upload-sarif@v3
    with:
      sarif_file: ${{ steps.draugr.outputs.sarif }}
```

With `tools: true` the action provisions the scanners each control needs (Trivy, Gitleaks,
Semgrep). See the [GitHub Action guide](docs/guides/github-action.md) for the full workflow and
all inputs.

## Use from an AI coding assistant

Ask an assistant to check a change for security problems and it will — by running whatever
scanner it can find, over a scope it chose for itself, and reading the raw output. That answer
has no relationship to the one your pipeline will give.

`draugr mcp` serves Draugr over the [Model Context Protocol](https://modelcontextprotocol.io),
so the assistant reads your **committed** Saga instead:

```bash
claude mcp add draugr -- draugr mcp
```

It can list the controls that exist, hand back the descriptor schema *your build* enforces,
validate a Saga before you write it, and rank an existing report by priority. Every
`*.saga.yaml` nearby is exposed as a resource, so the assistant reads the real scope rather than
guessing at one.

**Scanning is off by default** — it clones repositories and runs external tools. Turn it on with
`--scan=ask` to approve each call, or `--scan=always` for a sandbox. See
[use Draugr from an AI coding assistant](docs/guides/ai-agents-mcp.md).

## Documentation

**[Full documentation index →](docs/README.md)** (grouped by task, with a "building blocks"
glossary of Saga / Norn / Skald).

- [Quickstart](docs/getting-started/quickstart.md) — install, first scan, first survey, CI usage
- [Concepts](docs/concepts/saga.md) — Saga, controllers, scanners, surveyors, the pipeline, verdicts
- [Pipeline stages](docs/contributing/pipeline.md) — each stage in depth, incl. how the Norn (gate) works
- [Glossary](docs/reference/glossary.md) — security categories explained (SCA, SAST, DAST, SBOM, …)
- [Integrations catalog](docs/reference/catalog.md) — every controller/scanner/surveyor, with per-component docs + licenses
- [Changelog](CHANGELOG.md) — user-facing release notes
- [CLI reference](docs/reference/cli.md) — every command and flag
- [AI coding assistants](docs/guides/ai-agents-mcp.md) — the MCP server, its tools, and the consent model
- [Findings in your editor](docs/guides/findings-in-your-editor.md) — SARIF as inline diagnostics
- [Reports & publishers](docs/guides/reports-and-publishers.md) — every output format and where it can go
- [Saga schema](docs/reference/saga-schema.md) — the descriptor, field by field
- [Architecture](docs/contributing/architecture.md) · [Plugin API](docs/contributing/plugin-api.md) · [Naming](docs/contributing/naming.md)

## What Draugr doesn't promise

A passing verdict means the controls you configured found nothing they were looking for. It is
not a statement that your software is secure — it's silent about anything your descriptor doesn't
declare, controls you didn't enable, and whatever the underlying scanners miss. Licence findings
are information, not legal advice. Draugr is provided under Apache-2.0 **without warranty**.

The details, including whose terms the bundled scanners carry and your responsibility for
authorisation when scanning live endpoints:
[scope and disclaimer](docs/trust-and-operations/disclaimer.md).

## Security & supply chain

A security tool should hold itself to what it checks. Draugr does:

- **Standard output** — every finding is normalized to **SARIF 2.1.0** (OASIS), so results flow
  into GitHub / GitLab / Azure DevOps code scanning and any SARIF-aware tool.
- **Signed releases + provenance** — release archives' `checksums.txt` is **keyless-signed with
  cosign** (Sigstore) into a `checksums.txt.sigstore.json` bundle, and each release publishes
  **SLSA build-provenance** attestations (`gh attestation verify …`); verify before installing
  ([recipe](docs/trust-and-operations/verifying-releases.md)).
- **SBOMs** — a Syft **SBOM** is published for every release archive.
- **Verified tooling** — `draugr tools install` fetches scanners pinned by **SHA-256** and, where
  the upstream signs them, verifies the **cosign** signature too — and cosign itself is
  installable, so verification is self-sufficient.
- **We scan ourselves** — Draugr runs on its own repo every PR (dogfood self-scan), and we track
  our supply-chain posture with the **[OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/draugr-dev/draugr)**
  (badge above).

  That card reports **`SAST: 0`**, and it is worth saying why we are leaving it there. Static
  analysis does run on this repository: Semgrep and gosec through Draugr's own `sast` control on
  every scan, and gosec again inside `golangci-lint` on every pull request. Scorecard looks for a
  specific set of tools it recognises, and ours are not in it.

  Adding a third static analyser purely to move the number would be the same thing as writing
  tests that touch code without asserting anything — a metric improved without the property
  behind it improving. We would rather the score be wrong and the analysis be real. If you want
  to check the analysis rather than the score, the findings are in the repository's Security tab,
  uploaded by the scan itself.
- **Report a vulnerability** — see [SECURITY.md](SECURITY.md).

## Development

Requires Go 1.26+.

```bash
make build   # build ./bin/draugr
make gate    # full local gate: fmt, vet, golangci-lint, race tests + coverage, govulncheck
make test    # run tests
```

### Observability

Draugr uses [Cobra](https://github.com/spf13/cobra) for the CLI, `log/slog` for
logging (human-readable and colorized by default; `--log-format json` for structured logs in
CI/observability pipelines), and [OpenTelemetry](https://opentelemetry.io)
for traces and metrics. Telemetry is opt-in via the standard `OTEL_*` environment variables
(e.g. `OTEL_EXPORTER_OTLP_ENDPOINT`) — a no-op with zero overhead when unset. Logs and spans
never carry secrets.

## License

Draugr is licensed under the [Apache License 2.0](LICENSE).

