Dokumente/API & Webhooks/SARIF-Integration

SARIF-Integration

Pushen Sie den SARIF-Output eines beliebigen Code-Scanning-Tools (CodeQL, Semgrep, Snyk, Checkmarx, Trivy, Bandit, GitLab SAST, OWASP ZAP) an SecureCodingHub. Jede einzigartige CWE im Lauf wird zu einer Zuweisung auf dem Konto des Commit-Autors — meist innerhalb von Sekunden nach dem Merge.

Warum CI der richtige Auslöser ist

Generische "jeder Entwickler nimmt denselben OWASP Top 10-Kurs"-Rollouts haben niedrige Abschlussquoten und noch niedrigere Bindung. Die CI-Integration dreht das Modell um: Schulung wird speziell dem Entwickler zugewiesen, der ein Problem eingeführt hat, speziell zu der Schwachstellenklasse, die er benötigt, mit einer Frist von 14 Tagen gebunden an den Merge, der sie aufgedeckt hat. Das nennen Auditoren Just-in-Time Secure-Coding-Schulung.

Wie es Ende-zu-Ende funktioniert

1

Ihr SAST-Tool erzeugt eine SARIF 2.1.0-Datei als Teil eines CI-Jobs.

2

Ein CI-Schritt POSTet die Datei an /api/public/v1/sarif mit Commit-Metadaten als Anfrage-Header.

3

SecureCodingHub parst jedes result, extrahiert seine CWE-Tags und schlägt jeden in unserer internen CWE-zu-Topic-Zuordnung nach.

4

Für jedes einzigartige zugeordnete Topic wird eine Zuweisung für den Benutzer erstellt, dessen E-Mail mit X-Commit-Author-Email übereinstimmt, mit einer Frist von 14 Tagen.

5

Ein sarif.ingested-Webhook wird ausgelöst mit derselben Payload, die die synchrone Antwort zurückgibt.

Der Endpunkt

POST /api/public/v1/sarif
Authorization: Bearer scs_live_…
Content-Type: application/json
X-Source: github-codeql
X-Repo: acme/payments-api
X-Branch: main
X-Commit-Sha: 9c2f4b8e0c1d…
X-Commit-Author-Email: jane.smith@acme.com

<SARIF 2.1.0 JSON body, up to 10 MB>

Erforderlicher Geltungsbereich: sarif:ingest.

Anfrage-Header

HeaderErforderlichBedeutung
X-SourceFreiformat-Tool-Kennzeichner — z.B. github-codeql, snyk, semgrep-ci. Wird für Audit aufgezeichnet.
X-RepoRepository-Slug (owner/name). Wird für Audit aufgezeichnet.
X-BranchBranch-Name. Wird für Audit aufgezeichnet.
X-Commit-ShaempfohlenCommit-Hash. Wird zusammen mit X-Repo für 24-Stunden-Idempotenz verwendet.
X-Commit-Author-EmailempfohlenE-Mail des Commit-Autors. Wird zu einem SecureCodingHub-Benutzer aufgelöst; Zuweisungen werden ihm angehängt. Wenn die E-Mail mit keinem Benutzer übereinstimmt, wird der Lauf trotzdem aufgenommen, aber keine Zuweisungen erstellt.

Antwort

{
  "ingestionId": "7e4c9d09-86ca-4125-bbd8-7fae54c8f654",
  "findingsCount": 2,
  "uniqueCwes": ["CWE-79", "CWE-89"],
  "unmappedCwes": [],
  "assignmentsCreated": 12,
  "notes": []
}
  • findingsCount — Gesamtanzahl der geparsten result-Einträge.
  • uniqueCwes — Menge der CWEs, die über alle Befunde hinweg erwähnt werden.
  • unmappedCwes — CWEs, die wir keinem Topic zuordnen konnten. Senden Sie sie an Support, wenn Sie Abdeckung hinzugefügt haben möchten.
  • assignmentsCreated — Anzahl neuer Zuweisungsdatensätze (bestehende Duplikate werden übersprungen).
  • notes — nicht-fatale Warnungen (z.B. ungültiges Format der Commit-Autor-E-Mail).

Idempotenz

Das erneute Aufnehmen derselben SARIF-Datei ist sicher. Das Tupel (organization, repo, commit_sha) ist der Idempotenzschlüssel — ein Duplikat innerhalb eines 24-Stunden-Fensters gibt 200 mit der ursprünglichen ingestionId und assignmentsCreated: 0 zurück. Das bedeutet, dass CI-Workflows, die auf demselben Commit erneut laufen (Rebase, manueller Rerun, Push zu PR), keine doppelten Zuweisungen anhäufen.

GitHub Actions-Beispiel

Fügen Sie diesen Schritt in einen Workflow ein, nachdem Ihr CodeQL- oder Semgrep-Job results.sarif erzeugt hat:

- name: Send SARIF to SecureCodingHub
  if: always()
  run: |
    curl -sS -f -X POST \
      -H "Authorization: Bearer $SCH_API_KEY" \
      -H "Content-Type: application/json" \
      -H "X-Source: github-codeql" \
      -H "X-Repo: ${{ github.repository }}" \
      -H "X-Branch: ${{ github.ref_name }}" \
      -H "X-Commit-Sha: ${{ github.sha }}" \
      -H "X-Commit-Author-Email: ${{ github.event.head_commit.author.email }}" \
      --data-binary @results.sarif \
      https://api.limeplate.com/api/public/v1/sarif
  env:
    SCH_API_KEY: ${{ secrets.SCH_API_KEY }}

Speichern Sie den Schlüssel in Repository- oder Organisations-Secrets. Die if: always()-Schutzbedingung stellt sicher, dass Befunde auch dann gesendet werden, wenn der Security-Job den Build als fehlgeschlagen markiert hat — was genau der Zeitpunkt ist, an dem Sie am meisten möchten, dass Schulungszuweisungen ausgelöst werden.

GitLab CI-Beispiel

send_sarif_to_sch:
  stage: post-security
  image: curlimages/curl:latest
  needs: ["sast"]
  script:
    - >
      curl -sS -f -X POST
      -H "Authorization: Bearer $SCH_API_KEY"
      -H "Content-Type: application/json"
      -H "X-Source: gitlab-sast"
      -H "X-Repo: $CI_PROJECT_PATH"
      -H "X-Branch: $CI_COMMIT_BRANCH"
      -H "X-Commit-Sha: $CI_COMMIT_SHA"
      -H "X-Commit-Author-Email: $GITLAB_USER_EMAIL"
      --data-binary @gl-sast-report.json
      https://api.limeplate.com/api/public/v1/sarif
  rules:
    - if: $CI_COMMIT_BRANCH

Der GitLab SAST-Bericht ist SARIF-kompatibel — keine Konvertierung nötig.

Semgrep-Beispiel

semgrep ci --sarif --output results.sarif
curl -sS -f -X POST \
  -H "Authorization: Bearer $SCH_API_KEY" \
  -H "X-Source: semgrep" \
  -H "X-Repo: $REPO" \
  -H "X-Commit-Sha: $COMMIT" \
  -H "X-Commit-Author-Email: $AUTHOR_EMAIL" \
  --data-binary @results.sarif \
  https://api.limeplate.com/api/public/v1/sarif

CWE-Abdeckung

SecureCodingHub ordnet derzeit die OWASP Top 10, OWASP API Security Top 10, OWASP Mobile Top 10 und die CWE Top 25 Schulungs-Topics zu. Befunde, die mit CWE-IDs außerhalb dieser Menge getaggt sind, erscheinen in der unmappedCwes-Liste der Antwort. Häufige Formate, die wir auf der SARIF-Tag-Seite akzeptieren:

  • external/cwe/cwe-89 (CodeQL-Standard)
  • cwe-89
  • CWE-89
  • cwe:89

Die Tags werden sowohl aus result.properties.tags als auch aus dem entsprechenden tool.driver.rules[].properties.tags gelesen.

Größenbeschränkung des Anfragetexts

Der SARIF-Endpunkt akzeptiert Payloads bis zu 10 MB unkomprimiert. Die meisten realen SAST-Berichte für ein einzelnes Repository liegen deutlich unter dieser Grenze. Wenn Sie einen unternehmensweiten Monorepo-Bericht haben, der das Limit überschreitet, teilen Sie ihn nach Tool-Treiber auf (ein SARIF-Lauf pro Treiber) und POSTen Sie jedes Teil — sie sind unter derselben Commit-SHA idempotent.

Fehlermodi

SymptomWahrscheinliche Ursache
200 mit assignmentsCreated: 0Die E-Mail des Commit-Autors ist kein Benutzer in Ihrer Organisation, oder alle CWEs waren bereits zugewiesen.
200 mit unmappedCwes nicht leerBefunde verweisen auf CWEs, für die es noch kein Schulungs-Topic gibt. Leiten Sie die Liste an den Support weiter.
400 empty_bodyCurl fehlte --data-binary @file.sarif.
413 body_too_largeSARIF überschreitet 10 MB. Nach Treiber aufteilen.
200 mit einem notes-Eintrag, der mit idempotency: beginntDasselbe (repo, commit) wurde bereits innerhalb von 24 Std. aufgenommen. Die Antwort ist ansonsten identisch mit einer frischen Aufnahme mit assignmentsCreated: 0 — sicher zu ignorieren.