Security and Reliability Best Practices

Bitnob is designed to be programmable financial infrastructure. With stablecoins, you’re interacting with real money over public blockchains—so security, permission management, and reliability must be treated as core parts of your integration. This section outlines how to build a production-grade, fault-tolerant setup.


API Key Management

All access to Bitnob’s APIs is authenticated using HMAC signatures generated with your secret keys. These keys are powerful and must be handled with care — a ready-made signing function is available in the API reference.

Best Practices:

Use separate keys for production, staging, and development

Rotate keys regularly via the Bitnob Dashboard

Never expose keys in frontend code, GitHub, or client apps

Keys are tied to a company account. You can generate and manage them in the API section of your dashboard, and confirm a new key works with Validate Authentication.


Role-Based Scopes

A scope is a named permission attached to an API key that decides which endpoints the key may call. A key missing a scope still authenticates — it simply cannot reach the endpoints behind that scope, so a compromised read-only key cannot be used to move funds.

Scopes are named resource:action: the part before the colon is what is being acted on (wallet, transfer, webhook) and the part after it is how much power you are granting (read looks, write creates, create moves value). Each one maps directly to endpoints — wallet:read covers Get Balances, wallet:write covers Generate Addresses, and transfer:create covers Create Withdrawal:

scope
capability
blast radius if leaked
wallet:read
View wallet balances and metadata
Low — cannot create anything or move funds. The right scope for reporting, reconciliation and internal dashboards.
wallet:write
Create deposit addresses
Medium — creates places to receive funds, but cannot send any. Needed by whatever service onboards users.
transfer:create
Send stablecoins to addresses
High — this is the only scope that moves money. Grant it to the single service that initiates payouts, and nothing else.
webhook:read
View configured webhooks
Low — read-only view of your webhook configuration. Note that receiving webhooks needs no scope at all; Bitnob calls you.

Apply least privilege: only give keys the permissions required for a specific service or microservice. To confirm what a key actually carries, call Validate Authentication and inspect data.permissions — an unscoped key returns null there, meaning full account-level access. Treat that as a development-only setting.


Webhook Security

Bitnob signs all webhook requests using a shared secret with HMAC SHA-256. The reference implementation lives under Verifying Events.

To verify a webhook:

Get the X-Bitnob-Signature header from the request

Hash the raw request body using your webhook secret

Compare the result with the header value (use constant-time comparison)

Why it matters: Prevents spoofed or replayed webhook attacks.

If your infrastructure also restricts inbound traffic by IP, allowlist the addresses published under Source IPs. Treat the allowlist as a second layer only — signature verification remains the authoritative check.


Transfer Integrity and Idempotency

Always use a unique reference per outbound transfer — see the withdrawal request fields

Never initiate a second transfer until you’ve confirmed failure or completion of the first — the withdrawal status lifecycle defines which states are final

Listen for transfer.failed and transfer.success events for final state

Use internal locking if your app supports concurrent withdrawals


Access Control Recommendations

Enforce 2FA on all admin dashboards

Segment sensitive operations (like transfer:create) into separate services

Log all internal actions on your infrastructure: who initiated a transfer, who changed keys, etc.

If you operate a multi-tenant platform, make sure tenants cannot trigger transfers outside their scope


Reliability Patterns

failure
pattern
API downtime
Queue and retry writes with backoff
Webhook outage
Allow replays or trigger from dashboard
Chain congestion
Alert on delayed confirmation, auto-prioritize fees
Transfer failure
Automatically trigger re-attempt logic only after validation

Monitoring and Alerting

We recommend tracking the following for observability:

Transfer success and failure rates, per chain

Webhook delivery latencies and error rates

Wallet balance health (per token, per chain) via Get Balances

Key usage: high-frequency access or abuse patterns

Integrate these metrics into your monitoring stack (e.g., Datadog, Prometheus, Sentry).


Fraud Prevention Tips

Check every user-provided wallet address with Validate Address before you submit the transfer, so it matches the token standard expected on that chain (e.g., ERC-20 for Ethereum)

Require users to confirm high-value transfers with 2FA or passkeys

Set thresholds for withdrawals per account per day

Use reference checks to prevent double submission

Automatically flag withdrawals to newly created or unverified addresses

Validating an address

POST /api/addresses/validate takes an address and a chain and answers one question: is this string a well-formed address on that network? The response returns valid as a boolean, echoes back the address and chain it checked, and adds an error string explaining the failure when valid is false.

Two limits are worth stating plainly to your team: it is a format check only — it does not assign, persist or fund anything, and it cannot tell you whether the recipient actually controls the address, so it stops typos and wrong-chain pastes, not social engineering. Because it is a plain POST, it costs nothing to call it on every address a user types in.

The full request and response fields, with a signed example, are documented under Validate Address in the Addresses API reference.


Share on
Did you find this page useful?

Join our Discord