Skip to content

fix(seed): honor a pinned webhook signing secret - #76

Merged
gjtorikian merged 1 commit into
mainfrom
fix/seed-webhook-secret
Aug 21, 2026
Merged

fix(seed): honor a pinned webhook signing secret#76
gjtorikian merged 1 commit into
mainfrom
fix/seed-webhook-secret

Conversation

@gjtorikian

Copy link
Copy Markdown
Collaborator

Summary

  • webhookEndpoints[].secret in the seed config is now honored (whConfig.secret ?? randomBytes(...)), matching what POST /webhook_endpoints already accepts — and the same convention as apiKeys[].value and connectApplications[].client_secret: a service needs known credentials before anything talks to the emulator.
  • This was the one seeded value a caller could not discover afterwards: the API masks an endpoint's secret after creation (abc12345****), so a signature-verifying consumer had to register its endpoint over the API — which in-memory state loses on restart, silently stopping deliveries.
  • validateSeedConfig rejects a non-string or empty secret next to the existing events check, and the README's webhook registration section now shows the pinned secret in the seed YAML.
  • New spec proves a pinned secret is what actually signs deliveries: a receiver verifies the WorkOS-Signature HMAC with the pinned value, an omitted secret still gets a generated one, and the validator accepts/rejects correctly.

Fixes #74

The HTTP route accepts a caller-chosen secret, but the seed always
generated one — and the API masks secrets after creation, so a
generated secret is unrecoverable. A consumer that verifies
WorkOS-Signature headers therefore could not use the seed file at
all: it had to register its endpoint over the API, which in-memory
state loses on restart, silently stopping deliveries. A pinned
secret follows the same convention as apiKeys[].value and
connectApplications[].client_secret: a service needs known
credentials before anything talks to the emulator.
@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown

Greptile Summary

The PR allows seed configuration to pin webhook signing secrets while retaining generated secrets when omitted.

  • Adds secret to the public seeded webhook endpoint configuration.
  • Validates provided secrets as non-empty strings before seeding.
  • Uses the pinned value for webhook HMAC signatures and documents the configuration.
  • Adds integration coverage for pinned and generated secrets.

Confidence Score: 5/5

The PR appears safe to merge with no actionable correctness or security issues identified.

Validation precedes all seed insertion paths, endpoint indexing occurs after seeded inserts, and the configured secret reaches HMAC signing unchanged while omission retains the existing generated-secret behavior.

Important Files Changed

Filename Overview
src/workos/index.ts Adds the optional seed field and persists it unchanged, with the existing random-secret fallback preserved.
src/workos/config-validator.ts Rejects empty and non-string webhook secrets before any seeded endpoint is inserted.
src/workos/seed-webhook-secret.spec.ts Verifies real delivery signatures for pinned secrets, generated-secret fallback behavior, and validation outcomes.
README.md Documents how and why consumers can pin a seeded webhook signing secret.

Reviews (1): Last reviewed commit: "fix(seed): honor a pinned webhook signin..." | Re-trigger Greptile

@gjtorikian
gjtorikian merged commit 5c38781 into main Aug 21, 2026
9 checks passed
@gjtorikian
gjtorikian deleted the fix/seed-webhook-secret branch August 21, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Seeded webhook endpoints ignore a supplied secret, so a signature-verifying consumer cannot use the seed file

1 participant