Skip to main content
Didit Raises $7.5M to Build the Infrastructure for Identity and Fraud
Didit
Back to blog
Blog · March 6, 2026

Build a Secure Webhook Middleware for Didit with AWS Lambda

Learn how to build a robust and secure API Gateway middleware for Didit's webhooks using AWS Lambda. This guide covers signature verification, timestamp validation, and asynchronous processing, ensuring data integrity and.

By DiditUpdated
aws-lambda-api-gateway-didit-webhooks.png

Secure Webhook Ingestion Implementing HMAC-SHA256 signature verification and timestamp validation is crucial for securing Didit webhooks against tampering and replay attacks, ensuring data integrity and authenticity.

Asynchronous Processing Architecture Leveraging AWS Lambda and SQS decouples webhook ingestion from processing, enhancing scalability, reliability, and allowing for complex downstream logic without impacting real-time responses.

Real-time Identity Updates Didit's webhooks provide instant notifications on identity verification outcomes, enabling immediate updates to user statuses, fraud alerts, or compliance records within your application.

Didit's Developer-First Approach Didit offers a modular architecture and clean APIs, making it straightforward to integrate real-time identity verification results into your systems, further enhanced by a free core KYC offering and no setup fees.

The Importance of Secure Webhook Handling

In today's interconnected digital landscape, real-time data exchange is paramount, especially for critical functions like identity verification. Webhooks serve as the backbone for these real-time notifications, allowing services like Didit to inform your application instantly about the outcome of an identity check, an AML screening result, or a liveness detection status. However, simply receiving data isn't enough; ensuring its authenticity, integrity, and timely processing is vital. An insecure webhook endpoint can be a significant vulnerability, susceptible to data tampering, replay attacks, or denial-of-service attempts. This is where a well-designed API Gateway middleware, particularly for Didit's webhooks, becomes indispensable.

When Didit completes an ID Verification, Passive & Active Liveness check, 1:1 Face Match, or AML Screening, it sends a webhook to your configured endpoint. This notification contains crucial information about the verification status. Without proper security measures, malicious actors could forge these notifications, leading to incorrect user onboarding decisions or fraudulent activities. For instance, a forged 'verified' status could grant access to a bad actor, while a faked 'failed' status could lead to legitimate users being blocked. Therefore, establishing a secure and robust webhook reception mechanism is not just good practice; it's a necessity for maintaining the security and compliance of your platform.

Building a Robust Middleware with AWS Lambda & API Gateway

To effectively and securely handle Didit's webhooks, we can leverage the power of AWS Lambda and API Gateway to create a serverless middleware. This architecture offers scalability, cost-efficiency, and high availability, perfectly suited for event-driven data processing. The core idea is to have API Gateway act as the entry point, forwarding requests to a Lambda function responsible for initial validation and secure processing.

Step 1: Setting up API Gateway as the Entry Point

Your AWS API Gateway will expose a public endpoint (e.g., /api/webhooks/didit) that Didit will send its webhooks to. It's crucial to configure this endpoint to accept POST requests and integrate it with your Lambda function. Unlike traditional setups, the API Gateway should be configured to pass the raw request body directly to Lambda without immediate JSON parsing. This is because signature verification requires the exact raw payload sent by Didit.

Step 2: Implementing Secure Validation in AWS Lambda

The Lambda function is the heart of your middleware. Upon receiving a webhook, it must perform several critical validation steps before processing the data:

  1. Read Raw Request Body: The Lambda function must access the raw request body. This is essential for HMAC-SHA256 signature verification.
  2. Verify HMAC-SHA256 Signature: Didit's webhooks include an X-Signature header containing an HMAC-SHA256 signature. Your Lambda function will use your webhook secret (shared between your application and Didit) to compute its own signature from the raw request body. If the computed signature does not match the X-Signature header, the webhook is invalid and should be rejected immediately. This protects against data tampering.
  3. Validate Timestamp: Didit also includes an X-Timestamp header. Your Lambda function should verify that this timestamp is fresh, typically within a 5-minute window of the current time. This prevents replay attacks, where an attacker might resend an old, legitimate webhook event.
  4. Parse JSON Body: Only after successful signature and timestamp verification should the raw body be parsed into a JSON object.

Here's a conceptual Python snippet for signature verification within your Lambda:


import hmac
import hashlib
import time
import json

def verify_webhook_signature(body, headers, secret):
    signature_header = headers.get('X-Signature')
    timestamp_header = headers.get('X-Timestamp')

    if not signature_header or not timestamp_header:
        return False, "Missing signature or timestamp header"

    # Check timestamp for freshness (e.g., within 5 minutes)
    current_time = int(time.time())
    event_timestamp = int(timestamp_header)
    if abs(current_time - event_timestamp) > 300: # 300 seconds = 5 minutes
        return False, "Webhook timestamp too old or too far in future"

    # Reconstruct the signed payload
    signed_payload = f"v1:{timestamp_header}:{body}"

    # Compute HMAC signature
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        signed_payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    # Compare signatures in a secure way (constant time comparison)
    if hmac.compare_digest(signature_header, expected_signature):
        return True, "Signature valid"
    else:
        return False, "Signature mismatch"

# In your Lambda handler:
def lambda_handler(event, context):
    body = event['body'] # Raw request body
    headers = event['headers']
    webhook_secret = "YOUR_DIDIT_WEBHOOK_SECRET" # Store securely, e.g., in AWS Secrets Manager

    is_valid, message = verify_webhook_signature(body, headers, webhook_secret)

    if not is_valid:
        print(f"Webhook validation failed: {message}")
        return {
            'statusCode': 403,
            'body': json.dumps({'message': 'Unauthorized'})
        }

    # If valid, parse JSON and proceed with processing
    payload = json.loads(body)
    # ... process payload ...

    return {
        'statusCode': 200,
        'body': json.dumps({'message': 'Webhook received and processed'})
    }

Asynchronous Processing for Scalability and Reliability

After validating the webhook, it's generally best practice to decouple the ingestion process from the actual business logic. This means your Lambda function, after validation, should not directly execute complex database operations or external API calls. Instead, it should simply push the validated payload to an asynchronous processing queue, such as AWS SQS (Simple Queue Service).

This architecture offers several advantages:

  • Scalability: Your API Gateway and initial Lambda can handle a high volume of incoming webhooks without being bottlenecked by downstream processing.
  • Reliability: If your downstream systems are temporarily unavailable, messages remain in the queue, preventing data loss.
  • Decoupling: Different Lambda functions or services can process messages from the SQS queue, allowing for modular and independent development and deployment of your business logic (e.g., updating user records, triggering AML alerts, or logging verification results).
  • Fast Responses: The initial webhook endpoint can respond quickly (e.g., with a 200 OK), preventing Didit from retrying the webhook unnecessarily.

This ensures that whether you're performing ID Verification, using NFC Verification for ePassports, or leveraging Age Estimation for compliance, the results are processed efficiently and reliably.

How Didit Helps

Didit is an AI-native, developer-first identity platform designed for modularity and ease of integration. Our webhooks are a prime example of this philosophy, providing real-time, secure notifications about the status of your identity verification workflows. By offering a clean API and comprehensive documentation, Didit makes it straightforward to set up and integrate these webhooks into your custom middleware, like the AWS Lambda and API Gateway solution described above.

Didit's platform supports a wide array of identity verification primitives, including ID Verification (OCR, MRZ, barcodes), Passive & Active Liveness, 1:1 Face Match & Face Search, AML Screening & Monitoring, Proof of Address, Age Estimation, Phone & Email Verification, and NFC Verification. The results from any of these checks can be delivered via our secure webhooks, allowing you to build highly responsive and automated systems. Furthermore, Didit offers Free Core KYC, a modular architecture, and no setup fees, making it an accessible and powerful choice for businesses of all sizes looking to automate trust and orchestrate risk.

Ready to Get Started?

Ready to see Didit in action? Get a free demo today.

Start verifying identities for free with Didit's free tier.

Infrastructure for identity and fraud.

One API for KYC, KYB, Transaction Monitoring, and Wallet Screening. Integrate in 5 minutes.

Ask an AI to summarise this page
Build Secure Webhook Middleware for Didit with AWS Lambda.