Security
API authentication
BroSettlement API authentication uses asymmetric Ed25519 keys. Your backend signs each request with a private key, and BroSettlement verifies it with the registered public key.
Required headers
| Header | Description |
|---|---|
X-Api-Key-Id | API key UUID |
X-Api-Timestamp | Unix timestamp in UTC seconds |
X-Api-Nonce | Unique nonce for replay protection |
X-Api-Signature | Padded standard Base64 Ed25519 signature |
X-Api-Body-Hash | Lowercase SHA-256 hex of the exact body bytes; required by documented mutations |
Signature payload
Build the canonical string with exactly six lines:
text
METHOD
EXACT_REQUEST_TARGET
BODY_HASH
TIMESTAMP
NONCE
API_KEY_IDEXACT_REQUEST_TARGET is the raw path and query exactly as sent. For a request without body bytes, keep the third canonical line empty. For a body request, hash the exact raw bytes sent by the HTTP client.
Security controls
- Use Ed25519 key pairs for API authentication.
- Store private keys in a secrets manager or HSM-backed service.
- Rotate keys when access ownership changes.
- Enable IP whitelisting for production API keys.
- Enforce unique nonces for replay protection.
- Keep timestamps within the accepted request window.
- Use mandatory 2FA for all human users.
Example request
text
GET
/api/v1/assets?chain=tron%3Anile
1785402000
8f7b8f24-4e6a-45d2-a944-4b11c4c7d2f8
11111111-2222-4333-8444-555555555555The blank third line represents an absent body. Sign the exact text above, then send the same timestamp, nonce, and key ID in their headers.
Common failures
| Error | Cause | Fix |
|---|---|---|
INVALID_SIGNATURE | Signature does not match the canonical request | Preserve the exact request target and body bytes |
CLOCK_SKEW or INVALID_TIMESTAMP | Timestamp is invalid or outside the accepted window | Synchronize server time through NTP |
REPLAY_DETECTED | Nonce was already used | Generate a unique nonce for every request |
BODY_HASH_MISMATCH | Header hash differs from the body received | Hash the exact serialized bytes |
IP_NOT_ALLOWED | Request came from an unlisted IP | Update the API key IP allowlist |
INSUFFICIENT_SCOPE | API key lacks the operation scope | Grant the minimum required scope |