This document explains how HappySoup is architected and how we protect customer data. It is intended both for Salesforce’s AppExchange security review and for customers who want transparency into our security practices.
Architecture Diagram
The diagram below shows the high-level architecture of HappySoup and the flow of data between its core services.
Executive Summary
HappySoup only stores the minimum information needed to function. We do not store Salesforce passwords, refresh tokens, or metadata contents. Tokens are short-lived, encrypted, and automatically expire after two hours.
The table below summarizes the data we handle, where it is stored, how it is protected, and how long it is retained.
Data Type | Location | Protection | Retention | Notes |
Salesforce access token | Redis (Heroku) | AES-256-GCM encryption, TLS in transit | 2 hours (auto-expire) | No refresh tokens stored |
Session metadata (user/org ID, cache) | Redis (Heroku) | TLS in transit | 2 hours (auto-expire) | Deleted on logout |
Usage statistics (e.g. job counts, org size, # of Apex classes) | MongoDB Atlas | Encrypted at rest, TLS in transit | Retained indefinitely unless deletion requested under GDPR | Never includes metadata contents |
Customer identifiers (e.g. email, org ID) | MongoDB Atlas | Encrypted at rest, TLS in transit | Retained until deletion requested | Limited to identifiers, no credentials |
Together with the data we handle, it is also important to understand the core services that make up HappySoup’s architecture. The table below lists each major service or node, its purpose, and the key security considerations.
Service / Node | Purpose | Security Notes |
Vercel | Hosts the frontend at | TLS enforced on all connections |
Heroku (Dynos) | Hosts the backend API at | TLS enforced on all endpoints, MFA required for admin access |
Heroku Redis (Key-Value) | Stores short-lived encrypted sessions and access tokens | TLS enforced, 2h TTL, AES-256-GCM encryption |
MongoDB Atlas | Stores usage statistics and customer identifiers | Encryption at rest, TLS in transit, GDPR deletion rights |
Salesforce | Provides authentication and source data via OAuth 2.0 APIs | Tokens expire after 2 hours, minimal scopes requested |
Papertrail (Heroku add-on) | Centralized logging and monitoring | No tokens or sensitive user data logged |
Data Flow and Services
The following sections describe each part of the HappySoup architecture in more detail, following the flow of data through the system and the services involved.
Frontend Hosting
The app is served at https://web.happysoup.io/ through Vercel hosting. All connections are encrypted with TLS. The frontend communicates with the backend API at https://api.happysoup.io/.
Backend Hosting
Our API server is hosted on Heroku web dynos at https://api.happysoup.io/. We use Heroku’s recommended web and worker architecture. TLS is enforced on all endpoints by Heroku.
Authentication
HappySoup does not create its own identity system or store Salesforce passwords. Users log in with their Salesforce org using the standard OAuth 2.0 web-server flow, similar to Salesforce Workbench or the Salesforce CLI.
Our Salesforce Connected App requests only three scopes:
api
web
id
We do not request the refresh_token
scope. This means we never store long-lived credentials that could provide ongoing access to a Salesforce org. Instead, HappySoup only uses short-lived access tokens issued by Salesforce, which automatically expire after two hours.
Stored tokens are encrypted using AES-256-GCM with a unique initialization vector for each token. Encryption keys are stored as Heroku config vars, which are encrypted at rest and protected by multi-factor authentication. Tokens are decrypted in memory only when needed to make an API call, and never logged or backed up.
This approach combines limited scopes, short token lifetimes, and strong encryption to minimize the risk of unauthorized access.
Cookies and Session Management
When the OAuth flow completes, we create a server-side session stored on Heroku Key-Value (formerly Redis). All connections to Redis use TLS.
The session contains the encrypted access token, information about the logged-in user, and cached metadata for performance. To link browser requests with this session, we use secure HTTP cookies. Sessions expire after two hours, in line with Salesforce’s token lifecycle, and are destroyed when a user logs out.
Salesforce API Access
HappySoup interacts with Salesforce using standard SOAP, REST, and Tooling APIs. Access is always limited to the permissions of the authenticated user: if the user cannot access a certain object or metadata type in Salesforce, neither can HappySoup.
Tokens are decrypted only in memory when calling the Salesforce API. Results of some API calls are cached in Redis to improve performance and reduce API traffic.
Usage Statistics
We collect high-level usage statistics, such as the number of jobs performed and Salesforce org characteristics (e.g., number of users, number of Apex classes). This data helps us understand usage patterns and improve performance.
Usage statistics are stored in MongoDB Atlas, which provides encryption at rest and strict access controls. This data is retained indefinitely unless a customer exercises their deletion rights under GDPR or other applicable laws. We do not store customer metadata contents such as Apex code or field names. Details on data rights are provided in our Privacy Policy.
Access Controls
Only the CTO has access to production systems, which are protected by multi-factor authentication. Access follows the principle of least privilege.
Monitoring and Logging
Application logs are collected through Papertrail, a managed Heroku add-on. Logs are high-level and exclude user identifiers and access tokens. Logging is used to monitor system health and errors, not user activity.
Sub-Processors
HappySoup uses a small number of trusted infrastructure providers, including Vercel, Heroku, and MongoDB Atlas. The full and current list of sub-processors is published here: HappySoup Sub-Processors.