{"inputSchema":{"type":"object","required":["provider","body","secret"],"additionalProperties":false,"properties":{"provider":{"type":"string","enum":["github","stripe","shopify","slack","svix","generic_hmac"],"description":"Which provider signed the request."},"body":{"type":"string","maxLength":200000,"description":"The raw request body exactly as received, not re-serialised."},"secret":{"type":"string","minLength":1,"maxLength":2000,"description":"The signing secret."},"signature":{"type":"string","maxLength":2000,"description":"The signature header value. Required unless headers is given."},"headers":{"type":"object","description":"All request headers; the right one is picked by provider."},"timestamp":{"type":"string","maxLength":40,"description":"Timestamp, if the provider signs one and it is not in the headers."},"message_id":{"type":"string","maxLength":200,"description":"Message id for schemes that sign one, e.g. Svix."},"tolerance_seconds":{"type":"integer","minimum":1,"maximum":86400,"default":300,"description":"How old a signed timestamp may be."}}},"requestExample":{"provider":"github","body":"{\"synthetic\":true,\"event\":\"documentation-example\"}","secret":"HALOWERK-public-synthetic-example-never-use-for-authentication","signature":"sha256=fdfaa7380ce9e369a7d90e8651603bb777a4f008dd3070b056d2b59122d602f8"},"price_usdc":"0.002","example_request":{"provider":"github","body":"{\"synthetic\":true,\"event\":\"documentation-example\"}","secret":"HALOWERK-public-synthetic-example-never-use-for-authentication","signature":"sha256=fdfaa7380ce9e369a7d90e8651603bb777a4f008dd3070b056d2b59122d602f8"},"serviceName":"HALOWERK sicherwerk","tags":["security","webhook","hmac","signature"],"outputSchema":{"type":"object"},"outputExample":{"provider":"github","valid":true,"signature_matches":true,"timestamp_valid":null,"timestamp_age_seconds":null,"tolerance_seconds":300,"algorithm":"sha256","encoding":"hex","expected_signature":"sha256=fdfaa7380ce9e369a7d90e8651603bb777a4f008dd3070b056d2b59122d602f8","signed_string_preview":"{\"synthetic\":true,\"event\":\"documentation-example\"}","signed_string_length":50,"signature_candidates_tried":1,"findings":[{"severity":"info","code":"no_timestamp_signed","message":"github signiert keinen Zeitstempel. Gegen Wiederholung hilft nur, die Zustellungskennung selbst zu entwerten."}],"verdict":"valid","provider_note":"GitHub signiert nur den Rumpf. Ein Wiederholungsangriff ist damit nicht ausgeschlossen — die Zustellungs-ID muss selbst entwertet werden.","checked_at":"2026-10-22T23:41:36.996Z","limits":"Geprueft wird nur, ob die Signatur zum Rumpf und zum Geheimnis passt. Ob der Absender berechtigt ist, ob die Zustellung schon verarbeitet wurde und ob der Inhalt stimmt, steht hier nicht. Wiederholungsschutz braucht immer eine eigene Entwertung der Zustellungskennung — eine gueltige Signatur allein leistet das nicht."}}