← All articles

Describe your app, not your scanners

July 10, 2026 · Wilson Santos
devsecopsappsecsarif

Ask ten teams how they run application security in CI and you’ll get ten pipelines, each a hand-wired pile of scanner invocations: a SAST step here, a container scan there, a dependency check bolted on, some header probe someone copied from a gist two years ago. Every service reinvents it. Nobody remembers why the flags are set the way they are. And the moment you have more than a handful of services, it stops scaling.

The root problem is that we describe the tools instead of the software.

The tool-centric trap

When your pipeline is a list of scanner commands, three things go wrong as you grow:

  1. Every repo drifts. Each team tweaks the invocation, so no two services are assessed the same way. “Are we even scanning that service’s images?” becomes an unanswerable question.
  2. The results don’t come together. Each tool emits its own format and its own severity scale. You end up with five dashboards and no single answer to “can this release ship?”
  3. It’s expensive. You re-scan unchanged artifacts on every run because the pipeline has no idea what actually changed.

You can paper over any one of these. You can’t paper over all three at once — not across dozens of services.

Flip it: describe the app

Developers already know their software. They know where the code lives, what images it builds, what endpoints it exposes, what infrastructure it runs on. That knowledge is stable and small. So capture that — once, declaratively:

release:
  name: my-app
  version: "1.0"
components:
  - name: backend
    repositories:
      - url: https://github.com/acme/backend.git
    images:
      - image: registry.example.com/acme/backend:1.0
    hosts:
      - url: https://api.acme.com

From a description like this, the right controls follow automatically: images get an image scan, repositories get SAST and dependency analysis, endpoints get header and TLS checks. The developer never has to know which scanner runs, or how to configure it. They describe their app; the system figures out the rest.

Why this fixes the three failures

  • No drift. One descriptor format means every service is assessed consistently. New service? Describe it and you’re done — onboarding goes from days to minutes.
  • Results converge. Normalize every scanner’s output to a single interchange format — SARIF is the obvious choice — and you get one deduplicated view and one pass/fail verdict, not five dashboards. As a bonus, SARIF flows straight into GitHub, GitLab, and Azure DevOps security tabs for free.
  • It gets cheap. Because the descriptor names concrete artifacts (an image digest, a commit), you can hash the inputs and skip anything that hasn’t changed. Unchanged component, no re-scan. At a hundred services that’s the difference between a security gate people tolerate and one they route around.

The quiet win: security stops being a bottleneck

The tool-centric model makes security a specialist chore that slows delivery. The descriptor model makes it a property of the software that travels with it. Developers self-serve, the platform team sets sane defaults once, and the security team reviews evidence instead of babysitting pipelines. Everybody moves faster — which, counter to the usual framing, is exactly when security gets better, because the fast path is finally the secure path.

That inversion — describe your app, not your scanners — is the whole idea behind Draugr. More on how it works in future posts.