# Salesforce-to-Portal Security Integration Guide Note: 2025 update — Salesforce → Portal order provisioning is now event-driven via Platform Events. This document reflects the event-driven model. ## Overview This guide outlines secure patterns for **Salesforce-to-Portal communication** specifically for the **order provisioning workflow**. Based on your architecture, this focuses on order status updates, not invoice handling. ## Order Provisioning Flow (Async Preferred) ``` Portal Customer → Places Order → Salesforce Order (Pending Review) ↓ Salesforce Operator → Reviews/Approves Order ↓ Salesforce Flow → Publishes OrderProvisionRequested__e ↓ Portal BFF Subscriber → Provisions in WHMCS → Updates Salesforce Order Status ↓ Portal → Polls Order Status → Shows Customer Updates ``` ## 1. Secure Order Provisioning Communication ### Primary Method: Platform Events (Recommended) Use a Record-Triggered Flow to publish `OrderProvisionRequested__e`. The portal subscribes via the Salesforce Streaming API (Pub/Sub) and provisions asynchronously. Inbound webhooks from Salesforce are no longer required. If you still need synchronous HTTP for another use case, prefer OAuth2 Named/External Credential and avoid custom signature schemes. ### Secure Salesforce Quick Action Setup (Legacy) Legacy Quick Action + webhook details removed (use Platform Events). 2. **Apex Class for Secure Webhook Calls** // Your current pattern in salesforce-connection.service.ts // Uses private key JWT authentication - industry standard ``` ### Enhanced Patterns for Sensitive Operations For highly sensitive operations, consider adding: ```typescript @Injectable() export class SecureSalesforceService { async createSensitiveRecord(data: SensitiveData, idempotencyKey: string) { // 1. Encrypt sensitive fields before sending const encryptedData = this.encryptSensitiveFields(data); // 2. Add idempotency protection const headers = { 'Idempotency-Key': idempotencyKey, 'X-Request-ID': uuidv4(), }; // 3. Use your existing secure connection return await this.salesforceConnection.create(encryptedData, headers); } private encryptSensitiveFields(data: any): any { // Encrypt PII fields before transmission const sensitiveFields = ['ssn', 'creditCard', 'personalId']; // Implementation depends on your encryption strategy } } ``` ## 3. Data Protection Guidelines ### Sensitive Data Handling ```typescript // Example: Secure order processing export class SecureOrderService { async processOrderApproval(orderData: OrderApprovalData) { // 1. Validate customer permissions await this.validateCustomerAccess(orderData.customerNumber); // 2. Sanitize data for logging const sanitizedData = this.sanitizeForLogging(orderData); this.logger.log('Processing order approval', sanitizedData); // 3. Process with minimal data exposure const result = await this.processOrder(orderData); // 4. Audit trail without sensitive data await this.createAuditLog({ action: 'order_approved', customerNumber: orderData.customerNumber, orderId: orderData.orderId, timestamp: new Date(), // No sensitive payment or personal data }); return result; } private sanitizeForLogging(data: any): any { // Remove or mask sensitive fields for logging const { creditCard, ssn, ...safeData } = data; return { ...safeData, creditCard: creditCard ? '****' + creditCard.slice(-4) : undefined, ssn: ssn ? '***-**-' + ssn.slice(-4) : undefined, }; } } ``` ### Field-Level Security ```typescript // Implement field-level encryption for highly sensitive data export class FieldEncryptionService { private readonly algorithm = 'aes-256-gcm'; private readonly keyDerivation = 'pbkdf2'; async encryptField(value: string, fieldType: string): Promise { const key = await this.deriveKey(fieldType); const iv = crypto.randomBytes(16); const cipher = crypto.createCipher(this.algorithm, key); let encrypted = cipher.update(value, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { value: encrypted, iv: iv.toString('hex'), tag: cipher.getAuthTag().toString('hex'), }; } async decryptField(encryptedField: EncryptedField, fieldType: string): Promise { const key = await this.deriveKey(fieldType); const decipher = crypto.createDecipher(this.algorithm, key); decipher.setAuthTag(Buffer.from(encryptedField.tag, 'hex')); let decrypted = decipher.update(encryptedField.value, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } } ``` ## 4. Implementation Checklist ### Salesforce Setup - [ ] Create Platform Events for portal notifications - [ ] Configure IP allowlisting for portal endpoints - [ ] Create audit trails for all portal communications ### Portal Setup - [ ] Add IP allowlisting for Salesforce - [ ] Create encrypted payload handling - [ ] Implement idempotency protection ### Security Measures - [ ] Implement rate limiting per customer - [ ] Add comprehensive audit logging - [ ] Test disaster recovery procedures ## 5. Monitoring and Alerting ```typescript @Injectable() export class SecurityMonitoringService { async monitorWebhookSecurity(request: Request, response: any) { const metrics = { sourceIp: request.ip, userAgent: request.headers['user-agent'], timestamp: new Date(), success: response.success, processingTime: response.processingTime, }; // Alert on suspicious patterns if (this.detectSuspiciousActivity(metrics)) { await this.sendSecurityAlert(metrics); } // Log for audit this.logger.log('Webhook security metrics', metrics); } private detectSuspiciousActivity(metrics: any): boolean { // Implement your security detection logic // - Too many requests from same IP // - Unusual timing patterns // - Failed authentication attempts return false; } } ``` ## 7. Production Deployment ### Environment Variables ```bash # Platform Events SF_EVENTS_ENABLED=true SF_PROVISION_EVENT_CHANNEL=/event/OrderProvisionRequested__e SF_EVENTS_REPLAY=LATEST # Encryption FIELD_ENCRYPTION_KEY=your_field_encryption_master_key ENCRYPTION_KEY_ROTATION_DAYS=90 # Monitoring SECURITY_ALERT_WEBHOOK=https://your-monitoring-service.com/alerts AUDIT_LOG_RETENTION_DAYS=2555 # 7 years for compliance ``` ### Salesforce Named Credential Setup Not required for the event-driven provisioning path (the portal pulls events). This guide provides a comprehensive, production-ready approach to secure Salesforce-Portal integration that builds on your existing security infrastructure while adding enterprise-grade protection for sensitive data transmission.