PolicyMap for Salesforce: Technical overview
PolicyMap for Salesforce: Technical overview
PolicyMap for Salesforce allows Salesforce users to integrate location-based data provided by PolicyMap with their Salesforce records and view their records on a mapping application.
Features
- Import PolicyMap data into Salesforce.
- Add the names of containing boundaries, such as a record’s census tract or county, to Salesforce records.
- View PolicyMap data along with Salesforce record data on record pages, in reports, and on a map.
Users
PolicyMap for Salesforce relies on two permissions sets: PolicyMap Admin and PolicyMap User. PolicyMap Admin users may import PolicyMap data into Salesforce. PolicyMap Users may view the data but not import it. Because the data import process requires the ability to update org metadata, we recommend assigning the PolicyMap Admin permission set to a System Administrator user.
Custom Objects
PolicyMap data is imported into a custom object record. This object contains lookup fields to associate the PolicyMap data record with a standard or custom object record. No modifications are ever made to the related record itself.
The custom object that contains PolicyMap data is:
- PolicyMapData__c
Other custom objects:
- PolicyMapScheduledJob__c contains information about scheduled update jobs.
- PolicyMapFieldDetail__c contains additional information about each PolicyMap data field that can’t be accommodated in the field definition.
- PolicyMapDataRequestDetail__c contains information about the content and status of data requests made to PolicyMap. An external id corresponds to request information stored at PolicyMap.
- PolicyMap_Object_Setting__c, list type custom setting, contains the PolicyMap Admin user’s selections of which objects' records to populate with PolicyMap data.
- PolicyMap_Child_Object_Setting__c, list type custom setting, contains the PolicyMap Admin user’s selections of which objects to show PolicyMap data belonging to related records.
- PolicyMap_Util__c, hierarchy type custom setting, contains the line-break characters that the Is Location Changed formula field uses to compare addresses.
Components and Pages
- The PolicyMap Administration and Settings page is a Lightning page that contains the following Admin-only components:
- Set PolicyMap data and geocoding specs is where PolicyMap Admin users specify which object records to retrieve PolicyMap geocode and location data. It is also where they can restore an object’s PolicyMap report type to its default.
- Import and Organize PolicyMap Data is where PolicyMap Admin users choose which PolicyMap data and containing boundaries to import, as well as set the order in which the resulting field data will display on single record pages.
- View data import status is where PolicyMap Admin users can track the status of PolicyMap imports from inception through completion of a Bulk Data Load 2.0 job.
- Set update schedule allows PolicyMap Admin users to schedule automatic PolicyMap data updates for new records and records with changed addresses.
- The PolicyMap Index Card component is a Lightning Web Component available on record pages. The component includes a list of tiles containing PolicyMap data associated with the current record, viewable by both PolicyMap User and PolicyMap Admin users. PolicyMap User users may retrieve PolicyMap data for a single record only.
- The PolicyMap Record Locator component is an Aura Component available on record pages. The component displays a small PolicyMap page in a Canvas app showing the record location, with a link to the PolicyMap map page.
- The PolicyMap page is a Visualforce page containing a full-size PolicyMap page in a Canvas app and Lightning Web Components. Users may view Salesforce record locations on the map alongside PolicyMap data layers and point datasets. Salesforce records for each standard object are limited to 20,000 points for performance and viewability. Filters are available to control which records show on the map.
Report Types
For each object in Settings, the app maintains a custom report type labeled “PolicyMap: [object label] with PolicyMap Data”. The report type joins the object to its PolicyMapData records and has three sections: the object’s name and location fields, PolicyMap Data, and PolicyMap Containing Boundaries.
PolicyMap creates and updates the report types through the Metadata API (see Executing Data Import: External Client App below). Updates are non-destructive: new PolicyMap fields are merged into the existing report type, and customizations made by an admin are kept. Restoring the default report type replaces the report type, discarding customizations.
Platform Events
The app has one custom event channel:
- The PolicyMap Channel contains one channel member: PolicyMapDataImport. Currently, this channel is used for one event: PolicyMap Data Import with one field: Action. Some Lightning Web Components listen for an “update” action, sent via REST API from PolicyMap. Upon “update”, the component refreshes. This is to allow PolicyMap to provide live import status information.
How Salesforce and PolicyMap connect
PolicyMap stores PolicyMap for Salesforce customer org IDs in its database in order to associate each org with the data available to the customer and provide customer-specific features. Only orgs known to PolicyMap have access to any PolicyMap features.
Canvas App: Signed Request
As a post-installation step, System Administrators are instructed to modify the PolicyMap Canvas External Client App policies to “Admin-approved users are pre-authorized”, and to add the PolicyMap Admin and PolicyMap User permission sets.
The PolicyMap page and the Locator components embed a PolicyMap page into Salesforce using the PolicyMap Canvas app, which uses Signed Request authentication. The Canvas’s URL is a PolicyMap endpoint rather than the application page itself. The PolicyMap service parses the signed request and redirects the Canvas page to the application once it has verified that the request came from a PolicyMap customer org.
When users display Salesforce record data on the map, they choose which standard and PolicyMap fields will show. Salesforce publishes these field values, along with the location values, to the canvas as GeoJSON. The PolicyMap application then displays the GeoJSON on the map. This data is not added to PolicyMap’s database or retained in any way.
Requesting Data Import: Named Credential
Salesforce calls the PolicyMap endpoint using a Named Credential. The first time a PolicyMap Admin user launches the PolicyMap Data View and Import component, the component prompts them to complete setup by pressing a button. Completing setup populates the External Credential Principal with Basic Authentication credentials to access PolicyMap endpoints. The function that populates the credentials accesses the values from records of a package-protected custom metadata type. These credential values are not otherwise accessible.
Each callout to PolicyMap includes user and org information retrieved using Apex and passed as POST data. PolicyMap uses the POST data to both deliver a customer-specific response and also to authenticate with Salesforce using JWT (see below). Therefore, the External Credential serves only to gain access to this subsequent identification process and does not provide all that is needed to access PolicyMap data.
PolicyMap_Services endpoint: https://www.policymap.com
The POST data sent with every request:
- User ID
- Org ID
- Login URL
- Org Domain URL
- Package major version
The PolicyMap Admin component initiates the following callout through the Named Credential:
- Get Current Version (
act=ver)
Upon page load, queries PolicyMap for the latest version of the package. This callout serves to both validate the Named Credential, and can be used to notify PolicyMap Admin users that a newer version is available.
The Set PolicyMap data and geocoding specs tab in PolicyMap Admin initiates the following callouts through the Named Credential:
- Create Lookup and Formula Fields (
act=dlt)
Upon creating a new PolicyMap_Object_Setting__c record, notifies PolicyMap to create the necessary lookup field on the PolicyMapData__c object to relate the data records to the selected object’s records as well as formula fields that detect changes in the related record’s location in order to flag stale data records. - Update Report Types (
act=rtu)
After the object settings are saved, a Queueable Apex job sends PolicyMap the names of the report types for all objects in Settings. PolicyMap creates any that are missing and merges the default fields into the rest, keeping admin customizations. - Reset Report Type (
act=rtr)
Upon the user pressing Restore default Report Type for an object, sends PolicyMap the object’s default report type. PolicyMap replaces the org’s report type with it.
The Import and organize PolicyMap data tab in PolicyMap Admin initiates the following callouts through the Named Credential:
- Get Data Layers and Time Frames (
act=ind)
Upon loading the import form, retrieves the data layers and time frames available to the customer. The result populates the Layer and Year combo boxes. - Get Geographies for Data Layer and Time Frame (
act=def&ii=[layer id]&tfi=[time frame id])
Upon selecting a time frame, retrieves the geographies available for the data layer and time frame selected in the Layer and Year combo boxes. The result populates the Geography combo box. - Get Containment Definitions (
act=cd)
Upon loading the import form, retrieves the containing boundary types available to the customer, such as state, county, and census tract. The result populates the containing boundary choices.
The data request batch process initiates following callouts through the Named Credential:
- Initiate Data Request (
act=ic)
Upon beginning the first batch in the data request batch chain, POSTs the data request selections as JSON to PolicyMap, including any containing boundaries and the names of the PolicyMap report types. The result is a request identifier. - Initiate Containment Data Request (
act=cc)
Used instead of Initiate Data Request when the data request contains only containing boundaries and no data layers. - Add Locations to Data Request (
act=il&sfri=[request id])
Upon receiving the request identifier from the previous call, initiates a Batch Apex job to provide record locations to PolicyMap. Each batch POSTs its records' ID, along with location values. No other data from these records is sent to PolicyMap. Location batch data is transmitted to Amazon S3 and subsequently stored in PolicyMap’s database during data compilation, then deleted. - Execute Data Request (
act=ie&sfri=[request id])
Upon batch finished, notifies PolicyMap that the locations are provided, triggering PolicyMap to compile the requested location-based data. - Set Data Request Status (
act=s)
If a batch fails, notifies PolicyMap. The information is then stored to display in the View data import status tab.
The View data import status tab in PolicyMap Admin page initiates the following callouts through the Named Credential:
- Get Data Requests (
act=c)
Upon loading the status table and on subsequent refreshes triggered by the user or platform events, retrieves a list of data requests both in progress and completed. - Get Bulk Data Job Status (
act=j)
Upon loading the status table and on subsequent refreshes triggered by the user or platform events, retrieves the status of Bulk Data Load jobs that were previously in progress. - Delete Data Request (
act=d&sfri=[request id])
Upon user interaction, deletes a data request. If it’s in progress, PolicyMap stops processing it without sending any more data to Salesforce; Bulk Data Load jobs that Salesforce has already received are not cancelled. If it’s completed, it merely removes it from the list. Data already imported is not deleted. - Delete All Completed Data Requests (
act=dc)
Upon user interaction and confirmation, deletes all completed data requests, including failed ones, from the list. Requests in progress and data already imported are not deleted.
The PolicyMap Index Card component initiates the following callouts through the Named Credential:
- Get Single Location Data (
act=si)
Upon user interaction, retrieves location-based data and containing boundaries from PolicyMap to populate existing fields for a single record. This is the only callout that may be initiated by a PolicyMap User. This allows a user to retrieve data for a record that they added themselves.
See full callout documentation at https://documenter.getpostman.com/view/39830323/2sB2qfAz68
Executing Data Import: External Client App
As a post-installation step, System Administrators are instructed to modify the PolicyMap Services External Client App policies to “Admin-approved users are pre-authorized”, and to add the PolicyMap Admin permission set.
The PolicyMap Services External Client App uses JWT authentication to allow the PolicyMap application to make REST API requests to Salesforce. PolicyMap makes the following requests to Salesforce:
- PolicyMap requests user info after JWT authentication.
- Upon creating a new object setting, PolicyMap uses a Composite Tooling API request to create a custom lookup field on the PolicyMapData custom object to relate the data to the object’s records, and formula fields to detect changes in the related record’s location to flag stale data records.
- Since the PolicyMap_User permission set does not have broad read access to the data object (in order to expose related record address in the formula field), PolicyMap sends an Apex REST request for the package to assign field permissions to only those fields that require them.
- Upon compiling data for a location-based data request, PolicyMap uses a Composite Tooling API request to create custom fields on the PolicyMapData custom object to contain the new data, and again sends an Apex REST request to assign the appropriate field permissions to the new fields.
- After creating the custom fields, PolicyMap uses Bulk API 2.0 requests to initiate an ingest job to import the new data into the PolicyMapData custom object.
- When requested, PolicyMap uses Rest API to query the state of specified Bulk API 2.0 jobs.
- Periodically, PolicyMap uses Rest API to send a custom Platform Event to trigger a refresh of Lightning Web components.
The data import process
When a user completes the form to import PolicyMap data into Salesforce, this process is initiated:
- Salesforce initiates a chain of Apex Batch jobs that queries the specified records for Id and Address and sends this data to PolicyMap. Upon starting the first job in the chain, Salesforce sends PolicyMap an object containing the PolicyMap data specifications. PolicyMap sends back a Request Id to use throughout the batch chain.
- PolicyMap compiles the selected location-based data for each record into CSV format. Each row represents a new or updated PolicyMapData custom object:
Name, ExtId, [standard object api name]__c, [PolicyMap data field name], …
Name, ExtId, and [standard object api name]__c each contain the original record id. The rest of the row is comprised of the lookup field values, PolicyMap location and data field values. - PolicyMap sends a Composite Tooling API request to create the new fields and an Apex REST request to trigger assignment of the appropriate field permissions.
- PolicyMap sends Bulk API 2.0 ingest requests to import the data into the appropriate PolicyMapData custom object.
What PolicyMap receives and what it keeps
PolicyMap for Salesforce sends two very different kinds of information to PolicyMap:
- Your record data: values from your organization’s Salesforce records, such as record IDs, addresses, and any fields users choose to show on the map.
- App system data: information the app needs to run, such as your org ID, the history of your data requests, and the names of objects and fields involved.
A third, smaller group is information that identifies the Salesforce users who use the app.
For each item below, the table says how PolicyMap handles it. There are five possibilities:
- Map display only: shown on the PolicyMap map inside Salesforce. PolicyMap’s servers don’t use it, and it’s not stored.
- Used, not stored: PolicyMap’s servers use it to complete a request, then discard it.
- Stored temporarily: stored only while PolicyMap processes a request, then deleted.
- Kept until you delete it: stored until a PolicyMap Admin user deletes it in the app.
- Kept: stored for as long as your organization uses PolicyMap.
Your record data
Data | When it’s sent | How PolicyMap handles it |
Record IDs, with each record’s address or coordinates | During a data import or scheduled update | Stored temporarily. Stored while PolicyMap compiles the requested data, then deleted. No other values from these records are sent. |
A single record’s ID and address or coordinates | When a user retrieves data for one record on the PolicyMap Index Card | Used, not stored. |
Geocoded coordinates and addresses PolicyMap produces for your records | Returned to Salesforce with imported data | Used, not stored. Saved in your org on PolicyMapData records. PolicyMap doesn’t keep a copy. |
Record locations and the field values users choose to show on the map | When a user displays records on the PolicyMap page | Map display only. Up to 20,000 records per object. The map shows only records and fields the user already has access to in Salesforce. |
Filter criteria, including the values users enter (for example, “Owner equals Jane Smith”) | When a user filters records on the PolicyMap page | Map display only. |
A record’s name and its address or coordinates | When a record page with the PolicyMap Record Locator loads | Map display only. |
App system data
Data | When it’s sent | How PolicyMap handles it |
Org ID | With every request | Used, not stored. Compared with the org ID your organization gave PolicyMap at purchase, which PolicyMap keeps to identify you as a customer. |
Org domain URL, login URL, and package version | With every request | Used, not stored. |
Data request history: the data selected, the request name and description, when it was created and finished, and its status | During a data import or scheduled update | Kept until you delete it. Shown on the View data import status tab, where a PolicyMap Admin user can delete it. Deleting a request doesn’t delete data already imported. |
Error details for failed data requests | When a data import fails | Kept until you delete it, along with the request. |
Bulk API job IDs | When the View data import status tab checks on an import | Used, not stored. |
Names and labels of the objects and fields in your PolicyMap settings, and the formulas the app creates | When a PolicyMap Admin user saves settings | Used, not stored. Used to create fields in your org. |
Your PolicyMap report types, including any changes your admins have made | Read from your org when PolicyMap updates report types | Used, not stored. Used to add new fields to the report types without losing your changes. |
Information about your Salesforce users
Data | When it’s sent | How PolicyMap handles it |
The Salesforce username of the user making the request | With every request. For scheduled updates, this is the user who scheduled them. | Used, not stored. Used to connect to your org as that user. |
A standard bundle of user and org details that Salesforce sends to any embedded (Canvas) app. It includes the org ID, the org name, the user's name, email address, locale and time zone, and a limited-access token. PolicyMap can't choose what Salesforce includes. | When a user opens the PolicyMap page or a record page with the PolicyMap Record Locator | Used, not stored. PolicyMap uses only the org ID, to confirm your organization is a PolicyMap customer. Everything else in the bundle is ignored. |
The PolicyMap map loads directly from https://www.policymap.com in the user's browser. Like any website, PolicyMap receives standard web traffic information, such as IP address and browser type, as described in the Privacy Policy.
Appendix: PolicyMap’s security certifications
HIPAA
PolicyMap is certified for the U.S. Health Insurance Portability and Accountability Act of 1996 (HIPAA), enabling staff, customers, and users of the application a secure environment to process, transmit, maintain, and store protected health information (PHI). PolicyMap achieved its first HIPAA compliance in 2020, and it has been renewed each subsequent year.
PCI DSS (tests conducting by Security Metrics)
Payment Card Industry Data Security Standard (PCI DSS) is a proprietary information security standard administered by the PCI Security Standards Council. The compliance is designed to protect businesses and their customers against payment card theft and fraud, and the quarterly testing process monitors and reports on site vulnerabilities. PolicyMap first achieved PCI DSS compliance in 2011, and it has been renewed each quarter of each subsequent year.
Penetration Test (test conducted by Security Metrics)
In May 2024 a penetration test was conducted on the PolicyMap PolicyMap SaaS Product to simulate a cyberattack and identify security vulnerabilities in the application. The test employed the same tools and techniques used by malicious actors and provided a thorough evaluation of the application’s security protections. The application passed the test with no vulnerabilities exposed.