Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Webhook Verification — HMAC Signature Prototype

Task 1 (Solo Recon) · The Meridian Pivot sprint · Northstar Retail Co. (Sprint 2) Unfamiliar tool learned: Webhook verification via HMAC-SHA256 signatures.

A minimal Flask service that receives webhook POST requests and verifies their authenticity using an HMAC-SHA256 signature. This proves two things about every incoming request:

  • Origin — the sender holds the shared secret (not just anyone can forge it).
  • Integrity — the payload has not been altered since it was signed.

This prototype is the solo-learning deliverable for Assignment 1. It also lays the groundwork for the team's Day 4 pivot, when Northstar switches its inventory sync from a polling model to a webhook push model.


Why this matters (the sync context)

Northstar wants a live inventory sync service so their support tool's "is this in stock?" answers stay accurate.

  • Original spec (polling / pull): ask the warehouse API every 5 minutes.
  • Pivot spec (webhook / push): the warehouse pushes a notification the moment stock changes — and every pushed message must be verified before we trust it.

Verifying those pushes is exactly what this prototype does.


How it works

Sender                                   Receiver (this service)
------                                   -----------------------
signature = HMAC(secret, payload)
POST /webhook  ─────────────────────────▶  recomputed = HMAC(secret, raw_body)
  header: X-Signature: <signature>         compare_digest(recomputed, received)
                                             match   → 200  {"status": "valid"}
                                             mismatch→ 401  {"status": "invalid"}
                                             missing → 401  {"error": "..."}

Key security detail: comparison uses hmac.compare_digest() (constant-time) to prevent timing attacks, rather than a plain ==.


Project structure

webhooks-verification/
├── app.py               # Flask server: /webhook endpoint + HMAC verification
├── test_webhook.py      # Test harness: valid / tampered / missing-header cases
├── Blocker_Journal.md   # Learning & Blocker Journal (Assignment 1 deliverable)
├── README.md            # This file
└── .gitignore

Getting started

Prerequisites

  • Python 3.10+
  • pip install flask requests

1. Run the server

python3 app.py
# Serving on http://127.0.0.1:5000

2. Run the tests (in a second terminal)

python3 test_webhook.py

Expected results

Test Scenario Status
1 Valid signature 200{"message": "Signature verified", "status": "valid"}
2 Tampered payload (signature for original body) 401{"message": "Signature mismatch", "status": "invalid"}
3 Missing signature header 401{"error": "Missing signature header"}

Configuration

Setting Current (prototype) Production recommendation
Shared secret Hard-coded constant Read from os.environ.get("WEBHOOK_SECRET")
Debug mode debug=True False behind a WSGI server (gunicorn/uwsgi)
Replay protection None Validate a timestamp header, reject if > 5 min old

Known limitations & next steps

  • Secret is hard-coded — move to an environment variable.
  • No timestamp/replay protection yet.
  • No key-rotation / multiple-signature support.
  • Development server only (not production-hardened).

These are intentionally out of scope for the Day 1–2 solo prototype and are logged in Blocker_Journal.md under "If I had more time."


Author

Alex — Task 1, The Meridian Pivot sprint.

About

Learning Webhook verification via HMAC-SHA256 signatures.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages