Provide Proof Your Software Is Scanned for Vulnerabilities
For customers who need evidence that an application is checked for security issues. This guide shows exactly what to collect from your build pipeline, dependency scanner, and container scanner so you can send clear proof without involving support.
TL;DR — If a customer asks for proof that your software is scanned for vulnerabilities, send three things: a recent scan report, a screenshot or export from your CI/CD pipeline (automated build-and-deploy process), and the policy showing what happens when high-severity findings appear. The fastest path is usually your source control or CI provider dashboard; if that is not available, run the copy-paste commands below and attach the output. Reading time: ~5 min
Goal
When you finish, you will have a customer-ready evidence pack that shows your software is scanned for vulnerabilities, when it was last scanned, what tools were used, and whether any high or critical findings are currently open.
Prerequisites
- Access to your code hosting or CI/CD dashboard with permission to view pipeline runs and security reports
- Access to your dependency manifest files, such as
package.json,requirements.txt,pom.xml,Gemfile, orgo.mod - If you ship containers: the image name and tag, for example
ghcr.io/acme/app:2026.10.30 - If you use the command line: Git installed — check with:
git --version
- If you use Node.js projects: Node.js 20 or later — check with:
node --version
npm --version
- If you use Python projects: Python 3.11 or later and pip — check with:
python3 --version
pip --version
- If you use containers: Docker or compatible runtime — check with:
docker --version
- A place to save files you will send to the customer, such as a folder named
security-evidence
Steps
Step 1: Collect the latest automated scan result from your CI/CD dashboard
Open your CI/CD provider dashboard, then go to the latest successful production build or the latest default-branch build.
Use this path in your provider's dashboard:
Your CI/CD provider dashboard → Repository/Project → Pipelines or Actions → latest successful run on main/default branch → Artifacts, Security, or Logs
Download or save these exact items if they exist:
- Build log showing the security scan step ran
- Security report artifact in JSON, SARIF, HTML, or PDF
- Timestamp of the run
- Commit SHA (the unique commit ID)
You should see a run page with a completed status and at least one log line or artifact showing a dependency, code, or container scan executed.
Step 2: Export a dependency vulnerability report
If your dashboard already shows dependency scanning, export that report there. If not, run the command that matches your application.
For Node.js:
mkdir -p security-evidence
npm audit --json > security-evidence/npm-audit.json
For Python:
mkdir -p security-evidence
python3 -m pip install --upgrade pip-audit
pip-audit -f json > security-evidence/pip-audit.json
For Java projects using Maven:
mkdir -p security-evidence
mvn -q org.owasp:dependency-check-maven:check
cp target/dependency-check-report.html security-evidence/
For .NET:
mkdir -p security-evidence
dotnet list package --vulnerable --include-transitive > security-evidence/dotnet-vulnerable-packages.txt
You should see a new file in security-evidence containing a machine-readable or human-readable list of dependency findings.
Step 3: Export a container image scan report if you deploy containers
If you do not ship a container image, skip this step.
First try your registry or cloud dashboard:
Your container registry dashboard → Repositories → select image → Tags → select deployed tag → Vulnerabilities or Security scan → Export/Download report
If your registry does not provide an export, run a local scan with Trivy (a common container scanner).
Install and run Trivy on macOS with Homebrew:
brew install trivy
mkdir -p security-evidence
trivy image --format json --output security-evidence/container-scan.json ghcr.io/acme/app:2026.10.30
Run with Docker if you do not want a local install:
mkdir -p security-evidence
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD/security-evidence:/out" aquasec/trivy:latest image --format json --output /out/container-scan.json ghcr.io/acme/app:2026.10.30
You should see security-evidence/container-scan.json created with vulnerability results for the exact image tag you deploy.
Step 4: Capture proof that scans run automatically on every change
The customer usually wants proof that scanning is not manual and occasional.
In your source control or CI dashboard, open the pipeline configuration file and save the relevant section.
Common file names:
.github/workflows/*.yml
.gitlab-ci.yml
azure-pipelines.yml
Jenkinsfile
.circleci/config.yml
If you have shell access to the repository, copy the file into your evidence folder:
mkdir -p security-evidence
cp .github/workflows/*.yml security-evidence/ 2>/dev/null || true
cp .gitlab-ci.yml security-evidence/ 2>/dev/null || true
cp azure-pipelines.yml security-evidence/ 2>/dev/null || true
cp Jenkinsfile security-evidence/ 2>/dev/null || true
cp .circleci/config.yml security-evidence/ 2>/dev/null || true
You should have at least one pipeline config file or screenshot showing a scan job triggered on push, pull request, merge, or release.
View as text
[Developer Commit] ---- 1. push/merge ----> [CI/CD Pipeline] [CI/CD Pipeline] ---- 2. run scans ----> [Security Reports] [CI/CD Pipeline] ---- 3. pass/fail policy ----> [Deploy]
Step 5: Write a one-page summary the customer can read quickly
Create a plain text summary and fill in the literal values.
cat > security-evidence/SCAN-SUMMARY.txt <<'EOF'
Software vulnerability scanning summary
Application: YOUR-APP-NAME
Production version or image tag: YOUR-VERSION-OR-TAG
Default branch: main
Latest scan date (UTC): YYYY-MM-DD HH:MM UTC
Commit SHA scanned: YOUR-COMMIT-SHA
Scans performed:
- Dependency scan: TOOL-NAME
- Container scan: TOOL-NAME or Not applicable
- Static analysis (source code scan): TOOL-NAME or Not applicable
Automation:
- Trigger: On every push to main and on pull requests
- Enforcement: Builds fail on high/critical findings: Yes/No
Current result summary:
- Critical findings open: 0
- High findings open: 0
- Report files attached: LIST-FILES-HERE
EOF
You should see security-evidence/SCAN-SUMMARY.txt with all fields ready to replace.
Step 6: Package the evidence and send it
Create a single archive so the customer gets one attachment.
On macOS or Linux:
zip -r security-evidence.zip security-evidence
On Windows PowerShell:
Compress-Archive -Path security-evidence -DestinationPath security-evidence.zip -Force
You should see security-evidence.zip created and ready to attach to your email or ticket reply.
Verify it works
Check that the evidence pack contains the minimum proof set: one recent report, one automation proof item, and one readable summary.
List the files:
ls -lah security-evidence
Expected result: you see SCAN-SUMMARY.txt plus at least one of these files:
npm-audit.json
pip-audit.json
dependency-check-report.html
dotnet-vulnerable-packages.txt
container-scan.json
pipeline config file or screenshot export
Open the summary and confirm these values are present and not placeholders:
cat security-evidence/SCAN-SUMMARY.txt
Expected result: the file shows the real application name, scan date, commit SHA, tools used, and current counts for high and critical findings.
If you are sending a CI/CD screenshot instead of raw logs, verify the screenshot visibly includes:
- repository or project name
- pipeline/job name
- date/time
- successful or failed status
- scan step name
Common pitfalls
The report is old
Mistake: sending the last scan report you can find, even if it is weeks old.
Symptom: the customer asks, "Is this current for the version we use?"
Fix: rerun or export the latest default-branch or production-tag report and include the commit SHA or image tag in SCAN-SUMMARY.txt.
The report does not match the deployed version
Mistake: scanning latest instead of the exact release tag.
Symptom: the report shows a different version number than the one in production.
Fix: scan the exact deployed artifact, for example ghcr.io/acme/app:2026.10.30, and write that exact tag in the summary.
Only a screenshot is provided, with no readable details
Mistake: sending a green badge screenshot without the underlying report.
Symptom: the customer asks for severity counts, dates, or tool names.
Fix: attach the exported JSON, HTML, or text report and keep the screenshot only as supporting evidence.
The pipeline file is attached, but it does not show the scan step
Mistake: exporting the wrong workflow file or only part of it.
Symptom: the customer cannot see that scanning is automated.
Fix: attach the exact workflow file that contains the scan job, or include a pipeline run log with the scan step name visible.
Findings exist, but the summary says zero
Mistake: manually typing the summary before checking the report.
Symptom: the customer spots a mismatch between the attached report and your summary.
Fix: open the report first, count current high and critical findings, then update SCAN-SUMMARY.txt to match exactly.
Sensitive data is exposed in logs
Mistake: sending raw pipeline logs that contain internal URLs, usernames, or tokens.
Symptom: your security team blocks the customer reply, or you notice secrets in the attachment.
Fix: send the report artifact instead of full logs, or redact the sensitive lines before zipping the evidence folder.
This article was written by an AI system and published pending human review. Verify anything you intend to act on.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI