agent-orchestrator/.github/workflows/security.yml

116 lines
3.7 KiB
YAML

name: Security
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Run weekly to catch new vulnerabilities
- cron: "0 8 * * 1"
workflow_dispatch: # Allow manual triggering
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
gitleaks:
name: Scan for Secrets
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history to ensure base/head SHAs are available for PR scans
- name: Install Gitleaks
run: |
set -euo pipefail
GITLEAKS_VERSION="8.24.3"
GITLEAKS_BASE_URL="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}"
RUNNER_ARCH="$(uname -m)"
case "${RUNNER_ARCH}" in
x86_64|amd64)
GITLEAKS_ARCH="x64"
;;
aarch64|arm64)
GITLEAKS_ARCH="arm64"
;;
*)
echo "Unsupported runner architecture: ${RUNNER_ARCH}" >&2
exit 1
;;
esac
ARCHIVE_NAME="gitleaks_${GITLEAKS_VERSION}_linux_${GITLEAKS_ARCH}.tar.gz"
# Download gitleaks archive using the release filename so checksum verification works
curl -sSfL "${GITLEAKS_BASE_URL}/${ARCHIVE_NAME}" -o "${ARCHIVE_NAME}"
# Download the combined checksums file
curl -sSfL "${GITLEAKS_BASE_URL}/gitleaks_${GITLEAKS_VERSION}_checksums.txt" -o gitleaks_checksums.txt
# Verify checksum (sha256sum -c expects the filename in the checksums file to match the local file)
grep "${ARCHIVE_NAME}" gitleaks_checksums.txt | sha256sum -c -
# Extract the verified binary to a user-writable directory and add it to PATH
INSTALL_DIR="${RUNNER_TEMP}/gitleaks-bin"
mkdir -p "${INSTALL_DIR}"
tar -xzf "${ARCHIVE_NAME}" -C "${INSTALL_DIR}" gitleaks
echo "${INSTALL_DIR}" >> "${GITHUB_PATH}"
# Clean up
rm -f "${ARCHIVE_NAME}" gitleaks_checksums.txt
- name: Run Gitleaks
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
# Ensure the base and head SHAs exist locally when checkout uses the PR merge ref
git fetch origin ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} --depth=1
gitleaks detect --source . --verbose --log-opts "${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
else
gitleaks detect --source . --verbose --log-opts "-n 10"
fi
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
npm-audit:
name: NPM Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run npm audit
run: pnpm audit --audit-level=moderate
continue-on-error: true # Don't fail build on vulnerabilities in deps
- name: Run pnpm audit (strict)
run: pnpm audit --prod --audit-level=high
continue-on-error: true # npm's legacy audit endpoint returns 410 Gone — non-blocking until pnpm upgrades to bulk advisory API