Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
name: run-manual-docker-security-scan
description: Guide for running a manual Docker security scan for the tracker runtime image and documenting results. Covers build, Trivy scan, CVE triage, per-CVE catalog updates, and scan history updates. Use when asked to run a manual container scan, triage Docker CVEs, or refresh security scan docs.
metadata:
author: torrust
version: "1.0"
semantic-links:
related-artifacts:
- Containerfile
- docs/security/README.md
- docs/security/docker/README.md
- docs/security/docker/scans/README.md
- docs/security/docker/scans/torrust-tracker.md
- docs/security/analysis/README.md
- docs/security/analysis/non-affecting/
---

# Run Manual Docker Security Scan

Use this workflow to run and document manual security scans for the tracker production container.

## Scope

- Target image: tracker runtime image built from root `Containerfile`.
- Main severity gate: `HIGH,CRITICAL`.
- Documentation outputs:
- `docs/security/docker/scans/torrust-tracker.md`
- `docs/security/docker/scans/README.md`
- `docs/security/analysis/non-affecting/CVE-*.md` (when non-affecting CVEs are analyzed)

## Quick Commands

```bash
# 1) Build runtime image
docker build -t torrust-tracker:local -f Containerfile .

# 2) Gate scan (primary)
trivy image --severity HIGH,CRITICAL torrust-tracker:local

# 3) Full context scan (optional but recommended)
trivy image --severity MEDIUM,HIGH,CRITICAL torrust-tracker:local
```

## Workflow

### Step 1: Check Existing Catalog First

Before analyzing any CVE, search the existing catalog:

```bash
grep -R "CVE-<id>" docs/security/analysis/non-affecting/
```

If already present and `requires-recheck-when` conditions have not changed, reuse the existing verdict.

### Step 2: Build and Scan

- Build local runtime image from `Containerfile`.
- Run the gate scan with `HIGH,CRITICAL`.
- Run optional full scan (`MEDIUM,HIGH,CRITICAL`) to capture trend context.

### Step 3: Update Scan History Docs

Update:

- `docs/security/docker/scans/torrust-tracker.md` with:
- date/time, Trivy version, totals by severity
- notable CVEs and rationale
- `docs/security/docker/scans/README.md` summary table with latest status and date.

### Step 4: Document New Non-Affecting CVEs

For any new non-affecting CVE, create `docs/security/analysis/non-affecting/CVE-<id>.md` with:

- frontmatter fields:
- `cve-id`
- `date-analyzed`
- `source`
- `status: non-affecting`
- `review-cadence`
- `requires-recheck-when`
- evidence-based explanation tied to tracker architecture
- conditions that would invalidate the current verdict

### Step 5: Escalate Affecting CVEs

If a CVE is affecting:

- create/update a tracking issue
- include impact, affected component, exploitability context, and remediation plan
- update scan docs with current status and owner

## Recheck Triggers

Re-evaluate catalog verdicts when any of these happen:

- `Containerfile` base image changes
- new runtime/system dependency is introduced
- code path changes that satisfy a CVE file's `requires-recheck-when` condition

## Completion Checklist

- [ ] `trivy` gate scan executed (`HIGH,CRITICAL`)
- [ ] scan history files updated
- [ ] new CVEs cataloged or linked to existing catalog entries
- [ ] affecting CVEs escalated
- [ ] `linter all` passes
91 changes: 91 additions & 0 deletions .github/workflows/security-scan.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Security Scan

on:
push:
branches: [main, develop]
paths:
- "Containerfile"
- ".github/workflows/security-scan.yaml"

pull_request:
paths:
- "Containerfile"
- ".github/workflows/security-scan.yaml"

# Scheduled scans are important because new CVEs appear
# even if the code or images didn't change
schedule:
- cron: "0 6 * * *" # Daily at 6 AM UTC

workflow_dispatch:

env:
CARGO_TERM_COLOR: always

jobs:
security-scan:
name: Security Scan
runs-on: ubuntu-latest
# Scheduled scans pull the pre-built image; push/PR triggers rebuild from
# source (Containerfile change). Rust compilation can exceed 25 min.
timeout-minutes: 45
permissions:
contents: read
security-events: write

steps:
- name: Checkout code
uses: actions/checkout@v4

# Scheduled scans use the pre-built develop image from Docker Hub.
# Push/PR triggers on Containerfile changes need to build from source.
- name: Determine image source
id: image-source
run: |
if [ "${{ github.event_name }}" = "schedule" ]; then
echo "method=pull" >> "$GITHUB_OUTPUT"
echo "image=torrust/tracker:develop" >> "$GITHUB_OUTPUT"
else
echo "method=build" >> "$GITHUB_OUTPUT"
echo "image=torrust-tracker:local" >> "$GITHUB_OUTPUT"
fi

- name: Pull or build Docker image
run: |
if [ "${{ steps.image-source.outputs.method }}" = "pull" ]; then
docker pull "${{ steps.image-source.outputs.image }}"
else
docker build -t "${{ steps.image-source.outputs.image }}" -f Containerfile .
fi

# Human-readable output in logs
# This NEVER fails the job; it's only for visibility
- name: Display vulnerabilities (table format)
uses: aquasecurity/trivy-action@0.35.0
with:
image-ref: ${{ steps.image-source.outputs.image }}
format: "table"
severity: "HIGH,CRITICAL"
exit-code: "0"

# SARIF generation for GitHub Code Scanning
#
# IMPORTANT:
# - exit-code MUST be 0
# - Trivy sometimes exits with 1 even when no vulns exist
# - GitHub Security UI is responsible for enforcement
- name: Generate SARIF (Code Scanning)
uses: aquasecurity/trivy-action@0.35.0
with:
image-ref: ${{ steps.image-source.outputs.image }}
format: "sarif"
output: "trivy-results.sarif"
severity: "HIGH,CRITICAL"
exit-code: "0"
scanners: "vuln"

- name: Upload SARIF to Code Scanning
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: trivy-results.sarif
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Torrust Tracker

[![container_wf_b]][container_wf] [![coverage_wf_b]][coverage_wf] [![deployment_wf_b]][deployment_wf] [![testing_wf_b]][testing_wf] [![os_compat_wf_b]][os_compat_wf] [![db_compat_wf_b]][db_compat_wf] [![db_bench_wf_b]][db_bench_wf] [![docs_lint_wf_b]][docs_lint_wf]
[![container_wf_b]][container_wf] [![coverage_wf_b]][coverage_wf] [![deployment_wf_b]][deployment_wf] [![testing_wf_b]][testing_wf] [![os_compat_wf_b]][os_compat_wf] [![db_compat_wf_b]][db_compat_wf] [![db_bench_wf_b]][db_bench_wf] [![docs_lint_wf_b]][docs_lint_wf] [![security_scan_wf_b]][security_scan_wf]

**Torrust Tracker** is a [BitTorrent][bittorrent] Tracker that matchmakes peers and collects statistics. Written in [Rust Language][rust] with the [Axum] web framework. **This tracker aims to be respectful to established standards, (both [formal][BEP 00] and [otherwise][torrent_source_felid]).**

Expand Down Expand Up @@ -270,6 +270,8 @@ This project was a joint effort by [Nautilus Cyberneering GmbH][nautilus] and [D
[db_bench_wf_b]: ../../actions/workflows/db-benchmarking.yaml/badge.svg
[docs_lint_wf]: ../../actions/workflows/docs-lint.yaml
[docs_lint_wf_b]: ../../actions/workflows/docs-lint.yaml/badge.svg
[security_scan_wf]: ../../actions/workflows/security-scan.yaml
[security_scan_wf_b]: ../../actions/workflows/security-scan.yaml/badge.svg
[bittorrent]: http://bittorrent.org/
[rust]: https://www.rust-lang.org/
[axum]: https://github.com/tokio-rs/axum
Expand Down
158 changes: 158 additions & 0 deletions docs/issues/open/1459-docker-security-overhaul/ISSUE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
---
doc-type: issue
issue-type: task
status: completed
priority: p2
github-issue: 1459
spec-path: docs/issues/open/1459-docker-security-overhaul/ISSUE.md
branch: 1459-docker-security-overhaul
related-pr: "https://github.com/torrust/torrust-tracker/pull/1958"
last-updated-utc: 2026-06-29
semantic-links:
skill-links:
- create-issue
related-artifacts:
- .github/workflows/security-scan.yaml
- Containerfile
- .github/workflows/container.yaml
- .github/skills/dev/maintenance/run-manual-docker-security-scan/SKILL.md
- docs/security/README.md
- docs/security/docker/scans/
- docs/security/docker/README.md
- docs/security/analysis/non-affecting/
---

# Issue #1459 - Docker Security Overhaul: Set Up Security Scanning Workflow

## Problem

The torrust-tracker Docker image contains known vulnerabilities that need to be regularly scanned and monitored. As demonstrated by the Trivy scan results, the current image has multiple security vulnerabilities including critical, high, and medium severity issues.

## Goal

Implement a scheduled workflow to periodically scan Docker images for vulnerabilities and misconfigurations, ensuring the security posture of the application is maintained.

## Acceptance Criteria

- [x] A new GitHub Actions workflow is created in `.github/workflows/security-scan.yaml`
- [x] The workflow runs on a schedule (daily) to scan the Docker image
- [x] The workflow builds the Docker image and scans it with Trivy
- [x] Vulnerability findings are reported in both human-readable and SARIF formats
- [x] The workflow integrates with the existing container build process
- [x] The README.md badge row includes the new security scan workflow badge
- [x] `docs/security/docker/scans/` is created with the first baseline scan report
- [x] `docs/security/docker/README.md` provides scanning instructions
- [x] `docs/security/README.md` provides a priority-tier security overview
- [x] Per-CVE analysis files created in `docs/security/analysis/non-affecting/` for each
MEDIUM vulnerability found in the baseline scan
- [x] `docs/security/analysis/README.md` documents the catalog strategy and recheck policy
- [x] A maintenance skill exists at
`.github/skills/dev/maintenance/run-manual-docker-security-scan/SKILL.md`
documenting how to run and document manual Docker security scans

## Implementation Plan

### Step 1: Create Security Scan Workflow

Create a new workflow file `.github/workflows/security-scan.yaml` that:

- Runs on a schedule (daily at 6 AM UTC) and on push to main/develop branches
- Builds the Docker image using the Containerfile
- Scans the image with Trivy
- Reports results in both table and SARIF formats

### Step 2: Configure Trivy Scanning

Configure the workflow to:

- Use Trivy to scan the Docker image
- Report vulnerabilities in both human-readable table format and SARIF format for GitHub Code Scanning
- Generate SARIF output for integration with GitHub Security features

### Step 3: Integrate with Existing Workflows

Ensure the security scan workflow integrates properly with the existing container workflow.

### Step 4: Add Workflow Badge to README.md

Add the security scan workflow badge to the README.md header row and consistent reference links at the bottom, following the same pattern as existing workflow badges.

### Step 5: Create Security Documentation and Run Baseline Scan

Create `docs/security/docker/` structure mirroring the deployer's security docs pattern:

- `docs/security/docker/README.md` β€” scanning instructions and context
- `docs/security/docker/scans/README.md` β€” scan history index table
- `docs/security/docker/scans/torrust-tracker.md` β€” detailed scan report with vulnerability analysis

Run the first manual baseline scan of the production `release` stage image and document all findings, including vulnerability analysis and severity assessment.

### Step 6: Create Top-Level Security Overview

Create `docs/security/README.md` providing a priority-tier overview of security areas for the project, mirroring the deployer's top-level security README pattern:

- Priority 1: Production Docker image (critical, internet-exposed)
- Priority 2: Vulnerability analysis (evaluation and tracking)
- Priority 3: Build chain security (lower-risk, build-time only)
- Current security status summary
- Scan tooling reference

### Step 7: Create Non-Affecting CVE Catalog

Create per-CVE analysis files in `docs/security/analysis/non-affecting/` for each
vulnerability found in the baseline scan, following this pattern:

```text
non-affecting/
β”œβ”€β”€ CVE-2026-5435.md # glibc TSIG
β”œβ”€β”€ CVE-2026-5450.md # glibc scanf
β”œβ”€β”€ CVE-2026-5928.md # glibc ungetwc
β”œβ”€β”€ CVE-2026-6238.md # glibc DNS response
└── CVE-2026-27171.md # zlib CRC32
```

Each file includes:

- Frontmatter with `cve-id`, `date-analyzed`, `source`, `status`, `review-cadence`,
and `requires-recheck-when` conditions
- Vulnerability description and severity
- Evidence-based rationale for why it does not affect the tracker
- Conditions that would change the verdict

Update `docs/security/analysis/README.md` to document the catalog strategy (one catalog
for all vulnerability sources, per-CVE files preferred, with recheck policy).

### Step 8: Add Maintenance Skill for Manual Security Scans

Create a new skill at
`.github/skills/dev/maintenance/run-manual-docker-security-scan/SKILL.md` to standardize
how contributors run manual Docker security scans and maintain scan documentation.

The skill should include:

- build and scan commands (`docker build`, `trivy image`)
- triage workflow (check catalog first, then analyze)
- documentation update requirements (`docs/security/docker/scans/*` and
`docs/security/analysis/non-affecting/CVE-*.md`)
- recheck triggers and escalation path for affecting vulnerabilities

## References

- Original issue: https://github.com/torrust/torrust-tracker/issues/1459
- Related issue #1630
- Trivy documentation for GitHub Actions integration
- Tracker Deployer security scan workflow for reference: https://github.com/torrust/torrust-tracker-deployer/blob/main/.github/workflows/docker-security-scan.yml

## Verification Plan

### Automatic Checks

- [ ] Workflow file is created and syntactically correct
- [ ] Workflow runs successfully on schedule
- [ ] Trivy scan produces expected output

### Manual Verification Scenarios

- [ ] Run workflow manually to verify it scans the image
- [ ] Verify vulnerability reports are generated correctly
- [ ] Confirm workflow integrates with existing container workflow
Loading
Loading