Skip to main content

Security Best Practices

API key storage

Store API keys in a secrets manager or environment variables. Never hardcode them in source code.
ApproachRecommended
Environment variablesYes. Minimum acceptable approach.
Secrets manager (AWS Secrets Manager, Vault, GCP Secret Manager)Yes. Preferred for production.
Configuration file (.env, config.yaml)Only if gitignored and encrypted at rest.
Hardcoded in source codeNo. Never.
Client-side JavaScriptNo. Keys are visible to anyone with browser dev tools.
Mobile app bundlesNo. APKs and IPAs can be decompiled.
Never hardcode API keys in source code, client-side JavaScript, or mobile app bundles. Keys in these locations are trivially extractable and cannot be considered secret.
# Set via environment variable
export ZENOO_API_KEY="your-api-key"
export ZENOO_WEBHOOK_SECRET="your-webhook-secret"

Key rotation

Rotate API keys on a regular schedule and immediately after any suspected compromise. Planned rotation. Prepare your deployment pipeline before requesting a new key. The old key is revoked the moment the new one is issued. There is no overlap period.
1

Prepare configurations

Update all application configurations and CI/CD secrets to accept the new key.
2

Request rotation

Request rotation from Zenoo support.
3

Receive the new key

Receive the new key from Zenoo support.
4

Deploy immediately

Deploy the new key to all environments immediately after receiving it.
Emergency rotation. If a key is exposed in a public repository, log file, or client-side code, contact Zenoo support immediately. The compromised key will be revoked and a new one issued.

Transport security

All API communication must use HTTPS. Zenoo does not accept HTTP requests. Use TLS 1.2 or higher.
  • Verify server certificates. Do not disable certificate validation in production.
  • Pin certificates if your security policy requires it.

IP allowlisting

Contact Zenoo support to configure IP allowlisting for your API keys. When enabled, requests from IPs outside the allowlist are rejected with 403 Forbidden. Considerations:
  • Provide the public IP addresses or CIDR ranges of your application servers.
  • Update the allowlist before deploying to new infrastructure.
  • Cloud-hosted applications with dynamic IPs may need a NAT gateway or static IP assignment.

Webhook endpoint security

Your webhook endpoint receives verification results that may contain personally identifiable information. Protect it accordingly. Verify signatures. Always validate the X-Zenoo-Signature header before processing any webhook payload. See Webhook Signatures for implementation details. Use HTTPS. Your webhook endpoint must be accessible over HTTPS. Zenoo will not deliver webhooks to HTTP URLs. Respond quickly. Return 200 OK within 30 seconds. Queue the payload for async processing rather than performing business logic in the request handler. Log failures. Record every failed signature verification with the timestamp, source IP, and request headers. A pattern of failures may indicate someone is probing or spoofing your endpoint. Restrict access. If possible, configure your firewall or load balancer to only accept webhook requests from Zenoo’s IP ranges. Contact Zenoo support for the current list.

Monitoring

Track these metrics to detect issues early. Set up automated alerts for any anomalies — early detection is the best defense against key compromise and integration failures.
MetricWhat to watch
API error rate by status codeSpike in 401/403 may indicate key compromise or misconfiguration
5xx error rateSustained increase suggests provider or infrastructure issues
Webhook delivery success rateFailures may indicate endpoint issues or network problems
Webhook signature verification failuresRepeated failures suggest a misconfigured secret or attack
Response latency (p50, p95, p99)Increasing latency may indicate provider degradation
Set up alerts for:
  • 5xx error rate exceeding 5% over a 10-minute window.
  • Any 401 errors (may indicate a rotated or leaked key).
  • Webhook signature verification failure rate above 0%.
  • Average response time exceeding 2x your baseline.
Log the request_id from every API response. When contacting Zenoo support, include this ID to enable fast diagnosis.
const response = await fetch(url, options);
const data = await response.json();

if (!response.ok) {
  console.error(`Zenoo API error: ${data.error}`, {
    requestId: data.request_id,
    status: response.status,
    message: data.message
  });
}