Platform-native vs third-party scanner integration
Both GitHub and GitLab offer built-in security scanning, but they differ significantly in what is included at which tier and how results surface in the developer workflow.
- GitHub: Code Scanning (CodeQL + SARIF), Dependabot, and Secret Scanning are available on public repos for free. Private repos require GitHub Advanced Security (GHAS), which is bundled with GitHub Enterprise.
- GitLab: SAST, DAST, SCA, Container Scanning, and Secret Detection are built-in features. Basic tiers get report artefacts; blocking MR gates require GitLab Ultimate.
- Third-party scanners (Semgrep, Snyk, AquilaX, Trivy) integrate with both platforms via SARIF uploads, status checks, or platform-specific integrations. These are often preferable for custom rules, multi-language coverage, and cross-platform consistency.
SARIF is the integration standard: The Static Analysis Results Interchange Format (SARIF) is a JSON schema supported by both GitHub and GitLab for uploading findings from external scanners. Any scanner that outputs SARIF can integrate with both platforms without custom glue code.
GitHub: complete security pipeline
A complete GitHub security pipeline covering SAST, SCA, secrets, and IaC in a single workflow file:
name: Security Scan on: push: { branches: [main, develop] } pull_request: jobs: sast: runs-on: ubuntu-latest container: { image: semgrep/semgrep } steps: - uses: actions/checkout@v4 - run: semgrep scan --config=auto --sarif --output=sast.sarif . - uses: github/codeql-action/upload-sarif@v3 if: always() with: { sarif_file: sast.sarif } secrets: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } # full history for secret scan - run: | pip install trufflehog3 trufflehog3 --format json --output secrets.json . sca: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: | curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin grype dir:. --fail-on critical --output sarif > sca.sarif - uses: github/codeql-action/upload-sarif@v3 if: always() with: { sarif_file: sca.sarif } iac: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: aquasecurity/trivy-action@master with: scan-type: config format: sarif output: iac.sarif - uses: github/codeql-action/upload-sarif@v3 if: always() with: { sarif_file: iac.sarif }
GitHub Code Scanning and SARIF results
Once SARIF is uploaded, findings appear in the Security β Code scanning alerts tab and as inline annotations on pull request diff views. This is the most developer-friendly surface: reviewers see security findings alongside the code change that introduced them.
Branch protection rules: SARIF uploads alone do not block merges. To block PRs with findings, add a required status check in branch protection settings. The SAST job must exit with a non-zero code on findings, not just upload the SARIF artefact.
GitLab: security templates and built-in scanning
GitLab's security templates are the fastest path to full pipeline coverage:
include: - template: Security/SAST.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Container-Scanning.gitlab-ci.yml - template: Security/DAST.gitlab-ci.yml variables: SAST_EXCLUDED_PATHS: spec,test,tmp SECRET_DETECTION_HISTORIC_SCAN: "true" DS_EXCLUDED_ANALYZERS: "" # Custom AquilaX scan job aquilax-scan: image: aquilax/scanner:latest script: - aquilax scan --output gl-sast-report.json --format gitlab-sast artifacts: reports: sast: gl-sast-report.json
GitLab MR security widget
When jobs emit artefacts with the correct reports: keys, GitLab automatically aggregates findings and displays them in the Merge Request security widget. This shows:
- New findings introduced by this MR (not present on the target branch)
- Fixed findings (present on the target branch but resolved in this MR)
- Severity breakdown and links to individual finding details
On GitLab Ultimate, you can configure Security Approvals to require a security team member to approve any MR that introduces new critical or high findings β before it can merge.
Building security gates that actually block
A security gate is a pipeline job that exits non-zero when findings exceed a policy threshold, causing the CI system to mark the build as failed and block the merge. The key is configuring the right exit conditions:
- Block on CRITICAL: No exceptions, fix required before merge
- Warn on HIGH: Opens a ticket, does not block (initially β raise to block after backlog is cleared)
- Secrets found: Always block, regardless of severity. A secret is a secret.
The gradual rollout strategy: Enable all scanners in report-only mode for two weeks. Triage findings, fix the genuine ones, suppress the false positives. Then flip the gate to blocking mode with confidence. This avoids the "day one chaos" of discovering 1,000 pre-existing findings when you enable blocking.
AquilaX: one integration for both platforms
AquilaX provides native integrations for both GitHub and GitLab, with a single CLI that outputs SARIF (for GitHub) or the GitLab security report JSON format. This means consistent rules, thresholds, and suppressions across both platforms β critical for organisations that use both.
# GitHub Actions: output SARIF for Code Scanning upload aquilax scan --format sarif --output aquilax.sarif . # GitLab CI: output GitLab SAST report format aquilax scan --format gitlab-sast --output gl-sast-report.json .
One scanner, both platforms
AquilaX integrates natively with GitHub and GitLab β SARIF uploads, MR comments, security gates, and a central dashboard across all your repositories.
See all integrations β