Prompt
ChatGPT, I need to test webhook endpoints locally and in staging without exposing secrets.
Latest observation
A good way to do this is to separate “receiving” from “trusting”:
Safe patterns for local + staging webhook testing
1) Use a tunneling tool for local development
Expose your local webhook server through a temporary public URL using:
- ngrok
- Cloudflare Tunnel
- LocalTunnel (less preferred)
This lets the external service send webhooks to your local machine without deploying code.
Best practice: use a dedicated dev/staging webhook endpoint and a separate signing secret for that environment.
2) Never put production secrets in local configs
Instead:
- store secrets in environment variables
- use a secret manager in staging/production
- keep separate credentials per environment
- dev
- staging
- production
If a webhook provider requires a signing secret, generate a different secret for testing.
3) Validate signatures, but don’t log secrets
When testing webhook requests:
- verify the provider’s signature header
- return
401/403if invalid - avoid printing the raw secret or full signature in logs
- if needed, log only:
- event ID
- timestamp
- hash prefix or truncated signature
- request ID
4) Use replayable fixtures for local testing
Save representative webhook payloads as JSON fixtures and replay them locally with:
curl- Postman
- Insomnia
- a small script
This is especially useful for testing logic without needing real external callbacks.
Example:
curl -X POST http://localhost:3000/webhook \
-H 'Content-Type: application/json' \
-H 'X-Signature: test-signature' \
--data @fixtures/webhook-event.json
5) For staging, use a separate app/integration
If the provider supports it:
- register a staging webhook URL
- use a staging app/client ID
- use a staging signing secret
- restrict staging access with IP allowlists or auth if possible
This prevents test traffic from mixing with production data.
6) Mock the provider for unit/integration tests
For automated tests, don’t depend on live webhooks:
- mock HTTP callbacks
- record/replay real payloads
- use contract tests against sample payloads
This gives you repeatable tests and avoids exposing live credentials.
Minimal secure setup
- Local: tunnel + test secret
- Staging: dedicated webhook endpoint + staging secret
- Prod: production endpoint + production secret
- All environments: signature verification + no secret logging
If you want, I can help with one of these next:
- a Node/Express webhook verifier
- a Python/FastAPI example
- a docker-compose + ngrok/cloudflared setup
- a safe testing workflow for your specific webhook provider (Stripe, GitHub, Slack, etc.)