Security

Gravity SMS implements multiple layers of security to protect API access, data in transit, and stored credentials.

Transport security

  • HTTPS required — All API requests must use HTTPS in production. HTTP requests receive a 403 HTTPS required response.
  • TLS enforcement — The gateway only accepts TLS-encrypted connections, protecting data in transit including API keys and message content.

API key security

  • Hashed storage — API keys are hashed using SHA-256 before storage. The plaintext key is only returned once at creation time and cannot be retrieved later.
  • Prefix identification — Only the first 8 characters of the key (sgw_ prefix + 4 characters) are stored in plaintext for identification purposes.
  • Key rotation — API keys can be rotated via the rotate-key endpoint. The old key is immediately invalidated and a new key is generated.
Store your API key securely. It is only displayed once when the app is created or when the key is rotated. If lost, rotate the key to generate a new one.

WebSocket token security

Ephemeral WebSocket tokens allow browser-based applications to authenticate WebSocket connections without exposing API keys to client-side JavaScript.

  • Short-lived — Tokens expire after 60 seconds. Unused tokens are automatically cleaned up.
  • Single-use — Each token is consumed on first use and cannot be replayed.
  • In-memory only — Tokens are stored in server memory, not persisted to disk or database.
  • Scoped — Each token inherits the same appId, tenantId, and role as the API key that created it. No privilege escalation is possible.

Credential protection

RingCentral OAuth tokens are encrypted at rest using AES-256-GCM before being stored. Tokens are decrypted only when needed for API calls and are never exposed through any API endpoint.

Brute-force protection

The gateway tracks failed authentication attempts per IP address:

  • After 10 failed attempts within 5 minutes, the IP is blocked for 15 minutes.
  • Blocked IPs receive 429 Too many requests with a Retry-After header on all subsequent requests.

Security headers

The gateway sets standard security headers on all responses to mitigate common web vulnerabilities:

HeaderPurpose
Strict-Transport-Security: max-age=31536000; includeSubDomainsEnforces HTTPS for 1 year via HSTS, including subdomains.
X-Frame-Options: DENYPrevents clickjacking via iframes.
X-Content-Type-Options: nosniffPrevents MIME type sniffing.
X-XSS-Protection: 0Disables legacy XSS filter (modern CSP is preferred).
Content-Security-Policy: default-src 'none'Restricts all resource loading (API-only, no browser content served).
Referrer-Policy: no-referrerPrevents sending referrer information with requests.
Cache-Control: no-storePrevents caching of API responses.

Error sanitization

In production, unexpected server errors (5xx) return a generic {"error": "Internal server error"} response. Internal error details, stack traces, and implementation information are never exposed to API consumers.

Request size limits

Request bodies are limited to 100 KB by default. Requests exceeding this limit receive a 413 Payload too large response.

Webhook security

  • HTTPS required — Webhook URLs must use HTTPS in production environments, ensuring payloads are encrypted in transit.
  • HMAC-SHA256 signatures — Every webhook delivery includes an X-Gravity-Signature header containing an HMAC-SHA256 signature computed with the app's webhook secret. This allows you to verify that payloads are authentic and untampered.
  • Replay protection — The X-Gravity-Timestamp header is included in the signature computation. Reject requests with timestamps older than 5 minutes to prevent replay attacks.
  • Per-app secrets — Each app receives a unique webhook secret (whsec_ prefix) at registration time. Secrets can be rotated independently without affecting other apps.

See the Webhooks guide for implementation details and a code example.

Best practices

  • Rotate keys regularly — Use the rotate-key endpoint to periodically generate new API keys.
  • Use environment variables — Never hard-code API keys in source code. Store them in environment variables or a secrets manager.
  • Restrict key scope — Each API key is scoped to a single app. Use separate apps for different integrations to limit blast radius.
  • Monitor for 429 responses — A spike in rate limit errors may indicate credential leakage or unauthorized usage.
  • Verify webhook signatures — Always verify the X-Gravity-Signature header on incoming webhooks using your app's webhook secret.

Related docs