Authentication and Security
Jetpay's webhook system implements two layers of authentication to ensure security at both the API level and the webhook delivery level.
API Authentication
All webhook management operations (register, list, update, delete) require authentication using your company API token. Include your token in the Authorization header of API requests.
Webhook Request Authentication
Every webhook delivery includes a JWT (JSON Web Token) in the Authorization header with the format:
Authorization: Bearer <JWT>This JWT is signed using the RS256 algorithm (RSA Signature with SHA-256) and must be verified by your webhook endpoint to ensure the request genuinely comes from Jetpay.
JWT Structure
The JWT contains two main parts: headers and claims.
Headers:
- alg: Algorithm used for signing (always RS256)
- kid: Key identifier for retrieving the correct public key from JWKS endpoint
Claims:
- jti: Unique token identifier (UUID)
- iat: Issued at timestamp (Unix epoch)
- exp: Expiration timestamp (Unix epoch, typically ~90 seconds from issuance)
- iss: Issuer (always jetpay)
- sub: Subject (always webhook)
- payload_hash: Base64 url-encoded SHA-256 hash of the request body
JWKS Endpoint for Public Key Retrieval
To verify JWT signatures, retrieve Jetpay's public keys from our JWKS (JSON Web Key Set) endpoint:
Endpoint: GET /.well-known/jwks.json
This endpoint returns a standard JWKS response containing the public keys needed for JWT verification.
Payload Hash Verification
The payload_hash claim provides additional integrity verification:
- Compute the SHA-256 hash of the raw request body
- Base64 url-encode the hash
- Compare with the payload_hash claim in the JWT
This ensures the request body hasn't been tampered with during transit.
JWT Expiration
JWT tokens have a configurable expiration time, defaulting to approximately 90 seconds from issuance. Verify the exp claim to ensure the token hasn't expired. Expired tokens should be rejected.
This ensures your system will be protected from replay attacks.
Security Best Practices
- Always Verify JWT Signatures: Never trust webhook requests without validating the JWT signature using the public key from our JWKS endpoint
- Check Token Expiration: Reject requests with expired JWTs
- Verify Payload Hash: Compute and compare the payload hash to prevent tampering
- Use HTTPS Only: Configure webhook endpoints with HTTPS to protect data in transit
- Validate Event IDs: Track received event IDs to detect and handle duplicates
- Secure Token Storage: If using callback_api_key, store it securely (we'll include it in requests to your endpoint)
- Implement Rate Limiting: Protect your endpoint from potential abuse
- Monitor Failed Deliveries: Set up alerts for webhooks entering BACKING_OFF or FAILED states