Assist_Design/docs/SALESFORCE-PORTAL-SECURITY-GUIDE.md
T. Narantuya f305ee6e1a Implement Salesforce Platform Events for Order Provisioning
- Added support for Salesforce Platform Events, specifically subscribing to `OrderProvisionRequested__e` to trigger provisioning jobs.
- Introduced new environment variables for Salesforce event configuration, including SF_EVENTS_ENABLED, SF_PROVISION_EVENT_CHANNEL, and SF_PUBSUB_ENDPOINT.
- Refactored order fulfillment process to utilize event-driven architecture, enhancing reliability and scalability.
- Updated documentation to reflect changes in the provisioning workflow and environment variable requirements.
- Removed deprecated webhook handling code to streamline the integration.
2025-09-06 10:01:44 +09:00

6.9 KiB

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

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).

  1. 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

// 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

// 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<EncryptedField> {
    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<string> {
    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

@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

# 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.