For a higher-level overview of authentication and environments, see Authentication & Environments.
Overview
All Rebell server-to-server requests must be authenticated using an asymmetric RSA signature. The merchant signs the request using a private key; Rebell validates the signature using the merchant’s registered public key. Goals of RSA signing within Rebell:- Guarantee request authenticity
- Prevent tampering of payload and metadata
- Ensure requests cannot be replayed outside a valid temporal window
- Enforce a secure merchant identity model
Signing Workflow
A signed Rebell API request follows this lifecycle:1
Construct the Signing String
Build the string that will be signed, including method, path, Client-Id, timestamp, and payload
2
Serialize the Request Body
Convert the request body to a JSON string exactly as it will be sent
3
Sign with RSA
Sign the string using
SHA256withRSA algorithm4
Base64URL Encode
Encode the signature using Base64URL encoding
5
Add Signature Header
Include the signature in the
Signature header6
Send Request
Send the request over HTTPS
7
Rebell Validates
Rebell verifies signature + timestamp + payload integrity
Building the Signing String
The signing string is composed of two lines:Example
Important Rules
Signing String Construction Example
Signature Generation
Once you have the signing string, sign it using RSA-SHA256.Complete Request Example
Here’s a complete example of making a signed API request:Timestamp Requirements
TheRequest-Time header ensures replay protection.
| Requirement | Details |
|---|---|
| Format | ISO 8601 UTC timestamp (e.g., 2024-03-21T10:15:00Z) |
| Timezone | Must be UTC (indicated by Z suffix) |
| Tolerance | Must not differ from Rebell server time by more than ±5 minutes |
| Error | If drift exceeds this bound, Rebell returns TIMESTAMP_INVALID |
Best Practice: Ensure your backend servers use NTP synchronization to keep accurate time.
Timestamp Generation
Key Rotation Workflow
Rebell supports key rotation through versioning (keyVersion).
Rotation Sequence
1
Generate New Keypair
Merchant generates a new RSA keypair (minimum 2048-bit)
2
Upload Public Key
Merchant uploads the new public key to Rebell dashboard
3
Receive New Version
Rebell assigns a new
keyVersion number4
Update Signing Logic
Merchant updates signing logic to use the new private key and
keyVersion5
Transition Period
Both old and new signatures remain valid during transition
6
Deactivate Old Key
Old key is eventually deactivated in Rebell dashboard
Recommendation: Rotate keys at least annually or according to your internal security policies.
Key Rotation Example
Key Rotation
Webhook Signature Verification
Rebell signs webhook payloads using the same RSA mechanism. Merchants must verify these signatures.Verification Steps
1
Extract Signature
Parse the
Signature header to extract algorithm, keyVersion, and signature2
Reconstruct Signing String
Build the signing string from the request data
3
Validate Timestamp
Ensure
Request-Time is within acceptable window (e.g., 10 minutes)4
Verify RSA Signature
Verify using Rebell’s public key for the specified keyVersion
5
Process Event
Only process the webhook if verification succeeds
Verification Example
Common Errors and Resolution
INVALID_SIGNATURE
INVALID_SIGNATURE
Caused by:
- Incorrect signing string construction
- Wrong body serialization (extra spaces, different field order)
- Incorrect header values
- Using a retired
keyVersion - Base64 vs Base64URL encoding mismatch
- Log the exact signing string before signing
- Compare with what you expect byte-by-byte
- Ensure JSON serialization is consistent (no pretty-printing)
- Verify you’re using
SHA256withRSAalgorithm - Check that signature uses Base64URL encoding (not standard Base64)
Debug Signing String
TIMESTAMP_INVALID
TIMESTAMP_INVALID
Caused by:
- Clock skew greater than ±5 minutes
- Bad timezone conversions
- Non-UTC timestamps
- Missing
Zsuffix
- Use NTP time synchronization on your servers
- Always use UTC with
Zsuffix - Verify timestamp format:
2024-03-21T10:15:00Z
Correct Timestamp
ACCESS_DENIED
ACCESS_DENIED
Caused by:
- Wrong
Client-Id - Missing or wrong
keyVersion - Using production credentials in sandbox (or vice versa)
- Public key not registered with Rebell
- Verify your merchant credential set
- Ensure environment separation (sandbox vs production)
- Confirm public key is uploaded to Rebell dashboard
- Check
keyVersionmatches the registered key
Body Serialization Issues
Body Serialization Issues
Caused by:
- Pretty-printed JSON (with newlines/indentation)
- Different field ordering
- Unicode encoding differences
- Trailing whitespace
- Use compact JSON serialization
- Ensure consistent field ordering
- Use UTF-8 encoding
Consistent Serialization
Security Recommendations
Key Storage Best Practices
- Environment Variables
- AWS KMS
- HashiCorp Vault