A macOS menu bar application for backing up cloud data to Amazon S3:
- Google Workspace: Backup Takeout data from Google Cloud Storage
- Salesforce: Backup selected objects using Bulk API 2.0 with daily scheduling
- Menu Bar App: Lives in your menu bar for easy access
- Multiple Platforms: Support for Google Workspace and Salesforce
- Incremental Sync: Only transfers new or changed files (GCS)
- Bulk API 2.0: Efficient Salesforce data export using the Bulk API
- Object Selection: Choose which Salesforce objects to backup
- Daily Scheduling: Automatic daily Salesforce backups via launchd
- Progress Tracking: Real-time progress with transfer speeds and ETA
- macOS Notifications: Get notified when backups complete or fail
- Secure Credentials: All credentials stored in macOS Keychain
- Backup History: Track all backup operations
- macOS 13.0 (Ventura) or later
- Xcode 15.0 or later
- For Google Workspace: Google Cloud Service Account with Storage Object Viewer permissions
- For Salesforce: Connected App with OAuth enabled
- AWS IAM credentials with S3 write permissions
./build.shThis creates GWS Backup.app ready to use.
swift build -c release- Go to Google Cloud Console
- Create or select a project
- Enable the Cloud Storage API
- Create a Service Account with "Storage Object Viewer" role
- Download the JSON key
- In app Settings > Google Cloud:
- Import the service account JSON file
- Enter your GCS bucket name
-
Create a Connected App in Salesforce Setup:
- Go to Setup > App Manager > New Connected App
- Enable OAuth Settings
- Set Callback URL to:
gwsbackup://oauth/callback - Select OAuth Scopes:
api(Access and manage your data)refresh_token, offline_access(Perform requests at any time)
- Save and wait for activation (can take 2-10 minutes)
-
Get your credentials:
- Consumer Key (Client ID)
- Consumer Secret (Client Secret)
-
In app Settings > Salesforce:
- Enter Client ID and Client Secret
- Click "Connect to Salesforce" to authenticate
- Select which objects to backup
- Configure S3 destination bucket
- Optionally enable daily scheduling
- Go to AWS IAM Console
- Create a new IAM user with programmatic access
- Attach a policy allowing S3 access:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket", "s3:HeadObject" ], "Resource": [ "arn:aws:s3:::your-gcs-backup-bucket", "arn:aws:s3:::your-gcs-backup-bucket/*", "arn:aws:s3:::your-salesforce-backup-bucket", "arn:aws:s3:::your-salesforce-backup-bucket/*" ] } ] } - In app Settings > AWS S3:
- Enter your Access Key ID and Secret Access Key
Click the cloud icon in your menu bar to:
- See status of both Google Workspace and Salesforce backups
- Start manual backups for either platform
- View scheduled backup information
- Access Settings
- Configure GCS and S3 credentials
- Click "Backup Now" under Google Workspace
- The app compares files and only transfers new/changed ones
- Configure Salesforce Connected App credentials
- Connect to Salesforce via OAuth
- Select objects to backup (standard and custom objects)
- Configure S3 destination bucket
- Click "Backup Now" or enable daily scheduling
Enable automatic daily Salesforce backups:
- Go to Settings > Salesforce
- Toggle "Enable daily automatic backup"
- Set the time for the backup to run
- The app installs a launchd agent to run backups automatically
Files are synced to S3 maintaining the same structure as in GCS.
Each backup creates a timestamped folder containing:
- CSV files for each selected object (all fields)
_manifest.jsonwith backup metadata
Example structure:
salesforce-backup/
2025-01-22_02-00-00/
Account.csv
Contact.csv
Opportunity.csv
CustomObject__c.csv
_manifest.json
Make sure you've set up all required credentials in Settings.
- Verify the callback URL is exactly:
gwsbackup://oauth/callback - Wait 2-10 minutes after creating the Connected App
- Check that the Connected App has the required OAuth scopes
- Verify the app is installed in /Applications or your home directory
- Check
~/Library/Logs/GWSBackup-scheduler.logfor errors - Run
launchctl list | grep gwsbackupto verify the agent is loaded
The app uses Bulk API 2.0 which handles large datasets efficiently. For very large objects, backups may take longer but should complete.
This app implements several security best practices:
- Keychain Storage: All sensitive credentials (AWS keys, GCS service account JSON, Salesforce OAuth tokens) are stored in the macOS Keychain, not in files
- PKCE OAuth: Salesforce authentication uses Proof Key for Code Exchange (PKCE) for enhanced security
- No Hardcoded Secrets: The app contains no hardcoded API keys or credentials
- Secure Input: Password fields use SecureField components
- Token Refresh: OAuth tokens are automatically refreshed before expiry
- Memory Clearing: Sensitive values are cleared from memory after use
| Service | Required Credentials |
|---|---|
| Google Cloud | Service Account JSON key file |
| Salesforce | OAuth Client ID & Secret (from Connected App) |
| AWS | IAM Access Key ID & Secret Access Key |
All credentials are entered through the app's Settings UI and stored securely in macOS Keychain.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - See LICENSE file for details