Describe your app, not your scanners
On this page
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:
| What goes wrong | What it sounds like | |
|---|---|---|
| 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 unanswerable |
| 2 | The results do not come together | each tool emits its own format and its own severity scale, so you have five dashboards and no single answer to "can this release ship?" |
| 3 | It is expensive | unchanged artifacts get re-scanned every run, because the pipeline has no idea what 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:
project: my-app
release:
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
| The failure | What the descriptor does about it |
|---|---|
| No drift | one descriptor format means every service is assessed consistently. A new service is described and done, and onboarding goes from days to minutes |
| Results converge | normalizing every scanner to SARIF gives one deduplicated view and one pass/fail verdict rather than five dashboards, and it flows straight into the GitHub, GitLab and Azure DevOps security tabs for free |
| It gets cheap | because the descriptor names concrete artifacts, an image digest and a commit, the inputs hash and anything unchanged is skipped. Unchanged component, no re-scan |
It answers questions you didn't write it for
A descriptor written to drive scanners turns out to be useful to anything that needs to know what your software is, and the clearest example is one nobody was planning for when this model was designed.
Coding assistants are asked to check code for security problems constantly. Without something written down, an assistant answers from a scope it picked itself: whatever it can infer from the source tree in front of it. On our demo app that missed 78 of the 99 things you'd fix first, all of them in a container image the repository never mentions, because nothing in a source tree says which image the app ships.
Scope is a fact about your organization, not about your code. Once it's written down, an assistant reads your attack surface instead of guessing at it.
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.