Skip to content

SkyflowFoundry/salesforce-integration-reference

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Skyflow — Salesforce Reference Implementation

DISCLAIMER: This repository is provided for reference and exploratory purposes only. The code, configuration, and architecture contained herein are intended to illustrate integration patterns and are not designed, tested, or hardened for production use. Skyflow makes no representations or warranties regarding the suitability, security, or correctness of this implementation for any particular purpose. Use in production environments — or with real sensitive data — is done entirely at your own risk and is strongly discouraged without a thorough independent security review and adaptation to your organization's requirements.

A reference implementation showing how to integrate Skyflow with Salesforce to protect sensitive PII. On record save, PII fields are tokenized into a Skyflow vault before the record is committed to the Salesforce database. Tokens can be detokenized on demand, and the vault can be searched by plaintext value without ever exposing PII in Salesforce.

Latest managed package

Install the latest version into your org with this URL:

https://login.salesforce.com/packaging/installPackage.apexp?p0=04tgK000000DUoHQAW

Package version: Skyflow for Salesforce@1.0.0-9
Package ID: 04tgK000000DUoHQAW

Vault schema

The Skyflow vault schema used by this implementation is included at docs/vault-schema.json. It defines five tables, each holding a single PII field with deterministic tokenization and masked redaction:

Table Field Token type Masked format
first_name first_name Deterministic UUID Joh******
last_name last_name Deterministic UUID Smi******
email email Deterministic FPT ****oe@example.com
phone phone_number Deterministic FPT 0412******
date_of_birth date_of_birth Deterministic FPT **/**/1990

Import the schema via the Skyflow Studio vault import or the Management API.

How it works

Tokenize on insert

When a record is created, a before insert trigger intercepts the plaintext PII, replaces it with a Tokenizing... placeholder in the database row, then queues an async callout that tokenizes each field and writes the resulting tokens back to the record.

sequenceDiagram
    actor User
    participant SF as Salesforce
    participant Trigger as RC_CustomerTrigger<br/>(before insert)
    participant Handler as RC_CustomerTriggerHandler
    participant Skyflow as Skyflow Vault

    User->>SF: Create record with PII fields
    SF->>Trigger: before insert fires
    Trigger->>Handler: onBeforeInsert(newRecords)
    Handler->>Handler: Capture plaintext PII from record
    Handler->>Handler: Replace PII fields with "Tokenizing..." placeholder
    Handler-->>SF: Record committed with placeholder values
    Handler->>Handler: Queue @future(callout=true) tokenizeAsync()

    Note over Handler,Skyflow: Async — runs after DML commit

    loop For each PII field
        Handler->>Skyflow: POST /v1/vaults/{vault_id}/{table}<br/>{"records":[{"fields":{fieldName: value}}],"tokenization":true}
        Skyflow-->>Handler: {"records":[{"tokens":{fieldName: "token-value"}}]}
    end

    Handler->>SF: Update record: set tokens, Tokenized__c = true
    Handler->>User: Custom notification: "Customer Tokenized"
Loading

Detokenize

A user clicks "Reveal" on the record page. The LWC calls an Apex method that reads the stored tokens and exchanges them for plaintext values via the Skyflow detokenize API. A redaction level (PLAIN_TEXT, MASKED, or REDACTED) is passed by the caller.

sequenceDiagram
    actor User
    participant LWC as rcDetokenize LWC
    participant Apex as RC_DetokenizeService
    participant SF as Salesforce DB
    participant Skyflow as Skyflow Vault

    User->>LWC: Click "Reveal" (selects redaction level)
    LWC->>Apex: detokenizeRecord(recordId, redaction)
    Apex->>SF: SOQL — SELECT token fields WHERE Id = recordId
    SF-->>Apex: Record with token values
    Apex->>Skyflow: POST /v1/vaults/{vault_id}/detokenize<br/>{"detokenizationParameters":[{token, redaction}, ...]}
    Skyflow-->>Apex: {"records":[{token, value}, ...]}
    Apex->>Apex: Map tokens → field names
    Apex-->>LWC: {firstName, lastName, email, phone, dateOfBirth}
    LWC-->>User: Display plaintext (or masked) values
Loading

Vault search

A user enters one or more plaintext search terms. For each term the Apex service queries the vault to find matching tokens, then uses those tokens as SOQL filter values to find Salesforce records — no plaintext ever touches the Salesforce database.

sequenceDiagram
    actor User
    participant LWC as rcVaultSearch LWC
    participant Apex as RC_VaultSearch
    participant Skyflow as Skyflow Vault
    participant SF as Salesforce DB

    User->>LWC: Enter search term(s) and submit
    LWC->>Apex: search(firstName, lastName, email, phone, dateOfBirth)

    loop For each non-blank search field
        Apex->>Skyflow: POST /v1/vaults/{vault_id}/{table}/query<br/>{"query":"SELECT skyflow_id FROM {table} WHERE {field} ILIKE '%value%' LIMIT 25"}
        Skyflow-->>Apex: {"records":[{skyflow_id}, ...]}
        Apex->>Skyflow: GET /v1/vaults/{vault_id}/{table}?skyflow_ids=...&tokenization=true
        Skyflow-->>Apex: {"records":[{"tokens":{fieldName: "token"}},...]}
        Apex->>Apex: Collect matching tokens into a Set
    end

    Apex->>SF: SOQL — SELECT ... WHERE Field__c IN :tokens (AND across all searched fields)
    SF-->>Apex: Matching records (token values only)
    Apex-->>LWC: List of matching records
    LWC-->>User: Display results table
Loading

Prerequisites

Configuration required after deployment

1. Update the Named Credential

In Setup > Named Credentials, open Skyflow Retail Vault and update the URL to point to your vault:

https://<YOUR_CLUSTER_ID>.vault.skyflowapis.com/v1/vaults/<YOUR_VAULT_ID>

All Skyflow API calls are made from Apex via Named Credentials, so no Remote Site Setting is required.

2. Update the External Credential (bearer token)

In Setup > Named Credentials > External Credentials, open Skyflow_Retail_Auth and update the Authorization header value:

Bearer <YOUR_SKYFLOW_BEARER_TOKEN>

You can use either a short-lived bearer token or a service account API key. To generate a bearer token from a service account JWT:

curl -X POST https://manage.skyflowapis.com/v1/auth/sa/oauth/token \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer","assertion":"<YOUR_SIGNED_JWT>"}'

Alternatively, create a service account with an API key in Skyflow Studio (Manage Account > Service accounts > Add service account) and use the API key directly as the bearer value.

3. Assign the Permission Set

Assign the Skyflow for Salesforce permission set to any user who needs access.

Via CLI:

sf org assign permset --name Skyflow_for_Salesforce --target-org <your-org-alias>

Via Setup UI:

  1. Go to Setup > Users > Users
  2. Click the user's name
  3. Scroll to the Permission Set Assignments related list and click Edit Assignments
  4. Move Skyflow for Salesforce from Available to Enabled, then click Save

Deploying source with the Salesforce CLI

Install the Salesforce CLI

Full guide: Salesforce CLI Setup Guide

# macOS via Homebrew
brew install sf

# Or download from developer.salesforce.com/tools/salesforce-cli

Authenticate to your org

# Production / Developer Edition
sf org login web --alias my-org

# Sandbox
sf org login web --alias my-sandbox --instance-url https://test.salesforce.com

Deploy source

# Deploy all source
sf project deploy start --target-org my-org

# Deploy using the manifest
sf project deploy start --manifest manifest/package.xml --target-org my-org

# Check deploy status
sf project deploy report --target-org my-org

Useful links

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors