Overview
The Salesforce integration adds a native SparkVault Files panel to every Account, Contact, Opportunity, and Case record page in your org. Files uploaded from a record are encrypted via Forge with AES-256-GCM, stored as ingots in the SparkVault vault you choose at install time, and organized automatically into a dedicated folder per CRM record. Salesforce never holds the file contents, only the panel.
Key Features
- SparkVault Files panel on CRM records: native Lightning panel on Account, Contact, Opportunity, and Case pages
- Triple Zero-Trust encryption via Forge: files encrypted with AES-256-GCM using keys derived from your vault's key hierarchy
- Folder-per-record organization: files auto-organized by CRM object type and record ID, no manual folder management
- Vault unseal via VMK or DVAK: each user unlocks the vault with their own key
- Upload, download, and delete from Salesforce: manage record files without leaving the CRM
Your vault is sealed with a key that only you hold. The panel uses it to unlock the vault for the current session, then discards it. The key is never written to disk or stored on SparkVault servers. Once the vault is sealed, not even SparkVault can read your files, and Salesforce never stores the file bytes at all.
How It Works
User Flow
- A user opens an Account, Contact, Opportunity, or Case, and the SparkVault Files panel loads on the record page
- The panel resolves the record to its vault and deterministic folder (e.g.
Accounts/001xx000003DGbzAAG) - If the vault is sealed for this user, the panel prompts them to unlock it with their VMK or DVAK
- Once unsealed, files attached to the record are listed in a native Lightning datatable with download and delete actions
- Uploads open the embedded SparkVault upload widget in an in-panel modal; files are encrypted via Forge before storage
- Downloads open a signed Forge URL; the file streams directly from Forge to the user's browser
Folder Organization
Every record maps to one vault folder, named by object type and record ID. Folders are created lazily on first upload, so records without files add nothing to your vault.
| Record type | Vault folder |
|---|---|
| Account | Accounts/{recordId} |
| Contact | Contacts/{recordId} |
| Opportunity | Opportunities/{recordId} |
| Case | Cases/{recordId} |
Installation
Installation has two halves: the SparkVault managed package inside your Salesforce org, and the OAuth connection that binds the org to your SparkVault account and a vault you own.
In Salesforce
- Install the SparkVault managed package in your org
- Assign the SparkVault User permission set to users who need the Files panel
- Add the SparkVault Files panel to Account, Contact, Opportunity, and Case record pages via Lightning App Builder
In SparkVault
- Sign in and open Integrations in the SparkVault dashboard
- Click "Connect Salesforce"; you are redirected to Salesforce to authorize the connection (only the
openidscope is requested) - Choose which vault Salesforce CRM files will be stored in; the vault must belong to you, which SparkVault verifies server-side
- You are redirected back to SparkVault with the installation confirmed, and the panel becomes active for your org
The integration requests only the openid OAuth scope. SparkVault uses OAuth solely to
bind your Salesforce org ID and instance URL to your account. Salesforce access and refresh tokens
are not retained after installation. Every subsequent panel request is authorized by the calling
user's own Salesforce session instead.
Refreshing the Connection
If the connection needs to be re-authorized (for example after the panel reports "Reconnect SparkVault"), use Refresh Connection on the Integrations page. Re-authorization keeps the bound vault and must target the same Salesforce org; connecting a different org is rejected with "Disconnect first to connect a new org" so the original org-to-account mapping is never silently orphaned.
Connect SalesforceUsing the Files Panel
The panel is a native Lightning Web Component: no iframes for browsing, no third-party UI. It lists each file's name, size, and upload date with per-row Download and Delete actions.
Unsealing the Vault
A sealed vault shows an unlock prompt. The user enters their Vault Master Key (VMK) or a Delegated Vault Access Key (DVAK); the key unlocks the vault for the session and is then discarded. It is never saved in the browser or stored on SparkVault servers. Each Salesforce user unseals for themselves: one user's unlocked session is never shared with the rest of the org, and vault sessions expire after one hour, after which the panel prompts for the key again.
Uploading
Upload opens the embedded SparkVault upload widget in an in-panel modal. The vault and folder ride
in the widget URL, while the short-lived vault access token is handed to the widget via
postMessage, never in a URL. Files stream to Forge and are encrypted before storage;
when the upload completes, the panel refreshes the file list automatically.
Panel States
| State | Meaning | Resolution |
|---|---|---|
| Vault locked | No live vault session for this Salesforce user | Enter your VMK or DVAK to unseal |
| Reconnect SparkVault | The stored SparkVault connection can no longer be refreshed | A SparkVault admin uses Refresh Connection on the Integrations page |
| Subscription required | The SparkVault account has no active plan | Subscribe in SparkVault billing |
| Capacity exhausted | A pooled limit (storage, bandwidth, seats, or identity) is used up, blocking the gated operation: storage exhaustion blocks uploads | Add capacity in SparkVault billing |
The subscription and capacity states show an actionable billing link only to Salesforce administrators (users with the Customize Application permission). Standard users are never shown an action they cannot take.
Security Model
-
Caller authentication (session bearer verified against the installed org): every
panel request carries the current Salesforce user's session bearer token. SparkVault validates
that token against the installed org's own
/services/oauth2/userinfoendpoint and rejects the request unless the returned organization ID matches the installation. The org ID in the request body identifies the tenant but is never trusted as authentication. - Record-level access checks: before listing, uploading, downloading, or deleting, SparkVault confirms the calling user can actually see the record by querying Salesforce with the user's own session. Object types are allow-listed (Account, Contact, Opportunity, Case) and record IDs must match the strict 15/18-character Salesforce ID format, re-validated at the query site. The packaged Apex controller additionally performs user-mode record checks before any callout.
- Per-user vault sessions: unsealing mints a Vault Access Token stored per verified Salesforce user. A user who has not unsealed the vault cannot reuse another user's unlocked session.
- Per-record isolation: download and delete verify that the requested file actually lives in that record's folder. A file ID alone is never sufficient to reach a file attached to a different record.
- Vault ownership verified at install: the OAuth callback re-checks the selected vault against the installing user's own SparkVault session, so an installation can never bind to someone else's vault.
- Keys are never stored: the VMK or DVAK is used to unseal and then discarded: not written to disk, not stored on SparkVault servers, not saved in the browser.
-
No Salesforce tokens retained: after the
openid-scoped OAuth exchange, SparkVault keeps the org ID, instance URL, bound vault, and its own SparkVault credential for the account: no Salesforce access or refresh tokens. - Direct Forge streaming: file bytes stream between the browser and Forge. They are never proxied through the panel, the Apex controller, or Salesforce.
-
Explicit CSP allow list: the managed package trusts exactly
api.sparkvault.com,app.sparkvault.com, andfiles.sv, no wildcard domains.
API Endpoints
The integration is installed and managed from the SparkVault dashboard, and the Files panel talks to SparkVault on your behalf. The one endpoint you may want to call programmatically is uninstall.
/v1/apps/salesforce/uninstall
Disconnect Salesforce from your SparkVault account. Removes the installation; the Files panel stops working in your org. Authenticate with either a session JWT (Authorization: Bearer) or an API key (X-API-Key).
# Authenticate with a session JWT...
curl -X DELETE 'https://api.sparkvault.com/v1/apps/salesforce/uninstall' \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# ...or with an API key
curl -X DELETE 'https://api.sparkvault.com/v1/apps/salesforce/uninstall' \
-H "X-API-Key: YOUR_API_KEY"
{
"uninstalled": true,
"account_id": "acc_1234567890",
"org_id": "00Dxx0000001gPLEAY"
}
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR |
Salesforce is not installed for this account. |
| 401 | AUTHENTICATION_ERROR |
Missing or invalid credentials. |
Internal Endpoints
The following endpoints are called by the SparkVault Files panel (through its Apex controller) and by the SparkVault dashboard during installation. They are documented here for transparency but are not intended to be called directly by your application.
| Endpoint | Purpose | Auth |
|---|---|---|
POST /v1/apps/salesforce/resolve |
Map a CRM record to its vault and folder path | Salesforce session bearer + record access |
POST /v1/apps/salesforce/files |
List files attached to a CRM record | Salesforce session bearer + record access |
POST /v1/apps/salesforce/upload-context |
Vault, folder, and vault access token for the embedded upload widget | Salesforce session bearer + record access |
POST /v1/apps/salesforce/unseal |
Unseal the bound vault with a VMK or DVAK | Salesforce session bearer |
POST /v1/apps/salesforce/download |
Mint a signed Forge URL for direct file download | Salesforce session bearer + record access |
POST /v1/apps/salesforce/delete-file |
Delete a record-bound file from the vault | Salesforce session bearer + record access |
POST /v1/apps/salesforce/oauth/callback |
OAuth code exchange and vault selection during install | SparkVault JWT |
POST /v1/apps/salesforce/webhooks |
Salesforce lifecycle events (app.uninstall) |
Salesforce session bearer |
Salesforce does not sign outbound calls with an HMAC the way Slack or HubSpot do. Panel calls and webhooks instead authenticate with a Salesforce session bearer token, which SparkVault validates against the installed org before acting. See the Security Model above.
Uninstall Behavior
There are two ways to disconnect, and both end at the same place:
-
From SparkVault: click Disconnect on the
Integrations page, or call
DELETE /v1/apps/salesforce/uninstall. - From Salesforce: uninstalling the managed package notifies SparkVault via a session-verified webhook, which removes the installation.
Uninstalling removes the connection between your Salesforce org and your SparkVault account, and the SparkVault Files panel disappears from CRM records. Your files are not deleted. They remain encrypted in your vault under their per-record folders and stay accessible from the SparkVault app. The Salesforce-side uninstall notification is best-effort: if Salesforce cannot deliver it during package removal, disconnect from the SparkVault Integrations page instead.
Pricing
Free to install. Standard vault storage and transfer pricing applies. The integration itself adds no per-file or per-seat charge.
Best Practices
- Use a dedicated vault for CRM files: binding the integration to its own vault keeps access, capacity, and audit review simple, and disconnecting never touches your other vaults.
- Issue DVAKs instead of sharing the VMK: give each team member a Delegated Vault Access Key so they unseal with their own revocable credential rather than the vault's master key.
- Expect re-unseal after an hour: vault sessions are deliberately short-lived; the panel will prompt for the key again once a session expires.
- Scope the permission set: assign the SparkVault User permission set only to users who need the Files panel. Record-level checks still apply, but least privilege starts in Salesforce.
Get Started
Connect your Salesforce org and put encrypted file storage on every CRM record.