diff --git a/.github/workflows/snyk-scan.yaml b/.github/workflows/snyk-scan.yaml deleted file mode 100644 index 96709fc..0000000 --- a/.github/workflows/snyk-scan.yaml +++ /dev/null @@ -1,209 +0,0 @@ -name: Snyk Security Scan - -on: - workflow_call: - inputs: - fail-on-issues: - required: false - type: boolean - default: true - description: "Whether to fail the build if vulnerabilities are found" - - severity-threshold: - required: false - type: string - default: "high" - description: "Minimum severity to fail on (low|medium|high|critical)" - - target-file: - required: false - type: string - description: "Specific file to scan (e.g., package.json, go.mod, pom.xml)" - - command: - required: false - type: string - default: "test" - description: "Snyk command to run (test|monitor|iac test|container test)" - - args: - required: false - type: string - default: "" - description: "Additional arguments to pass to Snyk CLI" - - snyk-org: - required: false - type: string - description: "Snyk organization slug or ID" - - debug: - required: false - type: boolean - default: false - description: "Enable debug mode (-d flag) for verbose output" - - upload-sarif: - required: false - type: boolean - default: true - description: "Whether to upload SARIF results to GitHub Security" - - sarif-file-output: - required: false - type: string - default: "snyk.sarif" - description: "Path for SARIF output file" - - json-file-output: - required: false - type: string - default: "snyk.json" - description: "Path for JSON output file" - - outputs: - vulnerabilities-found: - description: "Whether vulnerabilities were found (true/false)" - value: ${{ jobs.snyk-scan.outputs.vulnerabilities-found }} - -jobs: - snyk-scan: - runs-on: ubuntu-latest - permissions: - contents: read - security-events: write - actions: read - outputs: - vulnerabilities-found: ${{ steps.snyk-scan.outputs.vulnerabilities-found }} - - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Setup Snyk - uses: snyk/actions/setup@master - - - name: Run Snyk Security Scan - id: snyk-scan - env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} - run: | - set +e # Don't exit on error immediately - - # Verify token is set - if [ -z "$SNYK_TOKEN" ]; then - echo "❌ ERROR: SNYK_TOKEN is not set" - exit 1 - fi - - echo "✅ SNYK_TOKEN is set (length: ${#SNYK_TOKEN})" - - # Build the Snyk command - SNYK_CMD="snyk ${{ inputs.command }}" - - # Add debug flag if enabled - if [ "${{ inputs.debug }}" = "true" ]; then - SNYK_CMD="$SNYK_CMD -d" - echo "🐛 Debug mode enabled" - fi - - # Add organization if specified - if [ -n "${{ inputs.snyk-org }}" ]; then - SNYK_CMD="$SNYK_CMD --org=${{ inputs.snyk-org }}" - fi - - # Add severity threshold - SNYK_CMD="$SNYK_CMD --severity-threshold=${{ inputs.severity-threshold }}" - - # Add SARIF output if upload is enabled - if [ "${{ inputs.upload-sarif }}" = "true" ]; then - SNYK_CMD="$SNYK_CMD --sarif-file-output=${{ inputs.sarif-file-output }}" - fi - - # Add JSON output for detailed reporting - SNYK_CMD="$SNYK_CMD --json-file-output=${{ inputs.json-file-output }}" - - # Add target file if specified - if [ -n "${{ inputs.target-file }}" ]; then - SNYK_CMD="$SNYK_CMD --file=${{ inputs.target-file }}" - fi - - # Add additional args if specified - if [ -n "${{ inputs.args }}" ]; then - SNYK_CMD="$SNYK_CMD ${{ inputs.args }}" - fi - - echo "Running: $SNYK_CMD" - - # Run Snyk scan - eval "$SNYK_CMD" - SNYK_EXIT_CODE=$? - - # Set output based on exit code - if [ "$SNYK_EXIT_CODE" -eq 0 ]; then - echo "vulnerabilities-found=false" >> "$GITHUB_OUTPUT" - echo "✅ No vulnerabilities found" - else - echo "vulnerabilities-found=true" >> "$GITHUB_OUTPUT" - echo "âš ī¸ Vulnerabilities found or scan error occurred" - fi - - # Handle fail-on-issues flag - if [ "${{ inputs.fail-on-issues }}" = "true" ]; then - echo "fail-on-issues is enabled, preserving exit code" - exit "$SNYK_EXIT_CODE" - else - echo "fail-on-issues is disabled, reporting only" - exit 0 - fi - - - name: Parse Snyk results and create summary - if: always() && hashFiles(inputs.json-file-output) != '' - run: | - echo "## 🔍 Snyk Security Scan Results" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - - if [ -f "${{ inputs.json-file-output }}" ]; then - # Extract vulnerability counts by severity - CRITICAL=$(jq '[.vulnerabilities[]? | select(.severity=="critical")] | length' "${{ inputs.json-file-output }}" 2>/dev/null || echo "0") - HIGH=$(jq '[.vulnerabilities[]? | select(.severity=="high")] | length' "${{ inputs.json-file-output }}" 2>/dev/null || echo "0") - MEDIUM=$(jq '[.vulnerabilities[]? | select(.severity=="medium")] | length' "${{ inputs.json-file-output }}" 2>/dev/null || echo "0") - LOW=$(jq '[.vulnerabilities[]? | select(.severity=="low")] | length' "${{ inputs.json-file-output }}" 2>/dev/null || echo "0") - - { - echo "| Severity | Count |" - echo "|----------|-------|" - echo "| 🔴 Critical | $CRITICAL |" - echo "| 🟠 High | $HIGH |" - echo "| 🟡 Medium | $MEDIUM |" - echo "| đŸŸĸ Low | $LOW |" - echo "" - } >> "$GITHUB_STEP_SUMMARY" - - TOTAL=$((CRITICAL + HIGH + MEDIUM + LOW)) - if [ "$TOTAL" -gt 0 ]; then - echo "âš ī¸ **Total vulnerabilities found: $TOTAL**" >> "$GITHUB_STEP_SUMMARY" - else - echo "✅ **No vulnerabilities found**" >> "$GITHUB_STEP_SUMMARY" - fi - else - echo "â„šī¸ No JSON output file found" >> "$GITHUB_STEP_SUMMARY" - fi - - - name: Upload Snyk SARIF results to GitHub Security - if: always() && inputs.upload-sarif == true && hashFiles(inputs.sarif-file-output) != '' - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: ${{ inputs.sarif-file-output }} - category: snyk-${{ inputs.command }} - - - name: Upload Snyk results as artifacts - if: always() - uses: actions/upload-artifact@v7 - with: - name: snyk-results-${{ github.run_id }} - path: | - ${{ inputs.sarif-file-output }} - ${{ inputs.json-file-output }} - retention-days: 30 - if-no-files-found: ignore diff --git a/docs/README.md b/docs/README.md index ad74ef9..80259e5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,10 +5,6 @@ available for use across the organization. ## Available Actions -### Security & Compliance - -- [**Snyk Security Scan**](./snyk-scan/) - Comprehensive security vulnerability scanning for dependencies, IaC, containers, and code using Snyk - ### Publishing & Distribution - [**Publish Docker Images**](./publish-docker/) - Build and push Docker images to GitHub Container Registry diff --git a/docs/snyk-scan/README.md b/docs/snyk-scan/README.md deleted file mode 100644 index ead1b95..0000000 --- a/docs/snyk-scan/README.md +++ /dev/null @@ -1,280 +0,0 @@ -# Snyk Security Scan - -The `.github/workflows/snyk-scan.yaml` reusable GitHub Action performs security -vulnerability scanning using **Snyk** for dependencies, Infrastructure as Code (IaC), -containers, and code. - -## 🚀 Usage - -### Inputs - -- **command** (optional, default: `test`): Snyk command to run. Options: `test`, `monitor`, `iac test`, `container test`, `code test`. -- **fail-on-issues** (optional, default: `true`): Whether to fail the build if vulnerabilities are found. -- **severity-threshold** (optional, default: `high`): Minimum severity to fail on. Options: `low`, `medium`, `high`, `critical`. -- **target-file** (optional): Specific file to scan (e.g., `package.json`, `go.mod`, `pom.xml`). -- **args** (optional): Additional arguments to pass to Snyk CLI. -- **snyk-org** (optional): Snyk organization slug or ID. -- **debug** (optional, default: `false`): Enable debug mode (`-d` flag) for verbose output. -- **upload-sarif** (optional, default: `true`): Whether to upload SARIF results to GitHub Security. -- **sarif-file-output** (optional, default: `snyk.sarif`): Path for SARIF output file. -- **json-file-output** (optional, default: `snyk.json`): Path for JSON output file. - -### Outputs - -- **vulnerabilities-found**: Whether vulnerabilities were found (`true`/`false`). - -### Required Secrets - -- **SNYK_TOKEN**: Snyk API token for authentication. Must be configured in repository or organization secrets. - -### Required Permissions - -```yaml -permissions: - contents: read - security-events: write - actions: read -``` - -## Features - -- ✅ **Multi-scan support**: Dependencies, IaC, containers, and code scanning -- ✅ **GitHub Security integration**: Automatic SARIF upload to Security tab -- ✅ **Detailed reporting**: JSON output with vulnerability breakdown -- ✅ **Workflow summary**: Visual table with severity counts -- ✅ **Artifact retention**: Results saved for 30 days for audit purposes -- ✅ **Flexible configuration**: Customizable thresholds and failure modes -- ✅ **Monitor mode**: Track vulnerabilities over time in Snyk dashboard - -## Best Practices - -- Always use a tagged version when referencing the GitHub action workflow to prevent unexpected breaking changes. -- Enable `upload-sarif: true` to integrate with GitHub Security features. -- Use `fail-on-issues: true` in pull requests to prevent merging vulnerable code. -- Configure `monitor` command on main/master branches to track vulnerabilities over time. -- Set appropriate `severity-threshold` based on your project's security requirements. -- Review artifacts regularly for compliance and audit purposes. - -## Workflow Examples - -### Basic IaC Scan - -Scan Infrastructure as Code files (Terraform, CloudFormation, Kubernetes, etc.): - -```yaml -name: Snyk Security Scan - -on: - push: - pull_request: - -jobs: - snyk-iac: - permissions: - contents: read - security-events: write - actions: read - uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@v1 - with: - command: "iac test" - fail-on-issues: false - severity-threshold: "high" - upload-sarif: true - snyk-org: ${{ vars.SNYK_ORG }} - secrets: inherit -``` - -### Dependency Scan with Strict Mode - -Fail on critical vulnerabilities in dependencies: - -```yaml -name: Snyk Dependency Scan - -on: - pull_request: - -jobs: - snyk-dependencies: - permissions: - contents: read - security-events: write - actions: read - uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@v1 - with: - command: "test" - fail-on-issues: true - severity-threshold: "critical" - upload-sarif: true - snyk-org: ${{ vars.SNYK_ORG }} - secrets: inherit -``` - -### Container Image Scan - -Scan Docker container images for vulnerabilities: - -```yaml -name: Snyk Container Scan - -on: - push: - branches: [main] - -jobs: - snyk-container: - permissions: - contents: read - security-events: write - actions: read - uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@v1 - with: - command: "container test" - args: "myapp:latest" - fail-on-issues: true - severity-threshold: "high" - upload-sarif: true - snyk-org: ${{ vars.SNYK_ORG }} - secrets: inherit -``` - -### Multi-Scan with Monitor - -Combine test and monitor for comprehensive security: - -```yaml -name: Snyk Security - -on: - push: - branches: [main, master] - -jobs: - snyk-test: - permissions: - contents: read - security-events: write - actions: read - uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@v1 - with: - command: "test" - fail-on-issues: false - upload-sarif: true - snyk-org: ${{ vars.SNYK_ORG }} - secrets: inherit - - snyk-monitor: - needs: snyk-test - permissions: - contents: read - security-events: write - actions: read - uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@v1 - with: - command: "monitor" - fail-on-issues: false - upload-sarif: false - snyk-org: ${{ vars.SNYK_ORG }} - secrets: inherit -``` - -### Scheduled Security Audit - -Run daily security scans to detect new vulnerabilities: - -```yaml -name: Scheduled Security Scan - -on: - schedule: - - cron: '0 2 * * *' # Daily at 2 AM UTC - -jobs: - snyk-scan: - permissions: - contents: read - security-events: write - actions: read - uses: datum-cloud/actions/.github/workflows/snyk-scan.yaml@v1 - with: - command: "test" - fail-on-issues: false - severity-threshold: "medium" - upload-sarif: true - snyk-org: ${{ vars.SNYK_ORG }} - secrets: inherit -``` - -## Results Visualization - -### GitHub Security Tab - -SARIF results are automatically uploaded to the Security tab: -- Navigate to **Security** → **Code scanning** → **Snyk** -- View detailed vulnerability information with remediation advice - -### Workflow Summary - -Each workflow run displays a summary table with vulnerability counts: - -| Severity | Count | -|----------|-------| -| 🔴 Critical | X | -| 🟠 High | X | -| 🟡 Medium | X | -| đŸŸĸ Low | X | - -### Artifacts - -JSON and SARIF files are saved as artifacts for 30 days, accessible from the workflow run page. - -### Snyk Dashboard - -When using `monitor` command, view historical trends and detailed analysis in the Snyk dashboard. - -## Supported Commands - -| Command | Description | Generates SARIF | -|---------|-------------|-----------------| -| `test` | Scan dependencies for vulnerabilities | ✅ | -| `monitor` | Send snapshot to Snyk for continuous monitoring | ❌ | -| `iac test` | Scan Infrastructure as Code files | ✅ | -| `container test` | Scan container images | ✅ | -| `code test` | Scan source code (SAST) | ✅ | - -## Troubleshooting - -### Error: SNYK_TOKEN is not set - -- Verify the `SNYK_TOKEN` secret exists in repository or organization settings -- Ensure `secrets: inherit` is specified in the workflow - -### SARIF upload fails - -- Verify `upload-sarif: true` is set -- Check that `security-events: write` permission is granted -- Confirm the Snyk command supports SARIF output (e.g., `monitor` does not) - -### Workflow fails unexpectedly - -- Enable `debug: true` temporarily for verbose output -- Review the "Run Snyk Security Scan" step logs -- Verify the command is compatible with your project type - -## Configuration Variables - -### Repository Variables (Optional) - -- **SNYK_ORG**: Snyk organization slug or ID for centralized configuration - -### Repository Secrets (Required) - -- **SNYK_TOKEN**: Snyk API authentication token - - Obtain from: https://app.snyk.io/account - - Add to: Settings → Secrets and variables → Actions → New repository secret - -## Additional Resources - -- [Snyk CLI Documentation](https://docs.snyk.io/snyk-cli) -- [GitHub Code Scanning](https://docs.github.com/en/code-security/code-scanning) -- [SARIF Format Specification](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning)