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
- 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).
- 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.
- 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. - Das Ende. Am Ablaufdatum wird der Befund wieder geöffnet, und die
Ausnahme wird als
expiredmarkiert.
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öser | Grund des Widerrufs |
|---|---|
| Jemand sie von Hand widerruft | manual |
| Der Schweregrad des Befunds über den genehmigten steigt | severity_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ässt | approver_left |
| Die Ausnahme auf dem Urteil nicht erreichbar beruhte und ein späterer Scan den Befund als erreichbar einstuft oder nicht entscheiden kann | reachability_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 Pfad | Scope | Was es tut |
|---|---|---|
GET /orgs/{org}/exceptions | findings:read | Jede 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}/exceptions | findings:write | Eine 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:read | Eine Ausnahme, genehmigt oder nicht. |
POST /orgs/{org}/exceptions/{id}/approve | findings:write | Genehmigen, optional mit {"comment": "..."}. |
POST /orgs/{org}/exceptions/{id}/reject | findings:write | Ablehnen, optional mit einem Kommentar. |
POST /orgs/{org}/exceptions/{id}/revoke | findings:write | Einen Antrag zurückziehen oder eine Ausnahme widerrufen. Eine für ein ganzes Repository oder Image braucht policy:write. |
GET, PUT /orgs/{org}/exceptions/settings | policy:read, policy:write | max_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:
| Art | scope | id | Was sie abdeckt |
|---|---|---|---|
| Verwerfung | finding | dismissal.<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 Repository | repo | repo.<uuid> | Eine Advisory in einem Paket und Manifest, in jedem späteren Scan des Repositorys. |
| Verwerfung für das ganze Image | image | image.<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.