Skip to content

fix: replace personal and merchant data in sample payloads - #82

Merged
garethx merged 1 commit into
mainfrom
fix/scrub-personal-data
Nov 5, 2026
Merged

garethx merged 1 commit into
mainfrom
fix/scrub-personal-data

Conversation

@garethx

@garethx garethx commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Replaces personal and merchant data in the sample payloads published to samples.hookdeck.com and shown on the Inspect vendor pages. This changes 860 files: every JSON key is unchanged apart from the removed signature and content-length headers. yarn compile succeeds and yarn test passes 26 of 26.

No real values appear in this PR text or the commit message.

What was replaced

Data Replacement
Emails, unless at a reserved domain or a role or placeholder address at the vendor's or a generic domain userN@example.com
Names, usernames and avatars beside a replaced email Jane Doe, jane-doe, https://example.com/avatar.png
Phone numbers that aren't already fictional Same format, 555 digits
Public IPs in IP fields 203.0.113.x (RFC 5737)
LinkedIn profile URLs linkedin.com/in/example-profile
AWS key ids and signatures in signed URLs AWS's published AKIAIOSFODNN7EXAMPLE and a placeholder signature
Basic and Bearer Authorization headers username:password in base64, Bearer example-token
Message ids Same id, domain changed to example.com

Every webmail address is gone, including all those in the known list (revenuecat, paysafe, azure-devops, resend, gitlab, authgear, cin7-core, uppromote, textus, hubspot, certn, github, bitbucket). Mailgun IPs and the BigCommerce store hash and test credentials are also replaced.

Aimfox: all 17 samples are rebuilt from Aimfox's current official examples (retrieved 2026-11-05), with identity fields replaced. See review item 1.

Captures changed

Captures are files with no source key, and 219 changed. When a body changed, its signature and stale content-length went too, so no capture keeps a signature that no longer matches.

Provider Files Fields
adyen 7 merchantAccountCode, NAME1/NAME2, Basic authorization, a phone number. Each hmacSignature removed
ampersand 2 Names, emails, location, Intercom and workspace ids, group and installation ids
bigcommerce 57 store_id, store hash in producer, username/password headers
bitbucket 10 Person and workspace names, account_id, uuid, gravatar links, commit authors and emails
commercelayer 7 Emails, customer name, order token, organization_id. Signature removed
github 10 Login, name, numeric id and node_id, avatar, emails, and the login inside URLs. x-hub-signature* removed
gitlab 7 Name, username, ids, avatar, emails, x-gitlab-token
hubspot 3 Contact and company properties, portal id, profile token and URL, LinkedIn URL, phone, email. Signatures removed
paddlebilling 5 cardholder_name. paddle-signature removed
paddleclassic 1 ip. p_signature removed
paypal 19 Names, addresses, merchant_id, business name, website, emails, phones. paypal-transmission-sig removed
pipedrive 12 Person and org names, deal title, emails, phones, meta.host, company and user ids, Basic authorization
scrapfly 1 client_ip, user_uuid. Placeholder signature removed
shopify 68 2023-01 real-store group: x-shopify-shop-domain in all 68; store URLs, vendor, shop_owner and person names where present. The 10 with a changed body lost x-shopify-hmac-sha256; the other 58 changed only a header, so their HMAC still holds
stripe 10 Customer name and email, account_name, hosted invoice, payment and buy links. stripe-signature removed

Captures I checked and left unchanged: WooCommerce (store host is local or a placeholder, signatures intact), Vapi (already sanitized), Formstack, Cronofy, Monday and Checkout.

Doc-sourced samples changed

623 files in 133 providers. Their source metadata is unchanged but they now differ from the vendor docs in the replaced values. Where a body changed, 11 signatures went too: Treezor object_payload_signature (9), BVNK (1) and Veriff (1).

Providers and file counts

360dialog (1), 8x8 (1), adyen (2), aftership (1), agentmail (10), aiprise (3), aircall (1), airwallex (2), attentive (9), auth0 (3), authgear (6), azure-devops (18), azure-event-grid (2), bigcommerce (3), bird (7), bitdefender (1), boldsign (4), box (1), brevo (1), bvnk (1), cal-com (1), castle (1), certn (1), checkout (1), cin7-core (15), clickup (1), community (4), connecteam (2), coterie (1), currents (1), dentally (1), document360 (1), doordash-drive (1), dub (4), envoy (13), factorial (1), folk (1), fountain (2), fusionauth (27), github (6), gitlab (5), goody (8), green-api (1), guesty (3), heroku (3), hibob (1), hitpay (12), honeybadger (3), humaans (1), incident-io (13), kolide (2), kombo (1), kustomer (2), launchdarkly (1), learnupon (12), lettermint (1), linear (1), linq (19), lokalise (2), mailersend (1), mailgun (6), mailtrap (1), micetribe (1), middesk (4), missive (1), modern-treasury (6), motive (1), nash (1), nitrosend (1), nium (3), nylas (2), oncehub (1), onelogin (1), opsgenie (12), partnero (1), paysafe (9), payt (11), paytabs (1), picqer (1), pipedrive (2), planetscale (4), polytomic (1), postmark (3), qonto (1), razorpay (6), recharge (16), recruitee (4), resend (14), revenuecat (9), rewardful (1), ringcentral (7), rocketlane (1), scalekit (11), segment (1), semaphore (1), sendgrid (1), sentry (2), shippo (1), slack (7), smile (1), snipcart (2), socure (7), solidgate (1), spacelift (1), sparkpost (23), square (6), statsig (1), storyblok (22), storylane (1), strapi (5), stream (9), supabase-auth-hooks (3), surge (9), telnyx (14), textus (1), thinkific (15), travtus (1), treezor (9), unipile (1), unit (1), uphold (1), uppromote (7), velt (1), veriff (1), waha (4), walmart (1), webflow (2), wistia (3), wiza (1), workable (4), zendesk (24), zoho-sign (1), zoom (29)

For a person to review

  1. Aimfox's own examples look like real people. The official examples no longer share any email with what we had, but they still carry first.last@ emails at 7 non-reserved domains (4 have MX records), LinkedIn-style public_identifiers and pictures under aimfox.com/linkedin-profile/. I couldn't tell whether they are invented, so I kept the event structure and non-identity fields and replaced the identity fields. These samples no longer match upstream byte for byte. Someone may want to raise this with Aimfox.
  2. Shopify's test fixture (436 files, x-shopify-shop-domain: shop.myshopify.com) is unchanged, so its HMACs stay valid. It still has 4 emails at non-reserved domains (email, customer.email, customer_email, email_address), plus phones, addresses and names. I treated these as Shopify's synthetic data because they repeat across API versions and some match known fixture values, but I didn't confirm them against Shopify's docs.
  3. Names without a real email beside them, in doc-sourced samples, were not judged: 286 files in 74 providers. The most are in github (45), cal-com (17), taiga (14), pine-labs (12) and fanvue (10). Their name, first_name, username and similar fields look like vendor examples, but nobody has checked each one.
  4. Merchant, store, company or org fields in doc-sourced samples were not judged: 419 files in 50 providers. The most are in square (148), payt (43), onfleet (26), notion (23) and pine-labs (20).
  5. Account ids left in captures: Stripe cus_/sub_ ids, HubSpot objectId, vid and owner ids, and Monday, PayPal and Commerce Layer resource ids. They need the account's API access to resolve, so I left them.
  6. BigCommerce body.hash was kept. I treated it as a hash of the event data rather than a signature, but didn't verify what it covers.
  7. Hookdeck-named repos and workspaces remain in the GitHub, GitLab and Bitbucket captures. I took these as our own test repos, not personal data.
  8. Tokens left in doc samples: VideoAsk media JWTs (media_id and exp claims, expired in 2020), Uphold shareToken (jti and url claims, no expiry) and FusionAuth jwt.refresh event.token (no email claim). The FusionAuth event.original, which has an email claim, was replaced.
  9. Zendesk fields still to check: detail.name, event.actor.name, event.comment.author.name, and event.previous in organization.name_changed. They look like placeholders or organization names. The 24 detail.email values were a Cloudflare email mask scraped from the docs and are now user@example.com.
  10. Kept emails: about 320 at non-reserved domains stayed. Most are role addresses or placeholder names at the vendor's own domain or a generic domain, such as noreply@. They were matched by rule, not read one by one.
  11. Known limits of the rules: single-word first names inside free text can remain, and base64 or otherwise encoded payloads weren't decoded (JWT claims were). A company or team name next to a real email may now read "Jane Doe".

Rotate if still in use

These secrets were public, and this PR doesn't change that: Adyen and Pipedrive Basic authorization headers, the GitLab x-gitlab-token, BigCommerce username/password, and the HubSpot profile-token.

Git history: not rewritten, your decision

The old values stay in public history: 209 commits on 4 branches (main, master, feat/scrapfly-may-2026, claude/zealous-mccarthy-zricp2), 0 tags, 73 PRs and 24 forks. A rewrite would involve:

  • Running git filter-repo --replace-text with the private old-to-new map on a fresh mirror clone, then force-pushing every branch. The map holds the real values, so it isn't in this repo.
  • Every commit SHA changes, so open branches must rebase and existing clones must re-clone.
  • GitHub keeps refs/pull/* and cached commit views, which a force-push can't remove. Purging them needs a GitHub Support sensitive-data request.
  • Forks keep their own copies. GitHub Support may help with some, but we can't guarantee their removal.

A rewrite reduces exposure but can't undo it, so rotating the credentials above matters either way.

🤖 Generated with Claude Code

Some samples held real-looking emails, names, phone numbers, IPs,
merchant and store identifiers, access tokens and Authorization
headers. They are published to samples.hookdeck.com and shown on the
Inspect vendor pages.

Replace them with reserved-domain and obviously fictional placeholders,
rebuild Aimfox from its current published examples, and drop signatures
and content-length headers from any capture whose body changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
webhook-samples Ready Ready Preview Nov 5, 2026 4:34pm UTC

Request Review

@garethx
garethx merged commit 68b39e9 into main Nov 5, 2026
3 checks passed
@garethx
garethx deleted the fix/scrub-personal-data branch November 5, 2026 17:04

This branch was successfully deployed

1 active deployment
Preview — 9a6378ff Deployed Nov 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant