diff --git a/CI/security/trivy.yml b/CI/security/trivy.yml new file mode 100644 index 0000000..3128239 --- /dev/null +++ b/CI/security/trivy.yml @@ -0,0 +1,37 @@ +trivy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Cache Trivy DB + uses: actions/cache@v4 + with: + path: ~/.cache/trivy + key: trivy-db-${{ runner.os }} + + - name: Install Trivy + run: | + TRIVY_VERSION="0.61.0" + BASE="https://github.com/aquasecurity/trivy/releases/download" + FILE="trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" + curl -sSfL "${BASE}/v${TRIVY_VERSION}/${FILE}" \ + | tar -xz -C /usr/local/bin trivy + + - name: Run Trivy + run: | + set -euo pipefail + + if ! command -v trivy &> /dev/null; then + echo "::error::trivy not found. Install it before running this script." + exit 1 + fi + + echo "ℹ️ Running Trivy filesystem scan..." + + if trivy fs --exit-code 1 --severity HIGH,CRITICAL --no-progress .; then + echo "✅ No HIGH/CRITICAL vulnerabilities" + exit 0 + else + echo "❌ Trivy found HIGH/CRITICAL vulnerabilities" + exit 1 + fi diff --git a/README.md b/README.md index a2f9c87..8a137f9 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ that projects compose into their own workflows. | Tool | Category | File | |------|----------|------| | gitleaks | security | [CI/security/gitleaks.yml](https://github.com/prog-time/workflows/blob/main/CI/security/gitleaks.yml) | +| trivy | security | [CI/security/trivy.yml](https://github.com/prog-time/workflows/blob/main/CI/security/trivy.yml) | | ESLint | linters | [CI/linters/eslint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/eslint.yml) | | golangci-lint | linters | [CI/linters/golangci-lint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/golangci-lint.yml) | | Hadolint | linters | [CI/linters/hadolint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/hadolint.yml) | @@ -80,7 +81,8 @@ Workflows/ │ │ │ ├── swiftlint.yml │ │ │ └── yamllint.yml │ │ ├── security/ -│ │ │ └── gitleaks.yml +│ │ │ ├── gitleaks.yml +│ │ │ └── trivy.yml │ │ ├── static_analysis/ │ │ │ ├── mypy.yml │ │ │ ├── phpstan.yml @@ -107,7 +109,8 @@ Workflows/ │ │ ├── swiftlint.sh │ │ └── yamllint.sh │ └── security/ -│ └── gitleaks.sh +│ ├── gitleaks.sh +│ └── trivy.sh │ ├── CI/ # assembled output (ready to use) │ ├── linters/ @@ -125,7 +128,8 @@ Workflows/ │ │ ├── stylelint.bats │ │ └── yamllint.bats │ ├── security/ -│ │ └── gitleaks.bats +│ │ ├── gitleaks.bats +│ │ └── trivy.bats │ └── helpers/ │ └── common.bash # shared test utilities (mocks, temp dirs) │ @@ -199,6 +203,7 @@ shellcheck: | Snippet | Tool | What it checks | |---------|------|----------------| | `CI/security/gitleaks.yml` | [gitleaks](https://github.com/gitleaks/gitleaks) | Hardcoded secrets, tokens, and API keys | +| `CI/security/trivy.yml` | [trivy](https://github.com/aquasecurity/trivy) | CVEs in OS packages, container images, and dependency manifests | ### Linters diff --git a/scripts/CI/security/trivy.yml b/scripts/CI/security/trivy.yml new file mode 100644 index 0000000..b1da65b --- /dev/null +++ b/scripts/CI/security/trivy.yml @@ -0,0 +1,21 @@ +trivy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Cache Trivy DB + uses: actions/cache@v4 + with: + path: ~/.cache/trivy + key: trivy-db-${{ runner.os }} + + - name: Install Trivy + run: | + TRIVY_VERSION="0.61.0" + BASE="https://github.com/aquasecurity/trivy/releases/download" + FILE="trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" + curl -sSfL "${BASE}/v${TRIVY_VERSION}/${FILE}" \ + | tar -xz -C /usr/local/bin trivy + + - name: Run Trivy + run: bash scripts/shell/security/trivy.sh diff --git a/scripts/shell/security/trivy.sh b/scripts/shell/security/trivy.sh new file mode 100644 index 0000000..1c024ac --- /dev/null +++ b/scripts/shell/security/trivy.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail + +if ! command -v trivy &> /dev/null; then + echo "::error::trivy not found. Install it before running this script." + exit 1 +fi + +echo "ℹ️ Running Trivy filesystem scan..." + +if trivy fs --exit-code 1 --severity HIGH,CRITICAL --no-progress .; then + echo "✅ No HIGH/CRITICAL vulnerabilities" + exit 0 +else + echo "❌ Trivy found HIGH/CRITICAL vulnerabilities" + exit 1 +fi diff --git a/tests/security/trivy.bats b/tests/security/trivy.bats new file mode 100644 index 0000000..87dedf6 --- /dev/null +++ b/tests/security/trivy.bats @@ -0,0 +1,52 @@ +#!/usr/bin/env bats + +load "../helpers/common" + +SCRIPT="$BATS_TEST_DIRNAME/../../scripts/shell/security/trivy.sh" + +setup() { + setup_test_dir + mkdir -p "$TEST_DIR/bin" + export PATH="$TEST_DIR/bin:$PATH" +} + +teardown() { + teardown_test_dir +} + +make_trivy_stub() { + local exit_code="$1" + cat > "$TEST_DIR/bin/trivy" <