GitHub Actions

Add one step to your workflow and every pull request gets a compliance scan. Findings upload to GitHub Code Scanning as SARIF and annotate the exact lines, offline, no API key, and your code never leaves the runner.

01 · Setup

3 steps.

01Add the workflow

Create .github/workflows/compliance.yml. The scan runs on every pull request and uploads SARIF to Code Scanning.

name: Compliance
on: [pull_request]
permissions:
  contents: read
  security-events: write   # required to upload SARIF
jobs:
  scrutora-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - id: scan
        uses: Scrutora/scrutora-scan@v1
        with:
          frameworks: dpdpa,hipaa
          fail-on: high        # none|low|medium|high|critical
      - if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: ${{ steps.scan.outputs.sarif-file }}
02Open a pull request

The scan runs automatically. Findings show in Security → Code scanning with the file, line, severity and the compliance obligation each maps to. With fail-on set, the check blocks the merge on findings at or above that severity.

03Optional: keep the results in Scrutora

By default nothing leaves your runner, which is why the scan above needs no account and no key. Add --upload and the scan posts its RESULTS to your Scrutora account when it finishes: the findings, the data map, the RoPA entries and the dependency inventory travel, your source never does. Paid plans only; the scan itself stays free forever. Store the key as a secret (GitHub: Actions secret, GitLab: masked CI variable, Bitbucket: repository variable, CircleCI: context, Azure: pipeline secret, Cloud Build: Secret Manager) and expose it as SCRUTORA_API_KEY so it never reaches your build log. Repository, commit, branch and PR number are read from the CI environment, and the scan is filed under a project named after the repository unless you pass --project. Re-running the same commit returns the scan already stored rather than adding a second one, so a retried pipeline does not distort the trend line. If the upload fails, the build result is unchanged: the scan already gave its verdict, and the step logs a warning rather than failing the job. On GitHub Actions you can set upload: true on the action itself instead of running the container by hand, and read the resulting scan id from the scan-id output.

docker run --rm -v "$PWD:/src" -w /src \
  -e SCRUTORA_API_KEY \
  ghcr.io/nirvahana/dpdp-scan@sha256:71e306bdab91587e01ed6b83a1d2c3baecf4c55ecf880b440a5ab76fe85eb461 \
  scan . --no-ai \
    --frameworks dpdpa,hipaa \
    --json-output scrutora.json \
    --output scrutora-report.pdf \
    --upload

# SCRUTORA_API_KEY is read from the environment, never passed on the command
# line, so it stays out of your build log. Add --project "my-service" to file
# the scan somewhere other than a project named after the repository.

# ── GitHub Actions: use the action's own inputs instead ─────────────────────
#   - id: scan
#     uses: scrutora/scrutora-scan@v1
#     with:
#       upload: true
#       api-key: ${{ secrets.SCRUTORA_API_KEY }}
#   - run: echo "Synced as ${{ steps.scan.outputs.scan-id }}"
02 · What you get

After the first run.

Code Scanning alerts

Each finding as an alert with remediation and the obligation it cites (e.g. DPDPA §8(5)).

PR line annotations

Reviewers see the finding inline on the exact changed line.

Merge gating

fail-on blocks a PR on high/critical findings, or run report-only.

Zero data egress

Runs entirely on the GitHub runner; no code, findings or telemetry leave.

03 · Questions

The ones people actually ask.

Does it work on private repositories?

The Code Scanning tab requires GitHub Advanced Security on private repos. Without GHAS the scan still runs and fail-on still gates the build, read the summary in the Actions log.

Do I need an API key or account?

No. The Action runs the scanner container offline on your runner. Nothing is uploaded and no key is required.

Which frameworks can I scan for?

DPDPA, HIPAA, GDPR, PCI-DSS, RBI and more, set the frameworks input to a comma-separated list.

View on GitHub