📎 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

Write your first Saga

On this page

The Saga (draugr.saga.yaml) is Draugr's descriptor, a declarative account of an application's security surface and the controls that must pass. This page walks you from a one-component file to a classified, multi-control descriptor. For the exhaustive field list, see the Saga schema.

Shortcut: draugr init scaffolds this file from what your tree holds: dependency files, copied JavaScript, infrastructure code, Dockerfiles and OpenAPI documents. And if you just want a scan now, draugr scan . needs no Saga at all.

The smallest thing that runs

A Saga names its project and declares at least one component with an enabled control:

project: my-app
config:
  controls:
    images:
      enabled: true
components:
  - name: web
    images:
      - image: alpine:3.19

Run it with draugr scan draugr.saga.yaml. A control only runs when it is enabled, globally under config.controls, or on an individual component. release: { version: "1.0" } labels the reports with the build being scanned.

Add more of your surface

Each component is one logical part of your app. List whatever applies, repositories, images, hosts, Kubernetes clusters, and enable the controls that should cover it:

config:
  controls:
    images:  { enabled: true }
    sca:     { enabled: true }   # dependency scanning
    secrets: { enabled: true }   # leaked-credential detection
components:
  - name: web
    repositories:
      - url: https://github.com/acme/web.git
        revision: main
    images:
      - image: registry.example.com/acme/web:1.0
        digest: sha256:…            # optional. Pin the immutable content digest

A repository scan needs git on your PATH; an image scan needs Trivy. Run draugr doctor draugr.saga.yaml to confirm the tools each enabled control needs are present.

It answers a second question at the same time, and this is the moment it is most worth asking: whether anything is set to look at what you just declared. A descriptor that names images while the images control is off scans clean over them, and a first Saga is exactly where that happens:

NOT CHECKED
  Component  Surface  Controls off
  web        images   images

Classify components so priority means something

Two optional attributes turn a wall of findings into a ranked list, exposure (how reachable the component is) and criticality (the business impact if it fails):

components:
  - name: web
    exposure: public          # public | authenticated | internal | restricted
    criticality: critical     # critical | important | supporting
    images:
      - image: registry.example.com/acme/web:1.0

Draugr combines these with each finding's severity to assign a P1–P4 priority. See prioritization. You can set them by hand, or let the guided draugr classify wizard write them for you.

Reference environment variables, not secrets

Any string value may reference an environment variable with ${{ VAR_NAME }}, if it is one of the built-in CI names or one the pipeline lists in $DRAUGR_SAGA_ENVS. Loading fails fast on any other name, and on a listed one that is unset. Never put a token in the Saga itself:

project: my-app
release:
  version: "${{ RELEASE_VERSION }}"

Next steps