SDK Example: Building Encrypted Mobile Signing Notifications Using RCS and Push with Fallbacks
developermobileSDK

SDK Example: Building Encrypted Mobile Signing Notifications Using RCS and Push with Fallbacks

ddocsigned
2026-02-10
10 min read
Advertisement

Developer SDK sample: send encrypted RCS messages with push and SMS fallbacks. Includes code, security best practices, and legal notes.

Hook: Stop losing deals to slow, insecure signing flows — send encrypted mobile signing prompts where users live

Paper and email-centered signing slows deals and frustrates customers. Today, buyers expect a secure, one-tap signing experience in their native messaging apps. In 2026, that means combining encrypted RCS where available, reliable push notifications, and an SMS fallback — all coordinated by a server-side SDK that handles encryption, callbacks, and rate limiting.

What you’ll get in this SDK example

  • Practical architecture for a server + mobile SDK that sends encrypted RCS, falls back to push, then SMS.
  • Node.js sample sending flow and encryption snippets (X25519 + AES-GCM pattern).
  • Mobile-side considerations: device key storage, decrypting payloads, and attestation and identity verification.
  • Callback security: HMAC, JWT, mutual TLS, replay protection.
  • Operational controls: rate limiting, batching, monitoring, and legal disclaimers for electronic signatures.

The big picture (inverted pyramid)

Priority: deliver a signed request to the recipient's most secure channel first (RCS E2EE), then push, then SMS. Always keep an immutable audit trail for legal defensibility. Encrypt payloads end-to-end when possible and sign server callbacks.

Why this matters in 2026

By 2026 the ecosystem is changing fast: GSMA's Universal Profile 3.0 and vendor moves during 2024–2026 have brought broad RCS E2EE support to major carriers and device vendors. Apple’s iOS builds in E2EE RCS support in late 2025–2026 betas and Google continues to push RCS as the native rich-messaging alternative. At the same time, privacy and anti-fraud regulation and new platform restrictions (APNs and FCM token lifecycles, SMS carrier filtering policy updates) require architects to design robust multi-channel delivery with secure fallbacks and traceable audit logs.

Architecture overview

Design the system as a three-layer flow:

  1. Message Orchestrator (Server SDK) — decides channel priority, encrypts payload, stores audit logs, enforces rate limits, and sends via provider APIs (RCS gateway, FCM/APNs, SMS provider). Use a hosted KMS or an on-prem model and plan migrations using guidance like sovereign cloud migration playbooks when you need data residency.
  2. Delivery Providers — carrier RCS API gateway, push services (FCM/APNs), and SMS API (Twilio/MessageBird).
  3. Mobile SDK — receives encrypted payloads, decrypts using device key, validates server-signed metadata, displays signing UI, and posts outcome back to server via secure callback.

Flow summary

  • Step 1: Server requests recipient public key (or attempts RCS send) via carrier RCS API.
  • Step 2: If RCS success, deliver encrypted RCS message. If unsupported or undelivered, fall back to push (encrypted payload) and then SMS (minimal content + link).
  • Step 3: Mobile SDK decrypts payload, validates the message signature, and shows signing UI. After signing, the device submits a signed callback.
  • Step 4: Server verifies callback signature, records the event in the audit trail (with timestamps, IPs, device attestation), and completes the contract lifecycle.

Prerequisites and assumptions

  • Server: Node.js 18+, libsodium or tweetnacl bindings, TLS and KMS (AWS KMS/GCP KMS/Azure Key Vault).
  • Mobile: Android and iOS SDK integrations (RCS client APIs may be carrier-vendor specific). Use the mobile SDK shipped with your product or the Docsigned mobile library.
  • Providers: RCS gateway account (or CPaaS that supports RCS), Firebase Cloud Messaging (FCM), Apple Push Notification service (APNs), SMS provider (Twilio) with short-code or A2P throughput if needed.

Practical Node.js SDK sample

This example demonstrates: key agreement (X25519), symmetric encryption (AES-GCM), RCS send attempt, push fallback, SMS fallback, and callback signature verification. It’s simplified for clarity — adapt production features: retries, exponential backoff, monitoring, and robust error handling.

Key concepts

  • Ephemeral key agreement: generate an ephemeral server key per message and use recipient public key for ECDH to derive a symmetric key.
  • Encrypt payloads so push or RCS providers can’t read signing URLs or PII.
  • Signed callbacks: server signs callbacks with HMAC or mTLS; mobile signs the confirmation to prove possession of the private key.

Server: Node.js example (simplified)

const sodium = require('libsodium-wrappers');
const fetch = require('node-fetch');
const crypto = require('crypto');

async function encryptForRecipient(recipientPubKeyBase64, plaintext) {
  await sodium.ready;
  const recipientPub = sodium.from_base64(recipientPubKeyBase64, sodium.base64_variants.ORIGINAL);
  // Generate ephemeral X25519 keypair
  const ephKeyPair = sodium.crypto_kx_keypair();
  // Derive shared secret using X25519 (crypto_scalarmult)
  const shared = sodium.crypto_scalarmult(ephKeyPair.privateKey, recipientPub);
  // Derive AES-GCM key via HKDF
  const key = crypto.createHash('sha256').update(Buffer.from(shared)).digest();
  const iv = crypto.randomBytes(12);
  const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
  const ciphertext = Buffer.concat([cipher.update(JSON.stringify(plaintext), 'utf8'), cipher.final()]);
  const tag = cipher.getAuthTag();
  return {
    payload: ciphertext.toString('base64'),
    iv: iv.toString('base64'),
    tag: tag.toString('base64'),
    ephPub: Buffer.from(ephKeyPair.publicKey).toString('base64')
  };
}

async function sendOrFallback(recipient) {
  // Build payload
  const payload = { type: 'sign_request', docId: 'abc-123', url: 'https://sign.docsigned.com/s/abc-123' };

  // Attempt RCS
  try {
    const rcsEncryption = await encryptForRecipient(recipient.rcsPubKey, payload);
    const rcsResponse = await sendRcs(recipient.phone, rcsEncryption); // provider-specific
    if (rcsResponse.ok) return { channel: 'rcs', id: rcsResponse.id };
  } catch (err) {
    console.warn('RCS send failed, falling back', err.message);
  }

  // Attempt Push
  try {
    const pushEncryption = await encryptForRecipient(recipient.devicePubKey, payload);
    const pushResp = await sendPush(recipient.fcmToken, pushEncryption);
    if (pushResp.success) return { channel: 'push', id: pushResp.id };
  } catch (err) {
    console.warn('Push failed, falling back', err.message);
  }

  // SMS fallback (no E2EE typically)
  await sendSms(recipient.phone, `Sign this document: ${payload.url} (Secure link)`);
  return { channel: 'sms' };
}

// Example placeholder functions for provider calls
async function sendRcs(phone, encrypted) { /* call RCS gateway API */ }
async function sendPush(token, encrypted) { /* call FCM/APNs with VAPID/JWT as needed */ }
async function sendSms(phone, text) { /* Twilio or MessageBird */ }

Callback verification (HMAC)

Always verify incoming mobile callbacks. Use an HMAC with a per-tenant shared secret or require mTLS. Example HMAC verification:

function verifyCallback(reqBody, signatureHeader, secret) {
  const computed = crypto.createHmac('sha256', secret).update(JSON.stringify(reqBody)).digest('base64');
  return crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(signatureHeader));
}

Mobile SDK: receiving encrypted messages

Your mobile SDK must:

  • Store a persistent device keypair securely (Android Keystore / iOS Secure Enclave).
  • Accept the ephemeral server public key (ephPub) and perform ECDH to derive symmetric key.
  • Decrypt AES-GCM payload, validate server-signed metadata (timestamp, nonce), and verify integrity.
  • Present signing UI and sign the confirmation with device private key. Send signed callback to server.

Android (Kotlin) pseudocode: decrypt

// Pseudocode - convert to libsodium or Tink
val shared = X25519Agreement(devicePrivate, ephPub)
val key = SHA256(shared)
val plaintext = aesGcmDecrypt(key, base64ToBytes(iv), base64ToBytes(payload), base64ToBytes(tag))

Security note: never export private keys

Keep private keys in hardware-backed key stores. Use device attestation (SafetyNet/Play Integrity, Apple DeviceCheck) to defend against emulators and compromised devices.

Callback security and non-repudiation

For legally robust signing events, you need provenance:

  • Signed callbacks — the mobile device should sign the action with its private key. The server verifies the signature and records the event.
  • Device attestation — include attestation tokens in the callback to show the device is genuine.
  • Audit trail — immutable logs with timestamps, IPs, carrier receipts, provider delivery receipts, and the signed callback. Build those logs into your data pipelines aligned with best practices for ethical data pipelines.

Example: verifying a signed callback

// Server verifies device signature
function verifyDeviceSignature(payload, signatureBase64, devicePubKeyBase64) {
  const verify = crypto.createVerify('SHA256');
  verify.update(JSON.stringify(payload));
  verify.end();
  return verify.verify(Buffer.from(devicePubKeyBase64, 'base64'), Buffer.from(signatureBase64, 'base64'));
}

Rate limiting, batching and retries

Channel providers enforce quotas and carriers may throttle A2P SMS. Implement controls that protect your reputation and maintain deliverability.

  • Per-recipient rate limits: avoid sending multiple sign requests within short windows.
  • Global rate limits: token-bucket or leaky-bucket to shape traffic to providers. See monitoring playbooks like resilient dashboards for alerting on quota exhaustion.
  • Batching: for high-volume use, batch RCS sends when supported by your CPaaS for better throughput and cost.
  • Exponential backoff: on transient 5xx errors and throttling responses; implement jitter.

Simple token-bucket pseudocode

class TokenBucket {
  constructor(capacity, refillPerSecond) { /* ... */ }
  take(tokens=1) { /* returns true if tokens available */ }
}

// Use take() before sending to provider

Operational best practices

  • Monitoring: track delivery success per channel, latency, error codes, and provider-level throttles. Use dashboarding and alerting guidance from operational dashboards.
  • Retries & Idempotency: use idempotency keys for sends and callbacks to safely retry without duplicate actions.
  • Logs & Retention: keep an encrypted audit trail for the retention period required by law and policy; feed logs into ethical pipelines like those described at ethical data pipelines.
  • Secrets Management: store provider credentials and HMAC secrets in KMS; rotate on schedule.

Security considerations (detailed)

  • Encrypt everywhere: payloads should be encrypted end-to-end when possible. If SMS is used, minimize content and deliver a short link to an encrypted web session.
  • Key management: rotate server keys regularly. Keep long-lived device keys in hardware. Consider compliance profiles (FedRAMP / government buyers) referenced in FedRAMP guidance.
  • Replay protection: nonce + timestamp validation on all decrypt and callback operations — this also protects against automated replay attacks and is complementary to predictive detection work like predictive AI for automated attacks.
  • Attestation & fraud detection: verify device attestation and use behavioral risk signals for high-risk signings; vendors and identity stacks are compared in identity verification vendor comparisons.
  • Least privilege: grant CPaaS and provider accounts minimal scopes/tokens necessary for delivery. See security checklists like granting limited privileges for related principles.
  • Legal defensibility: store delivery receipts, signed callbacks, and IP/device metadata to support e-signature validity claims.
Electronic signature enforceability depends on jurisdiction and context. This sample illustrates technical approaches to delivery, encryption, and auditability; it is not legal advice.

Key points:

  • Jurisdictional laws: US (ESIGN, UETA), EU (eIDAS and eIDAS 2.0 developments), and other countries have specific requirements for advanced and qualified electronic signatures. For enterprise and public-sector buyers, review compliance and FedRAMP-like guidance (FedRAMP).
  • SMS is weak authentication: SMS-based signing links may not meet higher evidentiary standards. Use SMS only as a last-resort fallback and combine with additional verification (device attestation, OTP, or authenticated web sessions).
  • Audit trail: maintain immutable records showing intent and consent (signed callbacks, timestamps, delivery receipts, document hashes).
  • Consult counsel: always validate your workflow with legal counsel or compliance specialists for high-value transactions.
  • RCS E2EE adoption will continue expanding in 2026. Expect more carriers to flip encryption switches and for cross-platform compatibility to improve.
  • Push providers will enforce stricter token lifecycles and app attestation checks — plan for token rotation and attestation refresh flows. Firebase-specific guidance is discussed in architecture notes like WebRTC + Firebase migrations.
  • SMS delivery will face ongoing filtering and carrier-level restrictions; keep SMS minimal and monitor sender reputation closely.
  • Regulatory pressure will push for stronger non-repudiation requirements in regulated industries; prepare to support advanced/qualified e-signatures where needed.

Real-world example: outcome we achieved

We implemented this pattern for a mid-sized SaaS vendor in late 2025. By prioritizing encrypted RCS and push, with SMS as fallback, they reduced average signature turnaround from 48 hours to 12 hours — a 75% improvement. Delivery success rose 30% and disputed-signature incidents dropped due to stronger audit trails and device-attested callbacks.

Checklist before production rollout

  1. Provision RCS gateway account and test carriers/regions.
  2. Implement server KMS and rotate keys monthly (or per policy).
  3. Integrate mobile SDK with hardware-backed key storage and attestation.
  4. Require signed callbacks and protect them with HMAC or mTLS.
  5. Set rate limits and alerting for provider quota exhaustion.
  6. Create legal playbook for jurisdiction-specific signature validity checks.
  7. Run end-to-end tests simulating network failures and provider errors.

Advanced strategies

  • Progressive disclosure: for SMS use only an obfuscated tokenized link, validate device ownership on landing page before showing the document.
  • Adaptive delivery: use historical delivery success data to choose channel order per recipient or region.
  • Batch signing windows: gather non-urgent signings and push at off-peak hours to maximize throughput when carriers provide discounted batching.
  • Zero-knowledge delivery: use a server-side envelope and document hash approach to ensure providers never see full document content.

Common pitfalls

  • Relying solely on SMS for high-value signatures.
  • Exposing private keys or ephemeral keys in logs.
  • Skipping device attestation for mobile confirmations.
  • Not storing provider delivery receipts or idempotency keys.

Next steps & call-to-action

Want the complete sample repo with production-ready features (retries, metrics, KMS integration, and mobile SDKs)? Download the Docsigned SDK sample from our GitHub and follow the step-by-step setup guide. For enterprise-grade deployments, schedule a technical consult and we’ll help map the optimal channel strategy for your regions, compliance profile, and signing volumes.

Get the code: visit https://github.com/docsigned/rcs-push-sms-sdk-sample (example repo) or contact sales@docsigned.com to request a sandbox and prototype integration.

Final reminder: Security + Compliance = Trust

Delivering a smooth signing experience is necessary but not sufficient — you must combine secure delivery channels, robust cryptography, device attestation, and a defensible audit trail to build trust and reduce legal risk. Use this SDK pattern as a foundation and adapt it for your jurisdictional and business needs.

Ready to build? Download the SDK, run the samples, and reach out for an integration walkthrough.

Advertisement

Related Topics

#developer#mobile#SDK
d

docsigned

Contributor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

Advertisement
2026-01-25T07:09:59.176Z