Skip to content

refactor: isolate webhook signature verification - #921

Merged
apcha-oai merged 1 commit into
mainfrom
apcha/castiron-java-webhook-verifier
Aug 21, 2026
Merged

refactor: isolate webhook signature verification#921
apcha-oai merged 1 commit into
mainfrom
apcha/castiron-java-webhook-verifier

Conversation

@apcha-oai

Copy link
Copy Markdown
Contributor

Summary

Move the existing webhook-signature algorithm out of the generated blocking service into an SDK-owned, Kotlin-internal/JVM-synthetic helper. verifySignature is now a thin typed delegate. The algorithm is unchanged, including secret precedence, required-header order, timestamp tolerance, HMAC calculation, timing-safe comparison, and exception messages. The existing unwrap implementation and async delegation are unchanged.

The mixed-file count remains 61, but the handwritten patch in WebhookServiceImpl shrinks from +112/-3 to +26/-3. The other 60 customizations are unchanged. Public service signatures, generation metadata, and API-reference artifacts are unchanged.

All existing tests remain intact. The new WebhookVerificationTest runs each of these cases through both public client flavors:

  • usesClientSecretAndPerCallOverride: configured secret, per-call override, and mismatch.
  • acceptsInclusiveToleranceAndRejectsOutsideIt: both tolerance boundaries, outside values, and custom tolerance.
  • preservesRequiredHeaderAndTimestampErrors: missing-secret/header precedence and malformed timestamps.
  • acceptsRawAndEncodedSecretsAndAnyMatchingSignature: raw/encoded secrets and multiple signatures.
  • unwrapVerifiesBeforeParsing: valid events, signature failure before parsing, and parse-error wrapping.
  • withOptionsUsesUpdatedClock: the derived service uses the updated clock.

Security-focused review is requested because this relocates signature-verification code.

Test Plan

Automated

  • Full formatting, lint, SDK build, and Jackson compatibility: passed.
  • Existing blocking/async webhook tests plus WebhookVerificationTest: 23 passed, no skips.
  • Baseline and proposed API-compatibility compilation and public-signature checks: passed.
  • JVM signature comparison for both webhook service APIs and verification parameters: unchanged; the new helper method is synthetic.
  • Exact token/body comparison: verifier logic and every other service statement are unchanged.

@apcha-oai apcha-oai added the custom-code-burndown Behavior-preserving cleanup of custom code in generated SDK files label Aug 20, 2026
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Castiron custom code

✅ No new custom-code files detected.

61 mixed files remain; 1 existing customization changed.

Compared ca9c11dd90be8e7834241538. Generated baselines verified.

File Result Current custom patch
openai-java-core/src/main/kotlin/com/openai/services/blocking/WebhookServiceImpl.kt Existing customization changed +26 / −3
60 existing customizations unchanged
  • openai-java-core/src/main/kotlin/com/openai/models/audio/AudioResponseFormat.kt
  • openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesServerEvent.kt
  • openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParams.kt
  • openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionMessageFunctionToolCall.kt
  • openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionToolMessageParam.kt
  • openai-java-core/src/main/kotlin/com/openai/models/embeddings/Embedding.kt
  • openai-java-core/src/main/kotlin/com/openai/models/embeddings/EmbeddingCreateParams.kt
  • openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCreateParams.kt
  • openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCall.kt
  • openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionWebSearch.kt
  • openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt
  • openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseStreamEvent.kt
  • openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseTextConfig.kt
  • openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesServerEvent.kt
  • openai-java-core/src/main/kotlin/com/openai/models/videos/Video.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/BetaServiceAsync.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/BetaServiceAsyncImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsync.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/ResponseServiceAsyncImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/WebhookServiceAsync.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/WebhookServiceAsyncImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/audio/TranscriptionServiceAsyncImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/beta/ResponseServiceAsyncImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsync.kt
  • openai-java-core/src/main/kotlin/com/openai/services/async/finetuning/checkpoints/PermissionServiceAsyncImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/BetaService.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/BetaServiceImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/ImageServiceImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseService.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/ResponseServiceImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/WebhookService.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/audio/TranscriptionServiceImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/ResponseServiceImpl.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/chat/ChatCompletionService.kt
  • openai-java-core/src/main/kotlin/com/openai/services/blocking/finetuning/checkpoints/PermissionServiceImpl.kt
  • openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesServerEventTest.kt
  • openai-java-core/src/test/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParamsTest.kt
  • openai-java-core/src/test/kotlin/com/openai/models/embeddings/EmbeddingTest.kt
  • openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesServerEventTest.kt
  • openai-java-core/src/test/kotlin/com/openai/services/async/CompletionServiceAsyncTest.kt

20 more in the full report.

A changed generated baseline means this report cannot reliably identify which handwritten lines changed.

Inspect the custom-code diff

Download the exact patch produced by this run (requires repository access):

gh run download 32430461716 --repo openai/openai-java \
  --name castiron-custom-code-32430461716-1 --dir /tmp/castiron-custom-code-32430461716-1
git apply --stat /tmp/castiron-custom-code-32430461716-1/custom-code.patch
cat /tmp/castiron-custom-code-32430461716-1/custom-code.patch

Or reproduce it from an SDK checkout containing the vendored reporter:

git fetch --no-tags origin ca9c11dd90be5b10b67797a0af6e575ce776bb6a 8e78342415389cb8e1cac4902076f932f76ccb1d
python3 scripts/castiron/custom_code_report.py report \
  --base ca9c11dd90be5b10b67797a0af6e575ce776bb6a \
  --head 8e78342415389cb8e1cac4902076f932f76ccb1d --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-8e7834241538
cat /tmp/castiron-custom-code-8e7834241538/custom-code.patch

This is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR.

Full report and patch

@apcha-oai
apcha-oai marked this pull request as ready for review August 20, 2026 23:52
@apcha-oai
apcha-oai requested a review from a team as a code owner August 20, 2026 23:53
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-20T23:53:55.729011Z 8e78342 Draft marked ready
🔒 Security Review Completed 2026-08-20T23:54:33.165906Z 8e78342 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@openai-sdks

openai-sdks Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 17.406s for Java SDK PR #921.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 539ms
tests/chat-completions-create.test.ts ✅ Passed 823ms
tests/chat-completions-stream.test.ts ✅ Passed 345ms
tests/files-content-binary.test.ts ✅ Passed 176ms
tests/files-create-multipart.test.ts ✅ Passed 260ms
tests/files-list-pagination.test.ts ✅ Passed 266ms
tests/initialize-config.test.ts ✅ Passed 271ms
tests/instance-isolation.test.ts ✅ Passed 253ms
tests/models-list.test.ts ✅ Passed 200ms
tests/responses-background-lifecycle.test.ts ✅ Passed 410ms
tests/responses-body-method-errors.test.ts ✅ Passed 607ms
tests/responses-cancel-timeout.test.ts ✅ Passed 215ms
tests/responses-cancel.test.ts ✅ Passed 490ms
tests/responses-compact-retries.test.ts ✅ Passed 440ms
tests/responses-compact.test.ts ✅ Passed 294ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 386ms
tests/responses-create-advanced.test.ts ✅ Passed 1.604s
tests/responses-create-disconnect.test.ts ✅ Passed 1.206s
tests/responses-create-errors.test.ts ✅ Passed 318ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 291ms
tests/responses-create-retries.test.ts ✅ Passed 913ms
tests/responses-create-stream-failures.test.ts ✅ Passed 310ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 296ms
tests/responses-create-stream-wire.test.ts ✅ Passed 6.599s
tests/responses-create-stream.test.ts ✅ Passed 84ms
tests/responses-create-terminal-states.test.ts ✅ Passed 441ms
tests/responses-create-timeout.test.ts ✅ Passed 209ms
tests/responses-create.test.ts ✅ Passed 342ms
tests/responses-delete.test.ts ✅ Passed 262ms
tests/responses-input-items-errors.test.ts ✅ Passed 314ms
tests/responses-input-items-list.test.ts ✅ Passed 346ms
tests/responses-input-items-options.test.ts ✅ Passed 205ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 282ms
tests/responses-input-tokens-count.test.ts ✅ Passed 306ms
tests/responses-malformed-inputs.test.ts ✅ Passed 5.319s
tests/responses-not-found-errors.test.ts ✅ Passed 472ms
tests/responses-parse.test.ts ✅ Passed 769ms
tests/responses-retrieve-retries.test.ts ✅ Passed 360ms
tests/responses-retrieve.test.ts ✅ Passed 327ms
tests/responses-stored-method-errors.test.ts ✅ Passed 944ms
tests/retry-behavior.test.ts ✅ Passed 3.547s
tests/sdk-error-shape.test.ts ✅ Passed 427ms

View OkTest run #32430463788

SDK merge (ee11cb66df1a) · head (8e7834241538) · base (ca9c11dd90be) · OkTest (2b1bdfd25e98)

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed an independent security-focused review: the extracted webhook verifier is token-equivalent to the previous implementation and preserves HMAC-SHA256, timing-safe comparison, timestamp/replay protection, injected-clock behavior, secret decoding/precedence, multiple signatures, malformed-input errors, and verify-before-parse ordering for both blocking and async clients. Public signatures and compatibility remain unchanged.

@apcha-oai
apcha-oai added this pull request to the merge queue Aug 21, 2026
Merged via the queue into main with commit 715a304 Aug 21, 2026
11 checks passed
@openai-sdks openai-sdks Bot mentioned this pull request Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

custom-code-burndown Behavior-preserving cleanup of custom code in generated SDK files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants