Zum Hauptinhalt springen

Ausnahmen

Eine Ausnahme akzeptiert ein Risiko für eine begrenzte Zeit: eine Schwachstelle, die du noch nicht beheben kannst, einen Lizenzbefund bei einem internen Werkzeug, ein Secret in einem Test-Fixture. Sie funktioniert für jede Art von Befund gleich (Abhängigkeiten, Container-Images, SAST, Lizenzen, Secrets, Malware in Abhängigkeiten, Registry-Pakete) und ebenso für Ausnahmen von der Paketrichtlinie.

Eine Ausnahme wird erst wirksam, wenn eine zweite Person sie genehmigt. Bis dahin bleibt der Befund offen, und die Richtlinie gilt weiter.

Eine Verwerfung ist eine Ausnahme, die keine Genehmigung brauchte. Verwerfungen, auch solche für ein ganzes Repository oder ein ganzes Image, werden an derselben Stelle und über dieselbe API aufgelistet, gelesen und widerrufen wie genehmigte Ausnahmen; siehe Ausnahmen ohne Genehmigung.

Wie eine Ausnahme funktioniert

  1. Beantragen. Jede Person, die mit Befunden arbeiten darf, beantragt eine, mit einer Begründung und einem Ablaufdatum. Das Datum darf höchstens so weit in der Zukunft liegen, wie die Obergrenze deiner Organisation erlaubt (366 Tage, sofern du keine niedrigere festlegst).
  2. Genehmigen oder ablehnen. Eine genehmigende Person, die nicht die antragstellende Person ist, entscheidet, optional mit einem Kommentar. Die genehmigenden Personen erhalten bei einem neuen Antrag eine E-Mail in ihrer eigenen Sprache.
  3. In Kraft. Der Befund ist bis zum Ablaufdatum verworfen. Der Befund hält fest, wer die Ausnahme beantragt (dismissed_by) und wer sie genehmigt hat (dismissal_approved_by). Ein erneuter Scan behält die Verwerfung bei.
  4. Das Ende. Am Ablaufdatum wird der Befund wieder geöffnet, und die Ausnahme wird als expired markiert.

Die Zustände sind requested, approved, rejected, expired und revoked.

Wer genehmigen darf

  • Standardmäßig: die Owner der Organisation und die Personen auf der Genehmigungsliste der Paketrichtlinie.
  • Oder, wenn du in den Einstellungen ein Genehmigungs-Team benennst: nur die Mitglieder dieses Teams.

Niemand kann den eigenen Antrag genehmigen: Die Konsole zeigt dafür keine Schaltfläche Freigeben, und die API antwortet mit self-approve. Ein Token, hinter dem keine Person steht, und die Zugangsdaten eines KI-Agenten können über eine Ausnahme gar nicht entscheiden (user-identity-required).

Automatischer Widerruf

Eine genehmigte Ausnahme wird widerrufen und ihr Befund sofort wieder geöffnet, wenn:

AuslöserGrund des Widerrufs
Jemand sie von Hand widerruftmanual
Der Schweregrad des Befunds über den genehmigten steigtseverity_raised
Eine neue Schwachstelle in derselben Komponente auftaucht (dasselbe Paket in derselben Version, oder dasselbe Image-Paket)new_vulnerability
Die genehmigende Person die Organisation verlässtapprover_left
Die Ausnahme auf dem Urteil nicht erreichbar beruhte und ein späterer Scan den Befund als erreichbar einstuft oder nicht entscheiden kannreachability_changed

Auf das Ausscheiden der genehmigenden Person wird reagiert, sobald sich die Mitgliedschaft ändert; die übrigen Prüfungen laufen stündlich. reachability_changed widerruft auch eine einfache Verwerfung, die auf dem Urteil „kein Aufrufpfad" beruhte; siehe Erreichbarkeit.

Audit und SIEM

Jeder Schritt ist ein Audit-Ereignis des Mandanten: code-security.exception.requested, .approved, .rejected, .revoked und .expired für Befunde, und package_policy.exception.* für Paketrichtlinien. Ein Widerrufsereignis enthält seinen Grund und was sich geändert hat. Wie jedes Audit-Ereignis erreichen sie deine SIEM-Endpunkte; filtere auf das Aktionspräfix code-security.exception., um nur diese zu erhalten.

In der Konsole

Öffne Sicherheit › Befunde › Ausnahmen. Die Seite enthält:

  • Wartet auf Genehmigung: die offenen Anträge, jeweils mit Freigeben und Ablehnen und einem Kommentarfeld. Bei deinen eigenen Anträgen fehlt Freigeben.
  • In Kraft: genehmigte Ausnahmen, mit Widerrufen.
  • Ohne Genehmigung akzeptiert: Verwerfungen, einschließlich solcher für ein ganzes Repository oder Image, mit einem Typfilter und Widerrufen. Siehe Ausnahmen ohne Genehmigung.
  • Verlauf: abgelehnte, widerrufene und abgelaufene Ausnahmen, mit der entscheidenden Person, dem Kommentar und bei einem Widerruf dem Grund.
  • Ausnahme für einen Befund beantragen: Auf der Seite jedes Befunds enthält das Formular zum Verwerfen einen Link Ausnahme beantragen, der das für dich ausfüllt.
  • Einstellungen: die längste erlaubte Laufzeit einer Ausnahme, das Genehmigungs-Team und Verwerfungen erfordern eine Genehmigung.

API

Basis-URL https://frem.sh/_app/api/v1. Die vollständigen Strukturen stehen in der API-Referenz.

Methode und PfadScopeWas es tut
GET /orgs/{org}/exceptionsfindings:readJede von einer zweiten Person genehmigte Ausnahme, neueste zuerst. Filtere mit status (kommagetrennt), kind (finding oder package) und scanner. Füge approval=none für Ausnahmen ohne Genehmigung hinzu, oder approval=all für beide.
POST /orgs/{org}/exceptionsfindings:writeEine beantragen. Für einen Befund: scanner, finding_id, justification, expires_at. Für eine Paketrichtlinie: "kind": "package" und die Felder einer Ausnahme von der Paketrichtlinie.
GET /orgs/{org}/exceptions/{id}findings:readEine Ausnahme, genehmigt oder nicht.
POST /orgs/{org}/exceptions/{id}/approvefindings:writeGenehmigen, optional mit {"comment": "..."}.
POST /orgs/{org}/exceptions/{id}/rejectfindings:writeAblehnen, optional mit einem Kommentar.
POST /orgs/{org}/exceptions/{id}/revokefindings:writeEinen Antrag zurückziehen oder eine Ausnahme widerrufen. Eine für ein ganzes Repository oder Image braucht policy:write.
GET, PUT /orgs/{org}/exceptions/settingspolicy:read, policy:writemax_days (1 bis 366), approver_team (ein Teamname, oder null für die Owner plus die Genehmigungsliste) und dismissals_require_approval (true oder false).

scanner ist einer von deps, images, sast, licenses, secrets, package_malware und packages; finding_id ist die id, die die Befund-Endpunkte zurückgeben. expires_at ist ein Datum (YYYY-MM-DD, bis einschließlich dieses Tages in UTC) oder eine Zeit nach ISO 8601. Ein zweiter Antrag für einen Befund, der bereits eine offene oder genehmigte Ausnahme hat, wird mit 409 duplicate-pending beantwortet.

Eine Ausnahme für einen Abhängigkeitsbefund beantragen:

curl -sS -X POST https://frem.sh/_app/api/v1/orgs/acme/exceptions \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
  -d '{"scanner":"deps","finding_id":"<id>","justification":"Not reachable from user input; fixed by the framework upgrade.","expires_at":"2026-12-31"}'

Eine Lizenzausnahme für die Paketrichtlinie:

curl -sS -X POST https://frem.sh/_app/api/v1/orgs/acme/exceptions \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
  -d '{"kind":"package","scope":"package","rule_kind":"licence","rule_selector":"GPL-3.0-only","pkg_type":"npm","name":"left-pad","justification":"Internal tool, never distributed.","expires_at":"2026-12-31"}'

Einstellungen als Code

PUT /orgs/{org}/exceptions/settings ist ein einfacher idempotenter Schreibvorgang, sodass die Obergrenze und das Genehmigungs-Team in deinem Konfigurations-Repository neben den übrigen Einstellungen deiner Organisation liegen können:

curl -sS -X PUT https://frem.sh/_app/api/v1/orgs/acme/exceptions/settings \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
  -d '{"max_days": 90, "approver_team": "security"}'

Ausnahmen ohne Genehmigung

Die Schaltfläche Verwerfen an einem Befund ist der Weg, ihn mit einer einzigen Person zu akzeptieren. Sie hält fest, wer verworfen hat und warum, und kann ein Ablaufdatum tragen. Es gibt keine zweite Person, also ist es eine Ausnahme ohne Genehmigung. Nutze eine genehmigte Ausnahme, wenn du das Vier-Augen-Prinzip brauchst, oder schalte Verwerfungen erfordern eine Genehmigung ein, damit jede Verwerfung durch jemanden, der nicht genehmigen darf, durch eine Genehmigung gehen muss.

Es gibt drei Arten, jeweils in der Konsole unter Ohne Genehmigung akzeptiert und über GET /orgs/{org}/exceptions?approval=none aufgelistet:

ArtscopeidWas sie abdeckt
Verwerfungfindingdismissal.<scanner>.<hash>Einen Befund. Die id bleibt über erneute Scans hinweg gleich. findings_count gibt an, wie viele Scanergebnisse sie gerade abdeckt, zum Beispiel denselben Befund in mehreren Pull Requests.
Verwerfung einer Abhängigkeit für das ganze Repositoryreporepo.<uuid>Eine Advisory in einem Paket und Manifest, in jedem späteren Scan des Repositorys.
Verwerfung für das ganze Imageimageimage.<uuid>Einen Befund in einem Container-Image, in jedem späteren Scan des Images.

Jeder Eintrag hat "approval": "none", "status": "approved" (in Kraft) und dieselben Felder wie jede Ausnahme: justification ist der Grund der Verwerfung, requested_by die Person, die verworfen hat, und expires_at ihr Ablaufdatum oder null. Mit approval=all tragen genehmigte Ausnahmen "approval": "required". Ohne den Parameter approval ist die Liste genau so wie vorher.

Eine abgelaufene Verwerfung wird nicht aufgeführt: Der tägliche Ablaufjob öffnet ihre Befunde wieder. Ebenfalls nicht aufgeführt: Befunde, die eine genehmigte Ausnahme verworfen hat (die Ausnahme ist der Eintrag), Befunde, die von selbst verschwunden sind, und Lizenzbefunde, die deine Lizenz-Zulassungsliste verwirft, denn die werden über diese Liste gesteuert.

Widerrufen öffnet die Befunde sofort wieder, und ein hoher oder kritischer Befund löst erneut eine Warnung aus. Der Widerruf einer Verwerfung für ein ganzes Repository oder Image löscht auch die Entscheidung, sodass spätere Scans sie nicht mehr übernehmen; dafür ist policy:write nötig, wie bei DELETE /orgs/{org}/code-security/deps/repo-dismissals/{id}. Jeder Widerruf wird im Audit-Log erfasst: code-security.<scanner>.dismissal_revoked, oder code-security.deps.repo_dismissal_revoked und code-security.images.repo_dismissal_revoked.

curl -sS "https://frem.sh/_app/api/v1/orgs/acme/exceptions?approval=none&scanner=deps" \
  -H "Authorization: Bearer $FREMFORGE_TOKEN"

curl -sS -X POST "https://frem.sh/_app/api/v1/orgs/acme/exceptions/dismissal.deps.3f1c0a9e5b7d2c4e6f8a0b1c/revoke" \
  -H "Authorization: Bearer $FREMFORGE_TOKEN"

Verwerfungen erfordern eine Genehmigung

Eine Einstellung pro Organisation, standardmäßig aus. Ist sie eingeschaltet, verwirft die Verwerfung eines Abhängigkeits-, SAST-, Secret-, Container-Image-, Lizenz- oder Abhängigkeits-Malware-Befunds durch jemanden, der nicht genehmigen darf, nichts. Stattdessen:

  • erhält jeder offene Befund einen Ausnahmeantrag, mit dem Grund der Verwerfung als Begründung und ihrem Ablaufdatum (der Obergrenze deiner Organisation, wenn die Verwerfung keines hatte);
  • bleibt der Befund offen, und die genehmigenden Personen erhalten eine E-Mail;
  • genehmigt oder lehnt eine genehmigende Person, die nicht selbst verworfen hat, ihn in der Warteschlange ab. Eine Genehmigung verwirft den Befund mit beiden Namen, genau wie jede andere Ausnahme. Niemand kann die eigene Verwerfung genehmigen.

Eine Verwerfung auf einem geschützten Release-Branch ist eine Ausnahme mit der id branch.<finding id> und dem Scope branch. Sie läuft noch nicht über diese Warteschlange: Solange diese Einstellung eingeschaltet ist, darf nur eine genehmigende Person auf einem Release-Branch verwerfen, und alle anderen erhalten 403 approval-required.

Genehmigende Personen verwerfen weiterhin direkt. In der Konsole führt dich eine Verwerfung, die zur Genehmigung ging, mit einem Hinweis zur Warteschlange der Ausnahmen. Über die API antwortet dann jeder Endpunkt zum Verwerfen und Sammel-Verwerfen mit 202 statt 200:

{
  "dismissed": false,
  "status": "pending_approval",
  "pending_count": 1,
  "exceptions": [
    { "id": "<exception id>", "finding_id": "<finding id>", "status": "pending_approval", "expires_at": "2027-10-11T15:00:00.000Z" }
  ],
  "skipped": []
}

skipped listet Befunde auf, die nicht in die Warteschlange kamen: not-found (nicht offen oder nicht deine) oder duplicate-pending (es gibt bereits eine offene oder genehmigte Ausnahme). Die Verwerfung eines einzelnen Befunds antwortet in diesen Fällen stattdessen mit 404 oder 409 duplicate-pending. Ein Ablaufdatum jenseits deiner Obergrenze wird mit 400 invalid-expires-at abgewiesen.

Ein Malware-Befund zu einer hochgeladenen Datei (Sicherheit › Befunde › Malware-Scan von Uploads) hat keinen Grund und kein Ablaufdatum, die durch die Warteschlange gehen könnten. Solange die Einstellung eingeschaltet ist, darf nur eine genehmigende Person einen solchen verwerfen; alle anderen erhalten 403 not-an-approver.

Schalte sie unter Sicherheit › Befunde › Ausnahmen › Einstellungen ein, über die API:

curl -sS -X PUT https://frem.sh/_app/api/v1/orgs/acme/exceptions/settings \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
  -d '{"dismissals_require_approval": true}'

oder mit exception_settings im Terraform-Modul. Das Ein- oder Ausschalten schreibt die Audit-Ereignisse exceptions.dismissal_approval.enabled und .disabled. Ein Antrag, der aus einer Verwerfung entsteht, ist das gewöhnliche Ereignis code-security.exception.requested mit "via": "dismissal". Bereits wartende Anträge bleiben beim Ausschalten in der Warteschlange und können weiterhin genehmigt werden.