Skip to content

A Dagger module for automated container security auditing. Integrates with Trivy, Grype, and Snyk to perform vulnerability scans, enforce best practices, and generate compliance reports for CI/CD pipelines.

License

Notifications You must be signed in to change notification settings

sylvester-francis/Sentry

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sentry

███████╗███████╗███╗   ██╗████████╗██████╗ ██╗   ██╗
██╔════╝██╔════╝████╗  ██║╚══██╔══╝██╔══██╗╚██╗ ██╔╝
███████╗█████╗  ██╔██╗ ██║   ██║   ██████╔╝ ╚████╔╝ 
╚════██║██╔══╝  ██║╚██╗██║   ██║   ██╔══██╗  ╚██╔╝  
███████║███████╗██║ ╚████║   ██║   ██║  ██║   ██║   
╚══════╝╚══════╝╚═╝  ╚═══╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝   

Container Security Auditing for CI/CD Pipelines

Go Dagger License: MIT Daggerverse

Trivy Grype Snyk Wiz Black Duck

InstallationQuick StartDocumentationCI/CD Integration


What is Sentry?

Sentry is a security auditing tool that scans your container images for vulnerabilities and misconfigurations. It integrates with your CI/CD pipeline to automatically check containers before deployment.

Key Features:

  • Multi-Scanner Support — Trivy, Grype, Snyk, Wiz, or Black Duck
  • Security Checks — Non-root user, secret detection, healthcheck validation
  • Reports — Markdown summaries, JSON for automation, 0-100 security scores
  • CI/CD Gates — Pass/fail exit codes to block vulnerable deployments
flowchart LR
    subgraph Scanners
        S1[Trivy]
        S2[Grype]
        S3[Snyk]
        S4[Wiz]
        S5[Black Duck]
    end
    
    subgraph Checks["Security Checks"]
        C1[Non-Root User]
        C2[Secret Detection]
        C3[Health Check]
    end
    
    subgraph Output["Output Formats"]
        O1[Markdown Report]
        O2[JSON]
        O3[Exit Code]
        O4[Score]
    end
    
    subgraph Config["Configuration"]
        CF1[Severity Threshold]
        CF2[Ignore CVEs]
        CF3[Disable Checks]
    end
Loading

Architecture

flowchart LR
    subgraph Input
        A[Container Image]
    end
    
    subgraph Sentry["Sentry Module"]
        B[Security Checks]
        C[Vulnerability Scanner]
        D[Score Calculator]
    end
    
    subgraph Scanners["Scanner Options"]
        E[Trivy]
        F[Grype]
        G[Snyk]
        H[Wiz]
        I[Black Duck]
    end
    
    subgraph Output
        J[Report]
        K[JSON]
        L[Exit Code]
    end
    
    A --> B
    A --> C
    C --> E & F & G & H & I
    B --> D
    C --> D
    D --> J & K & L
Loading

What is Dagger?

Dagger is a programmable CI/CD engine that runs your pipelines in containers. Instead of writing YAML, you write code in Go, Python, or TypeScript.

Why Dagger?

  • Portable — Same pipeline runs locally and in any CI (GitHub Actions, GitLab, Jenkins)
  • Fast — Intelligent caching speeds up builds
  • Reproducible — Containers ensure consistent environments

Sentry is a Dagger Module — a reusable component you can call from any Dagger pipeline.

flowchart TB
    subgraph traditional["Traditional CI/CD"]
        direction TB
        T1[Write YAML config] --> T2[Debug syntax errors]
        T2 --> T3[Push and wait for CI]
        T3 --> T4[Fix CI-only failures]
        T4 -.->|repeat| T1
    end
    
    subgraph dagger["With Dagger"]
        direction TB
        D1[Write code with IDE] --> D2[Test locally first]
        D2 --> D3[Push with confidence]
        D3 --> D4[Same result in CI]
    end
Loading

Installation

Prerequisites

  1. DockerInstall Docker
  2. Dagger CLI — Install with one command:
# macOS / Linux
curl -fsSL https://dl.dagger.io/dagger/install.sh | sh

# Windows (PowerShell)
Invoke-WebRequest -Uri https://dl.dagger.io/dagger/install.ps1 -OutFile install.ps1; .\install.ps1

Verify installation:

dagger version

No Additional Setup Required

Sentry runs directly from the Daggerverse — no cloning or installing needed.


Quick Start

Your First Scan

stateDiagram-v2
    [*] --> Scanning: dagger call scan
    Scanning --> SecurityChecks: Container loaded
    SecurityChecks --> VulnScan: Checks complete
    VulnScan --> Scoring: Scan complete
    Scoring --> Passed: score >= threshold
    Scoring --> Failed: score < threshold
    Passed --> [*]: Exit code 0
    Failed --> [*]: Exit code 1
Loading

Scan any container image with a single command:

dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=nginx:latest \
  report

Output:

# Security Audit Report

## Executive Summary

┌─────────────────────────────────────────────────────────────┐
│  STATUS: PASSED                                             │
├─────────────────────────────────────────────────────────────┤
│  Score: 85/100                                              │
│  Checks: 2 passed, 1 warning                                │
│  Vulnerabilities: 12 total (0 critical, 2 high)             │
└─────────────────────────────────────────────────────────────┘

Common Use Cases

Get a pass/fail result for CI pipelines:

dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  exit-code
# Returns 0 (pass) or 1 (fail)

Get JSON output for automation:

dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  json

Get just the security score:

dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  score
# Returns: 85

Usage Guide

Choosing a Scanner

Sentry supports multiple vulnerability scanners. Default is Trivy.

Scanner Command Auth Required
Trivy (default) with-trivy No
Grype with-grype No
Snyk with-snyk --token=env:SNYK_TOKEN Yes
Wiz with-wiz --client-id=... --client-secret=... Yes
Black Duck with-black-duck --url=... --token=... Yes

Example: Use Grype instead of Trivy

dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  with-grype \
  report

Example: Use Snyk with authentication

export SNYK_TOKEN=your-token-here
dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  with-snyk --token=env:SNYK_TOKEN \
  report

Setting Failure Thresholds

Control when the audit fails based on vulnerability severity:

# Fail only on CRITICAL vulnerabilities (lenient)
dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  fail-on --severity=CRITICAL \
  exit-code

# Fail on HIGH or above (default)
dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  fail-on --severity=HIGH \
  exit-code

# Fail on MEDIUM or above (strict)
dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  fail-on --severity=MEDIUM \
  exit-code

Ignoring Known CVEs

Suppress specific CVEs (for accepted risks or false positives):

dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  ignore-cves --cve-ids=CVE-2024-1234,CVE-2024-5678 \
  report

Disabling Specific Checks

# Skip non-root check (for containers that must run as root)
dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  with-non-root-check --enable=false \
  report

# Skip secret detection
dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  with-secret-check --enable=false \
  report

# Run security checks only (no vulnerability scanning)
dagger call -m github.com/sylvester-francis/Sentry \
  scan --container=myapp:latest \
  without-scanner \
  report

Security Checks

Sentry performs these automated security checks:

Check Severity Description
Non-Root User HIGH Verifies container doesn't run as root (UID 0)
Secret Detection HIGH Scans environment variables for exposed credentials
Health Check INFO Verifies curl or wget is available for health probes
flowchart TD
    A[Container] --> B{Non-Root Check}
    B -->|UID > 0| C[PASS]
    B -->|UID = 0| D[FAIL - HIGH]
    
    A --> E{Secret Detection}
    E -->|No secrets found| F[PASS]
    E -->|Secrets detected| G[FAIL - HIGH]
    
    A --> H{Health Check}
    H -->|curl/wget available| I[PASS]
    H -->|Not available| J[WARN - INFO]
    
    C & D & F & G & I & J --> K[Calculate Score]
    K --> L{Score >= Threshold?}
    L -->|Yes| M[PASSED]
    L -->|No| N[FAILED]
Loading

Secret Detection Patterns

Sentry detects these credential patterns in environment variables:

  • AWS Access Keys (AKIA...)
  • GitHub Tokens (ghp_, gho_, ghs_, ghr_)
  • JWT Tokens (eyJ...)
  • Private Keys (-----BEGIN...)
  • Database URLs with credentials
  • Slack Tokens, API Keys

CI/CD Integration

sequenceDiagram
    participant Dev as Developer
    participant CI as CI/CD Pipeline
    participant Sentry as Sentry Module
    participant Registry as Container Registry
    
    Dev->>CI: Push Code
    CI->>CI: Build Container
    CI->>Sentry: Scan Container
    Sentry->>Sentry: Run Security Checks
    Sentry->>Sentry: Run Vulnerability Scan
    Sentry->>CI: Return Exit Code
    alt Passed (exit code 0)
        CI->>Registry: Push Container
        CI->>Dev: Deploy Success
    else Failed (exit code 1)
        CI->>Dev: Block Deployment
    end
Loading

GitHub Actions

name: Security Audit

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Dagger
        run: curl -fsSL https://dl.dagger.io/dagger/install.sh | sh

      - name: Run Security Audit
        run: |
          ./bin/dagger call -m github.com/sylvester-francis/Sentry \
            scan --container=myapp:${{ github.sha }} \
            exit-code

GitLab CI

security_audit:
  stage: security
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - curl -fsSL https://dl.dagger.io/dagger/install.sh | sh
  script:
    - ./bin/dagger call -m github.com/sylvester-francis/Sentry \
        scan --container=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA \
        exit-code

Using in Your Dagger Module

Call Sentry from your own Dagger pipeline code:

package main

import (
    "context"
    "dagger/mymodule/internal/dagger"
)

type MyModule struct{}

func (m *MyModule) Build(ctx context.Context) (*dagger.Container, error) {
    container := dag.Container().
        From("golang:1.21").
        // ... build steps ...

    // Run security audit before deploying
    result, err := dag.Sentry().
        Scan(container).
        FailOn("HIGH").
        Report(ctx)
    
    if err != nil {
        return nil, err
    }
    
    return container, nil
}

Output Formats

Markdown Report (report)

Human-readable report with executive summary, vulnerability breakdown, and check results.

JSON Report (json)

Machine-readable format for automation and integration:

{
  "timestamp": "2026-01-13T12:00:00Z",
  "imageRef": "myapp:latest",
  "scannerUsed": "trivy",
  "passed": true,
  "score": 85,
  "checks": [...],
  "vulnerabilities": [...],
  "vulnSummary": {
    "critical": 0,
    "high": 2,
    "medium": 5,
    "low": 5,
    "total": 12
  }
}

Security Score (score)

0-100 score based on findings. Deductions:

  • CRITICAL vulnerability: -10 points
  • HIGH vulnerability: -5 points
  • MEDIUM vulnerability: -2 points
  • Failed security check: -15 to -25 points
quadrantChart
    title Security Score Interpretation
    x-axis Low Risk --> High Risk
    y-axis Low Confidence --> High Confidence
    quadrant-1 Review Findings
    quadrant-2 Safe to Deploy
    quadrant-3 Needs Investigation
    quadrant-4 Block Deployment
    Score 90-100: [0.15, 0.85]
    Score 70-89: [0.35, 0.70]
    Score 50-69: [0.60, 0.45]
    Score 0-49: [0.85, 0.25]
Loading

Command Reference

Command Description
scan --container=<image> Start audit for a container
scan-image --image-ref=<ref> Start audit from image reference string
with-trivy / with-grype / with-snyk Select vulnerability scanner
fail-on --severity=<level> Set failure threshold (CRITICAL/HIGH/MEDIUM/LOW)
ignore-cves --cve-ids=<list> Suppress specific CVE IDs
with-secret-check --enable=<bool> Enable/disable secret detection
with-non-root-check --enable=<bool> Enable/disable non-root check
report Generate Markdown report
json Generate JSON report
score Get numeric security score (0-100)
summary Get one-line status summary
passed Get boolean pass/fail
exit-code Get CI exit code (0=pass, 1=fail)

Troubleshooting

Issue Solution
Scanner returns empty results Normal for minimal images (e.g., scratch, distroless)
"Container running as root" Add USER nobody to your Dockerfile
"No curl/wget found" Add health check tools or disable check with --with-health-check=false
401 Unauthorized Refresh your scanner authentication token

Development

Run Tests

dagger call -m github.com/sylvester-francis/Sentry test

Local Development

git clone https://github.com/sylvester-francis/Sentry.git
cd Sentry
dagger develop
dagger functions
dagger call scan --container=alpine:latest report

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: dagger call test
  5. Open a Pull Request

Links


Built with Dagger

About

A Dagger module for automated container security auditing. Integrates with Trivy, Grype, and Snyk to perform vulnerability scans, enforce best practices, and generate compliance reports for CI/CD pipelines.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages