The queue worker posts job results to callback_url. Without a hardened receiver you get duplicate Slack alerts, double CSV imports, and race conditions when workers retry. This recipe is a minimal FastAPI service with HMAC verification and job_id deduplication.

Flow

Worker POST /hooks/mlx  → verify X-MLX-Signature
                        → dedupe job_id (Redis SET NX)
                        → update job status in DB / notify ops
                        → 200 OK (even on duplicate — idempotent)

Payload contract

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "ok",
  "profile_id": "mlx-profile-uuid",
  "task": "sync_orders",
  "duration_ms": 8420,
  "error": null
}

Workers may retry on timeout — receiver must treat duplicate job_id as success (return 200, no side effects).

HMAC sign (worker side)

import hmac
import hashlib
import json

SECRET = b"your-shared-secret"

def sign(body: dict) -> str:
    raw = json.dumps(body, separators=(",", ":"), sort_keys=True).encode()
    return hmac.new(SECRET, raw, hashlib.sha256).hexdigest()

# Header: X-MLX-Signature: <hex>

FastAPI receiver

from fastapi import FastAPI, Request, HTTPException
import hmac
import hashlib
import json
import redis

app = FastAPI()
r = redis.Redis(decode_responses=True)
SECRET = b"your-shared-secret"
IDEMP_TTL = 86400  # 24h

def verify_sig(body: bytes, sig: str) -> bool:
    expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig or "")

@app.post("/hooks/mlx")
async def mlx_webhook(request: Request):
    raw = await request.body()
    sig = request.headers.get("X-MLX-Signature", "")
    if not verify_sig(raw, sig):
        raise HTTPException(401, "invalid signature")

    payload = json.loads(raw)
    job_id = payload["job_id"]
    idem_key = f"mlx:hook:{job_id}"

    # Idempotent: first delivery wins
    if not r.set(idem_key, "1", nx=True, ex=IDEMP_TTL):
        return {"accepted": True, "duplicate": True}

    status = payload.get("status")
    if status == "ok":
        mark_job_complete(job_id, payload)
    else:
        mark_job_failed(job_id, payload.get("error"))

    notify_ops(payload)  # Slack, PagerDuty, etc.
    return {"accepted": True}

Flask variant (minimal)

from flask import Flask, request, abort
app = Flask(__name__)

@app.post("/hooks/mlx")
def mlx_hook():
    raw = request.get_data()
    if not verify_sig(raw, request.headers.get("X-MLX-Signature", "")):
        abort(401)
    payload = request.get_json()
    if not r.set(f"mlx:hook:{payload['job_id']}", "1", nx=True, ex=86400):
        return {"accepted": True, "duplicate": True}, 200
    handle_payload(payload)
    return {"accepted": True}, 200

Security checklist

Observability hooks

Increment counters for webhook_received_total{status} and webhook_duplicate_total. Wire to observability guide Grafana panels alongside queue latency.

Related

Disclosure: MLX-MMO affiliated with Multilogin. Verify API endpoints against official Multilogin documentation.