Signature Verification
This document explains how to verify that API requests and webhooks from BRIJ are authentic and have not been tampered with.
Overview
All requests from BRIJ to your endpoints (API calls and webhooks) include a cryptographic signature in the
X-BRIJ-Signature HTTP header. This signature is a JSON Web Token (JWT) signed with BRIJ’s private key using the RS256
algorithm.
By verifying this signature, you can ensure that:
- The request originated from BRIJ
- The request payload has not been modified in transit
- The request is not a replay of a previous request
Signature Format
HTTP Header
JWT Structure
The signature is a standard JWT with three parts: header, payload, and signature.
- Always
RS256(RSA with SHA-256) - Token type, always
JWT
- Issuer - always
brij.fi - Audience - your partner ID
- Issued at - Unix timestamp (seconds) when the token was created
- Expiration - Unix timestamp (seconds), 10 minutes after
iat - JWT ID - unique UUID for this request (use for idempotency)
- SHA-256 hash of the request body, hex-encoded
Verification Steps
Follow these steps to verify an incoming request:
1. Extract the JWT
Get the X-BRIJ-Signature header from the incoming request.
2. Verify the JWT Signature
Using BRIJ’s public key (see below), verify the JWT signature. This confirms the token was signed by BRIJ.
3. Validate Claims
After signature verification, validate the following claims:
issmust equalbrij.fiaudmust equal your partner IDexpmust be greater than the current Unix timestamp (token not expired)
4. Verify Payload Integrity
- Read the raw request body
- Calculate the SHA-256 hash of the body
- Hex-encode the hash
- Compare with the
payload_hashclaim
If they match, the payload has not been tampered with.
5. (Optional) Check for Replay Attacks
Store the jti claim and reject any requests with a previously seen jti. This prevents replay attacks.
Public Keys
Use the appropriate public key based on your environment:
Production
Demo
Code Examples
Node.js / TypeScript
Python
Go
Security Best Practices
Always Verify Signatures
Never process a request from BRIJ without first verifying the signature. Unverified requests could be forged by malicious actors.
Reject Expired Tokens
The exp claim provides protection against replay attacks with old tokens. Always check that the token has not expired.
Implement Idempotency
Use the jti (JWT ID) claim to detect and reject duplicate requests:
- Store seen
jtivalues (e.g., in Redis with TTL matching token expiration) - Reject requests with previously seen
jtivalues - This prevents replay attacks even with valid, non-expired tokens
Use the Correct Public Key
Make sure to use the appropriate public key for your environment:
- Use the Demo public key for testing and development
- Use the Production public key for live transactions
Key Management
- Perform signature verification server-side, never in client-side code
- Subscribe to BRIJ notifications for key rotation announcements
Troubleshooting
”Invalid signature” Error
- Ensure you’re using the correct public key for the environment
- Verify the JWT string is complete and not truncated
”Token expired” Error
- Check if your server’s clock is synchronized (use NTP)
- Tokens are valid for 10 minutes from issuance
- If requests consistently expire, investigate network latency
”Payload hash mismatch” Error
- Ensure you’re hashing the raw request body before any parsing
- The hash must be calculated on the exact bytes received
- Check for any middleware that modifies the body before verification
”Invalid audience” Error
- Verify your partner ID matches what BRIJ has configured
- Partner IDs are case-sensitive
Missing Header
If you don’t see the X-BRIJ-Signature header:
- Check if your load balancer or proxy is stripping custom headers
- Verify the header name is case-insensitive in your framework
Support
If you encounter issues with signature verification, contact BRIJ support with:
- The full JWT token (from
X-BRIJ-Signatureheader) - The raw request body
- Your partner ID
- The error message you’re receiving
