NestGuard
A Woodpecker CI plugin for SBOM generation and vulnerability scanning
NestGuard
NestGuard is a Woodpecker CI plugin that generates a Software Bill of Materials (SBOM) with Syft and scans it for vulnerabilities with Grype. Results are printed to the pipeline log and, when running on a pull request, posted as a comment on the corresponding Gitea PR.
Usage
steps:
- name: nestguard
image: your-registry/nestguard:latest
settings:
fail_on_severity: high
forge_token:
from_secret: gitea_token
Settings
| Setting | Type | Default | Description |
|---|---|---|---|
image |
string | - | Container image reference to scan (e.g. ghcr.io/myorg/app:latest). Takes priority over workspace. |
workspace |
string | $CI_WORKSPACE |
Directory to scan instead of a container image. |
output |
string | table |
Grype result output format. One of table, json, cyclonedx, sarif, etc. (any format supported by grype --output). |
fail_on_severity |
string | medium |
Minimum severity that causes the step to fail. One of negligible, low, medium, high, critical. |
forge_token |
string (secret) | - | API token for the Forge (Gitea) used to post the scan result as a PR comment. Required only for PR comments; the step works without it, just skips the comment. |
debug |
boolean | false |
If set (any non-empty value), prints Syft/Grype versions before running the scan. |
Choosing a scan source
Exactly one of the following applies, in priority order:
imageis set → the given image reference is scanned.workspaceis set → the given directory is scanned (see known issue above).- Neither is set →
$CI_WORKSPACE(the default checkout directory) is scanned.
Behavior
- Prints Syft and Grype version info if
debugis enabled. - Generates an SBOM (
syft-jsonformat) from the configured source and prints a human-readable table to the log. - Runs Grype against the generated SBOM.Output is printed to the log and buffered for the PR comment.
- The step's exit code matches Grype's exit code, so the pipeline fails when the configured
fail_on_severitythreshold is met or exceeded.
- The step's exit code matches Grype's exit code, so the pipeline fails when the configured
- If the build is a pull request and
forge_tokenis set, posts the Grype output as a Markdown comment on the corresponding Gitea PR via the Gitea API (POST /api/v1/repos/{owner}/{repo}/issues/{pr}/comments). Otherwise this step is skipped with a warning in the log.
Example: scanning a built image
steps:
- name: nestguard
image: woodpeckercommunity/nestguard:1
settings:
image: ghcr.io/myorg/app:latest
fail_on_severity: high
forge_token:
from_secret: gitea_token
Example: debug mode
steps:
- name: nestguard
image: woodpeckercommunity/nestguard:latest
settings:
debug: 'true'
fail_on_severity: critical
Requirements
- A Gitea / Forgejo bot account token with permission to comment on issues/PRs (only needed if PR comments are desired).
- The pipeline must run in
pull_requestcontext for a comment to be posted (CI_COMMIT_PULL_REQUESTmust be set).
Limitations / Roadmap
- No Grype vulnerability database caching between pipeline runs yet — each run re-downloads/validates the DB.
- PR comments are always appended as a new comment; there is no update-in-place behavior for repeated pushes to the same PR yet.