Skip to Content
DojOps: AI-powered DevOps automation. Learn more →
TutorialsSecurity Audit & Remediation

Security audit & remediation

Run a full security audit on your project with scanning, SBOM generation, and auto-remediation.

Difficulty: Intermediate Duration: 30 minutes What you’ll build: A complete security picture of the example Next.js project — vulnerability scan results across multiple categories, a CycloneDX SBOM, LLM-generated remediations for the findings, and a 50%+ reduction in total findings after applying fixes.


What you’ll learn

  • How DojOps runs multiple scanners in parallel and aggregates findings
  • Which of the 10 built-in scanners cover which threat categories
  • What a Software Bill of Materials is and when you need one
  • How auto-remediation generates context-aware fixes, not generic advice
  • How scan comparison tracks your security posture over time

Prerequisites

  • Node.js >= 20 (nodejs.org )
  • Git installed
  • DojOps installed: npm i -g @dojops/cli
  • An API key from a supported LLM provider

Optional but recommended for full scanner coverage: install some or all of the external scanners. DojOps runs whichever scanners it finds on your PATH and skips the rest. You don’t need all ten to get meaningful results, but npm-audit alone gives limited coverage.

The fastest way to install scanners is through the DojOps toolchain. All six external scanners are available:

# Install all scanners at once dojops toolchain install trivy gitleaks hadolint shellcheck semgrep checkov

The toolchain downloads pre-built binaries for trivy, gitleaks, hadolint, and shellcheck to ~/.dojops/toolchain/bin/. Semgrep and checkov are Python tools — the toolchain installs them in sandboxed venvs at ~/.dojops/toolchain/venvs/ (requires python3 on your system).

Trivy requires a vulnerability database (~100 MB) to detect CVEs. The toolchain installer downloads it automatically after placing the binary. If the download fails (network issues, firewalls), trivy retries on the first scan. You can verify the DB is ready by running trivy fs --scanners vuln /tmp — if it reports “Number of vulnerabilities: 0” instead of a download error, the DB is present.

Run dojops toolchain list to see all available tools and their install status.

Note: If no external scanners are installed, dojops scan runs only npm-audit (for Node.js projects) and may report “No security issues found” — which can be misleadingly reassuring. Install at least trivy and gitleaks for meaningful coverage: dojops toolchain install trivy gitleaks.


Workshop steps

Step 1: Setup

Install DojOps if you haven’t already, then clone the example project:

npm i -g @dojops/cli git clone https://github.com/dojops/example-nextjs.git cd example-nextjs

Configure your LLM provider and initialize the project:

dojops provider add openai --token sk-... dojops init
Initializing DojOps... Languages detected: TypeScript, JavaScript, CSS CI/CD platforms: GitHub Actions (.github/workflows/ci.yml) Container files: Dockerfile, .dockerignore Project context saved to .dojops/context.json

The project context records which files exist. Scan commands use this to know where to look.


Step 2: Run a full scan

Run all available scanners in a single command:

dojops scan
Security Scan ───────────────────────────────────── Detecting available scanners... npm-audit found trivy found gitleaks found hadolint found checkov found shellcheck not installed (skip) semgrep not installed (skip) pip-audit not installed (skip) trivy-sbom found trivy-license found Running 6/10 scanners... npm-audit ✓ 2 findings trivy ✓ 0 findings gitleaks ✓ 0 findings hadolint ✓ 3 findings checkov ✓ 1 finding trivy-license ✓ 0 findings ───────────────────────────────────── Summary: Critical 0 High 1 Medium 3 Low 2 Results saved to .dojops/scan-history/scan-a1b2c3.json

DojOps ran 6 of its 10 scanners — the 4 missing tools were skipped without error. The output tells you exact finding counts per scanner so you know where the problems are before looking at details. No Critical findings is good. The High finding from npm-audit needs attention.

View the detailed findings:

dojops scan --show scan-a1b2c3
Scan Details: scan-a1b2c3 ───────────────────────────────────── npm-audit: [HIGH] GHSA-9c47-m6qq-7p4h semver < 7.5.2 Path: next > postcss > semver Fix: npm update semver [MEDIUM] GHSA-72xf-g2v4-qvf3 Next.js response splitting Path: next@14.0.1 Fix: Upgrade to next@14.0.4 or later hadolint: [MEDIUM] DL3008 apt-get install without pinned versions Line: Dockerfile:14 Fix: Pin: apt-get install -y curl=7.88.1-10+deb12u5 [MEDIUM] DL3018 apk add without pinned versions Line: Dockerfile:22 Fix: Pin: apk add --no-cache bash=5.2.15-r5 [LOW] DL3025 Use JSON array notation for CMD Line: Dockerfile:31 Fix: CMD ["node", "server.js"] checkov: [HIGH] CKV_DOCKER_2 Dockerfile has no HEALTHCHECK Fix: Add HEALTHCHECK instruction

You now have exact file and line references for every finding. The High from checkov is a missing HEALTHCHECK — fixable in one line.


Step 3: Focused scans

Run targeted scans when you only care about a specific category. Useful when you want to verify a specific fix without re-running everything.

Vulnerability and secret detection only:

dojops scan --security
Security Scan (security mode) trivy ✓ 0 findings (container/filesystem vulnerabilities) gitleaks ✓ 0 findings (hardcoded secrets, API keys) No security findings.

No leaked credentials, no known CVEs in your container image.

Dependency audit only:

dojops scan --deps
Dependency Audit npm-audit ✓ 2 findings pip-audit not installed (skip) Findings: [HIGH] semver < 7.5.2 — upgrade via: npm update semver [MEDIUM] next@14.0.1 — upgrade to next@14.0.4

Use --deps when you’ve just updated package.json and want to confirm no new vulnerabilities slipped in.

Infrastructure as Code only:

dojops scan --iac
IaC Scan checkov ✓ 1 finding (Dockerfile/Terraform/K8s policy) hadolint ✓ 3 findings (Dockerfile lint) shellcheck not installed (skip) Findings: [HIGH] CKV_DOCKER_2 Dockerfile — missing HEALTHCHECK [MEDIUM] DL3008 Dockerfile:14 — unpinned apt-get [MEDIUM] DL3018 Dockerfile:22 — unpinned apk add [LOW] DL3025 Dockerfile:31 — CMD not JSON array

IaC scanning catches misconfigurations before deployment, not after. A missing HEALTHCHECK doesn’t fail your build, but it will cause your container orchestrator to route traffic to unhealthy instances.


Step 4: Generate an SBOM

A Software Bill of Materials lists every component in your application — direct dependencies, transitive dependencies, their versions, licenses, and cryptographic hashes. You need one for supply chain security compliance (SOC 2, SLSA, executive orders on software security).

dojops scan --sbom
SBOM Generation ───────────────────────────────────── Format: CycloneDX JSON Scanner: trivy-sbom Target: ./ Scanning dependency tree... Components found: 247 Direct: 18 Transitive: 229 License breakdown: MIT 184 components ISC 31 components Apache-2.0 22 components BSD-3 10 components Output: .dojops/scan-history/sbom-b2c3d4.json

The SBOM is in CycloneDX format — compatible with Grype, Dependency-Track, and most compliance tooling. Each component entry includes its package URL (purl), version, and SHA-256 hash. That hash lets you verify later that the component you shipped matches what was recorded.

Check for license compliance issues:

dojops scan --license
License Audit trivy-license ✓ running License findings: [INFO] GPL-2.0 found in: some-package@1.2.3 Note: GPL requires source disclosure if distributed [INFO] LGPL-2.1 found in: another-package@2.0.0 Note: LGPL requires disclosure of modifications only No policy violations detected.

If your organization prohibits GPL in commercial products, DojOps surfaces those conflicts before they become legal issues.


Step 5: Auto-remediation

Send the scan findings to your LLM provider and generate targeted fixes. The key difference from manual fixing: the LLM has your full project context, so fixes reference your actual Dockerfile structure rather than producing generic snippets.

dojops scan --fix
Auto-Remediation ───────────────────────────────────── Reading latest scan: scan-a1b2c3 Loading project context: .dojops/context.json Sending findings to openai (gpt-4o)... Generating fixes... ───────────────────────────────────── Finding 1: hadolint DL3008 — apt-get without pinned versions File: Dockerfile:14 Fix: Pinned curl to curl=7.88.1-10+deb12u5 Preview: - RUN apt-get install -y curl + RUN apt-get install -y curl=7.88.1-10+deb12u5 Apply? (y/n/skip): y Finding 2: hadolint DL3018 — apk add without pinned versions File: Dockerfile:22 Fix: Pinned bash to bash=5.2.15-r5 Preview: - RUN apk add --no-cache bash + RUN apk add --no-cache bash=5.2.15-r5 Apply? (y/n/skip): y Finding 3: hadolint DL3025 — CMD not in JSON array File: Dockerfile:31 Fix: Converted to exec form Preview: - CMD node server.js + CMD ["node", "server.js"] Apply? (y/n/skip): y Finding 4: checkov CKV_DOCKER_2 — no HEALTHCHECK File: Dockerfile Fix: Added HEALTHCHECK with appropriate interval Preview: + HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))" Apply? (y/n/skip): y ───────────────────────────────────── Remediation summary: Applied: 4 fixes Skipped: 0 Backup: Dockerfile.bak (original preserved) Note: npm-audit findings require package updates: Run: npm update semver Run: npm install next@14.0.4

The npm-audit findings aren’t auto-fixed because updating dependencies requires npm install — DojOps won’t run arbitrary package manager commands without explicit instruction. But the instructions are there. Run them manually, or ask DojOps to generate a script:

dojops "Generate a shell script to apply the npm-audit fixes from the latest scan"

Step 6: Compare scans

After applying fixes, run another scan and compare before and after:

dojops scan dojops scan --compare
Scan Comparison ───────────────────────────────────── Previous: scan-a1b2c3 (2026-03-20 10:00) Current: scan-c3d4e5 (2026-03-20 10:20) Resolved (4 findings): ✓ hadolint DL3008 Dockerfile apt-get now pinned (was MEDIUM) ✓ hadolint DL3018 Dockerfile apk add now pinned (was MEDIUM) ✓ hadolint DL3025 CMD now in JSON array form (was LOW) ✓ checkov CKV_DOCKER_2 HEALTHCHECK now present (was HIGH) New (0 findings): — none Unchanged (2 findings): ! npm-audit semver < 7.5.2 (HIGH — pending manual fix) ! npm-audit next@14.0.1 response splitting (MEDIUM — pending manual fix) ───────────────────────────────────── Trend: 6 → 2 findings (67% reduction) Severity delta: -1 High, -2 Medium, -1 Low

Four findings resolved, none introduced. The two remaining are npm dependency updates you need to run manually. The comparison makes it easy to present security progress to a team or auditor — you have a timestamped, hash-chained record of every scan and fix.


Step 7: Verify the audit trail

All scan operations are logged in the hash-chained audit trail:

dojops history list
◇ Plans (3) ────────────────────────────────────────────────────╮ │ │ │ scan-a1b2c3 COMPLETED 3/20/2026 Full security scan │ │ scan-d4e5f6 COMPLETED 3/20/2026 SBOM generation │ │ scan-g7h8i9 COMPLETED 3/20/2026 Post-remediation scan │ │ │ ├────────────────────────────────────────────────────────────────╯

Verify the chain integrity:

dojops history verify
Audit chain integrity: verified Entries: 4 Chain status: valid (all hashes match)

The audit trail is useful beyond compliance. If a vulnerability reappears after a fix, you can check the history to confirm the fix was actually applied and rule out the possibility that a subsequent operation reverted it.


Try it yourself

Challenge 1 — Scan with severity filter. Run dojops scan --severity=high to see only High and Critical findings. Useful for prioritizing a backlog without noise from Low/Medium items.

Challenge 2 — Export the SBOM. The SBOM is at .dojops/scan-history/sbom-*.json. Open it and find a component with a GPL license. Check whether your project’s license is compatible.

Challenge 3 — Add scanning to CI. Use dojops "Add a security scanning step to the GitHub Actions workflow that fails on High severity findings". Review the diff — it should add dojops scan --security --severity=high as a CI step with a non-zero exit on findings.


Troubleshooting

Only 2 of 10 scanners run Most scanners are external tools you need to install separately. Run dojops scan --list-scanners to see which are available and where to install the missing ones. npm-audit is always available because it uses the npm CLI you already have.

gitleaks reports a finding in a file you don’t recognize Gitleaks scans git history, not just the working tree. A secret committed in a previous commit — even a deleted file — will appear. Rotate the credential and use git filter-repo or BFG to scrub the history.

Auto-remediation generates a fix that breaks your build DojOps creates a .bak before modifying any file. Restore with cp Dockerfile.bak Dockerfile. Then run dojops scan --fix again with a more specific prompt describing your constraint — for example, if you can’t upgrade to a specific package version because of a peer dependency conflict.

SBOM generation fails with “trivy not found” trivy-sbom requires the trivy binary. Install it from aquasecurity.github.io/trivy . On macOS: brew install trivy. On Linux: use the install script from the Trivy docs.


What you learned

You ran a multi-scanner security audit across six categories, generated a CycloneDX SBOM with 247 components, and used LLM-powered auto-remediation to fix four Dockerfile findings. Scan comparison confirmed a 67% reduction in total findings with no regressions introduced. The entire operation — scans, fixes, re-scans — is logged in a hash-chained audit trail that proves the chain of custody for every change.


Next steps