Troubleshooting
CI/CD Issues

CI/CD Issues

Build fails on "high" findings

Symptom: The CI workflow fails because NAT found high-severity issues.

This is the intended behavior when fail-on: high is configured. The build is designed to fail when security issues are found.

Options:

  1. Fix the findings (recommended) — address the vulnerabilities before merging
  2. Adjust the threshold — change fail-on to critical to only fail on critical issues
  3. Dismiss the finding if it's a false positive:
    nat findings dismiss --id FINDING_ID --reason false_positive
  4. Use continue-on-error temporarily while addressing findings:
    - uses: bg-playground/nat-action@v1
      continue-on-error: true
      with:
        api-url: ...

NAT_API_KEY secret not found

Symptom: Workflow fails with "API key is required" or authentication error.

Solutions:

  1. Verify the secret is set: Repository → SettingsSecrets and variablesActions
  2. Confirm the secret name matches exactly: NAT_API_KEY (case-sensitive)
  3. For organization-level secrets, ensure the secret is shared with the repository
  4. Check that the workflow has permission to access secrets (not blocked by environment protection rules)

Target API not reachable from CI runner

Symptom: Connection errors when the CI workflow tries to scan your staging API.

Common causes:

CauseSolution
Staging not deployed yetAdd a "wait for deployment" step before the scan
CI runner can't reach stagingUse a self-hosted runner on the same network as staging
Firewall blocks GitHub Actions IPsAllowlist GitHub Actions IP ranges (opens in a new tab)
Staging on private VPNAdd a VPN connection step to the workflow

Wait for staging to be ready:

- name: Wait for staging deployment
  run: |
    for i in $(seq 1 30); do
      if curl -sf ${{ vars.STAGING_API_URL }}/health; then
        echo "Staging is ready"
        exit 0
      fi
      echo "Waiting for staging... ($i/30)"
      sleep 10
    done
    echo "Staging didn't become ready in time"
    exit 1

Scan times out in CI

Symptom: The scan is killed by the CI runner due to exceeding the job timeout.

Solutions:

  1. Increase the GitHub Actions timeout-minutes:
    jobs:
      nat-scan:
        timeout-minutes: 60
  2. Reduce scan scope:
    - uses: bg-playground/nat-action@v1
      with:
        exclude: "/api/v1/reports/*,/api/v1/exports/*"
        max-requests: "1000"
  3. Reduce concurrency and timeout to prevent queuing:
    concurrency: "2"
    timeout: "15"

SARIF upload fails

Symptom: The github/codeql-action/upload-sarif step fails after the scan.

Solutions:

  1. Ensure the job has security-events: write permission:
    permissions:
      security-events: write
      contents: read
  2. Use if: always() so the upload runs even when the scan step fails:
    - uses: github/codeql-action/upload-sarif@v3
      if: always()
      with:
        sarif_file: nat-results.sarif
  3. Ensure the SARIF file was created — if the scan errored before creating it, the upload will fail:
    - uses: bg-playground/nat-action@v1
      id: nat
      continue-on-error: true
     
    - uses: github/codeql-action/upload-sarif@v3
      if: always() && hashFiles('nat-results.sarif') != ''
      with:
        sarif_file: nat-results.sarif

Workflow runs on every commit but is slow

Symptom: The scan workflow adds significant time to every PR.

Solutions:

  1. Only run on pushes to main and PRs to main (not on every branch push):
    on:
      pull_request:
        branches: [main]
      push:
        branches: [main]
  2. Cache the pip installation:
    - uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: nat-${{ runner.os }}-pip
  3. Run the scan as a separate non-blocking job:
    jobs:
      tests:
        ...
      nat-scan:
        needs: []    # run in parallel with tests, not after
        continue-on-error: true

Secrets not available in pull requests from forks

Symptom: Scans work on direct pushes but fail on PRs from forked repositories.

GitHub does not pass secrets to workflows triggered by pull requests from forks, for security reasons.

Solutions:

  1. Use the pull_request_target event (with caution — review security implications)
  2. Require collaborators to be added before their PRs are scanned
  3. Run the scan only on push to protected branches, not on pull_request

Next steps