Skip to main content

Security Overview

Product: Keelstone Actions
Publisher: Keelstone
Contact: security@keelstone.dev
Document version: 1.3
Last updated: April 2026


Executive Summary

Keelstone Actions is a Salesforce managed package that enables Salesforce Screen Flows to read and write Microsoft Office documents (Excel, Word, PowerPoint) and Google Workspace documents (Sheets, Docs, Slides) through a cloud relay architecture. This document describes the security design, data handling practices, authentication model, and compliance posture of the Keelstone platform for the benefit of Salesforce security reviewers, enterprise security teams, and IT administrators evaluating the product.

Key security properties:

  • No Salesforce data is stored by Keelstone. The relay service acts as a stateless command broker. Salesforce data passes through in transit only and is never persisted outside Salesforce.
  • All traffic is encrypted. Every connection between components uses TLS 1.2 or higher. No plaintext endpoints exist.
  • Salesforce credentials are never sent to Keelstone servers. Authentication uses Salesforce-issued OAuth 2.0 access tokens obtained via PKCE. Keelstone never sees or stores usernames or passwords.
  • All Apex code runs with sharing enforced. Every Apex class uses with sharing and checks field-level security before data access.
  • The relay session is short-lived and scoped. Each Keelstone session ID is a random UUID tied to a single user and invalidated on logout.

Architecture Overview

Keelstone has three components:

Salesforce Org
Contains the managed package (kstone namespace). Apex invocable actions run inside the customer's org, under the customer's Salesforce security model (profiles, permission sets, field-level security, sharing rules). No data leaves Salesforce except the specific values passed by the admin-controlled Flow.

Keelstone Cloud (app.keelstone.dev)
A cloud-hosted relay service. Its sole function is to forward commands from Salesforce to the correct Office or Google Workspace session and return the result. It does not store document data, Salesforce record data, or field values. Document content never passes through the relay — only control commands (e.g., "write these values to range A1:C10") and their results. The only data persisted is:

  • Session records (UUID, org ID, user ID, creation/expiry timestamps, active flag)
  • Org registration records (Salesforce org ID, instance URL, plan tier, created timestamp)
  • Merge count records (org ID, user ID, doc type, timestamp) — used for plan limit enforcement

Office Taskpane / Google Workspace Add-on
An Office JS add-in running inside Excel, Word, or PowerPoint (or a Google Apps Script add-on for Sheets, Docs, and Slides). It maintains a persistent connection to the relay service. When it receives a command, it executes the corresponding document API call and returns the result. All document access is local — no document content is sent to the relay service.

The taskpane also monitors the open document for selection changes, cell edits, sheet activations, and slide changes. These events are forwarded to any open flow dialog, allowing LWC components inside flows to react to live document state. Only event metadata (e.g., selected range address, selected text) is forwarded — no document bytes are transmitted.


Authentication and Authorization

Salesforce OAuth 2.0 with PKCE

Keelstone uses OAuth 2.0 Authorization Code flow with PKCE (Proof Key for Code Exchange) and a Salesforce External Client App (ECA). The ECA is created automatically by the post-install Apex job and is scoped to the minimum permissions required. No client secret is used — PKCE replaces it, eliminating the risk of secret exposure.

OAuth scopes requested: api web refresh_token

  • api — required to call Salesforce REST APIs for data queries and file operations
  • web — required for Lightning Out session compatibility
  • refresh_token — allows silent session renewal without re-prompting the user

What Keelstone receives from OAuth:

  • An access_token (Salesforce-issued, short-lived)
  • A refresh_token (Salesforce-issued, used only to refresh the access token)
  • The user's Salesforce user ID and org ID (from the identity endpoint)

Keelstone does not receive or store:

  • The user's Salesforce username or password
  • The user's email address or personal information
  • Any Salesforce record data during the OAuth exchange

The access_token is stored server-side in the session record and used to make API calls on behalf of the user when server-side document generation is requested (e.g., downloading a template file from Salesforce Files). It is never returned to the browser or to the Salesforce Flow.

Keelstone Session ID

When a user authenticates, the relay service creates a Keelstone session: a random UUID (cryptographically generated) stored with a reference to the Salesforce user ID and org ID.

This session ID is:

  • Passed to the Office or Google taskpane and stored in localStorage at app.keelstone.dev
  • Injected into the Salesforce Screen Flow as the KeelstoneSessionId input variable by the taskpane at launch time
  • Used by Apex actions as a Bearer token on all requests to the relay service
  • Never transmitted to Salesforce — it flows from the taskpane into the flow dialog via the flow launch parameters only

The session ID is treated as a secret. Any request to the relay API that presents a valid session ID is authorized to issue commands to the taskpane session associated with it. Sessions are invalidated on explicit logout and expire after 24 hours of inactivity.

Relay Service Authorization

Every relay API endpoint requires a valid Authorization: Bearer <sessionId> header. The relay service validates the session ID before processing any request. Invalid or expired sessions receive HTTP 401.

The relay service additionally enforces:

  • Plan tier checks: Free-tier orgs are limited to 1 visible action in the taskpane
  • Merge limits: Document generation is rate-limited per plan tier:
    • Free: 5 merges per org per month
    • Pro: 100 merges per user per month

No Privilege Escalation

Keelstone Actions operate entirely within the Salesforce user's existing permissions. The Apex invocable actions run as the calling user (with sharing). If the calling user does not have read access to a field or object, the Apex query will not return that data — Keelstone has no mechanism to bypass Salesforce field-level security or sharing rules.


Data Handling

What data passes through the relay service

The relay service forwards command payloads between the Apex action and the taskpane. Payloads may contain:

  • Data values that the Flow developer explicitly chose to write to the document (e.g., opportunity names, amounts, dates)
  • Cell addresses and range references
  • Chart configuration parameters
  • HTML or text content for Word insertion
  • Document property keys and values
  • Office event metadata (e.g., selected range address, selected text snippet, active worksheet ID) — forwarded to flow dialogs on the same session

The relay service does not inspect or log payload contents. Payloads are forwarded opaquely. Logs capture event types and session IDs for debugging but not payload values.

Server-side document generation

For template merge operations, the relay service temporarily holds document bytes in memory during processing:

  1. Resolves templateKey → queries the most recent ContentDocumentLink on the Keelstone_Template__c record
  2. Downloads the template from Salesforce Files using the user's access token
  3. Merges the provided data into the template in-memory
  4. Uploads the result to Salesforce Files using the user's access token
  5. Returns only the resulting ContentDocumentId — the bytes are discarded immediately

No document content is written to disk or stored in the database at any point during this process.

Document identity properties

When a generated document is inserted into the open Word or Excel document, Keelstone writes two custom properties directly into the Office file:

PropertyValuePurpose
_ks_doc_idContentDocumentId of the generated fileDocument provenance tracking
_ks_template_keyTemplate Key slug (e.g. "welcome-packet")Template-scoped action filtering

These properties are stored entirely within the Office document file (.docx / .xlsx) on the user's local machine or OneDrive — they are not sent to the Keelstone relay service. On next taskpane open, the taskpane reads _ks_template_key and sends it to the config endpoint as a URL query parameter to filter the action list. Only the key string (a short developer-chosen slug) is transmitted — no document content.

Invocable actions KS_GetDocumentProperty and KS_SetDocumentProperty explicitly block access to _ks_doc_id and _ks_template_key to prevent flows from reading or overwriting these internal markers.

What data is NOT sent to Keelstone

  • Salesforce record data not referenced by the Flow — Flows only pass the data they explicitly wire to action inputs
  • Document content from Office or Google Workspace — Document content is never uploaded to the relay service as part of taskpane relay operations. The KS_GetRange action returns cell values to the Flow, but this data stays within the Salesforce → relay → Salesforce round trip and is not stored.
  • User credentials — Usernames, passwords, and MFA tokens are never transmitted to Keelstone
  • Personal data — Keelstone does not collect names, email addresses, or any PII beyond the Salesforce user ID (a system identifier, not PII under most definitions)

Data retention

DataRetention
Session recordsDeleted on logout; automatically expired after 24 hours of inactivity
Org registration recordsRetained while the org is active; deleted on request
Merge count recordsRetained for 13 months for plan limit calculation and billing
Application logsRetained for 30 days; contain session IDs and event types but not payload data
Salesforce OAuth tokensAccess token: stored encrypted, in use for session lifetime; refresh token: stored encrypted, deleted on logout

Data residency

The relay service is hosted in the United States. Customers with data residency requirements outside the US should contact support@keelstone.dev before deploying.


Network Security

Transport encryption

All connections use TLS 1.2 or higher:

ConnectionProtocol
Browser → app.keelstone.devHTTPS / WSS (TLS 1.2+)
Apex → app.keelstone.devHTTPS
Relay service → session storeTLS

HTTP requests to app.keelstone.dev are redirected to HTTPS (301). No plaintext connections are accepted.

Endpoint security

All Keelstone invocable actions call endpoints under https://app.keelstone.dev/api/. All endpoints require a valid Bearer session token. Unauthenticated requests return HTTP 401.

Infrastructure

The relay service has no inbound ports open other than 443 (HTTPS). The session store is not publicly accessible. DDoS protection is provided at the infrastructure edge.


Salesforce Package Security

Apex security practices

All Apex classes in the Keelstone Actions package follow Salesforce security best practices:

PracticeImplementation
with sharingEvery Apex class declares global with sharing
FLS checksisAccessible() checked before any SOQL query on ContentVersion and other objects
CRUD checksObject-level access validated before DML operations
No dynamic SOQLAll SOQL queries use static, parameterized form
Input validationSession ID is validated server-side; no user-supplied input is concatenated into SOQL
No stored credentialsNo Salesforce credentials, API keys, or secrets are stored in Apex code or custom settings visible to users

Callout security

Every Apex invocable action makes a single HTTPS callout to https://app.keelstone.dev. The callout:

  • Uses Authorization: Bearer <sessionId> for authentication
  • Sets a 30-second timeout
  • Does not follow redirects
  • Requires the remote site https://app.keelstone.dev to be in the org's Remote Site Settings (installed automatically by the package)

The session ID used as the Bearer token is the Keelstone session UUID — it does not contain any Salesforce credentials or tokens.

Package permissions

The Keelstone Actions package requests the following permissions:

PermissionReason
Read/Write Keelstone_Action__cAdmin configuration of action tiles
Read/Write Keelstone_Group__cAdmin configuration of action groups
Read/Write Keelstone_Template__cAdmin configuration of template registry records
Read/Write Keelstone_Template_Action__cAdmin configuration of template-scoped action visibility
Read/Write Keelstone_Setting__mdtPost-install registration and org branding configuration
Create External Client Apps (post-install only)One-time ECA creation via post-install Apex
Callout to https://app.keelstone.devAll invocable action calls and document generation

No permissions to standard Salesforce objects (Accounts, Contacts, Opportunities, etc.) are requested by the package itself. Data access to those objects is determined entirely by the Flow the admin builds and the permissions of the running user.

Lightning Locker / LWC Security

The keelstoneGenerateDocument LWC component runs inside Salesforce's Lightning Locker Service. It:

  • Does not access the DOM of other components
  • Does not make cross-origin requests from the LWC layer (all HTTP calls go through Apex)
  • Fires standard FlowAttributeChangeEvent and FlowNavigationFinishEvent only
  • Does not use eval() or dynamic code execution

Third-Party Services

ServicePurposeData shared
Microsoft Office JSDocument API in Excel, Word, PowerPointNo data sent to Microsoft beyond normal Office telemetry. Keelstone's Office JS code is local.
Google Apps ScriptGoogle Workspace add-on runtimeNo data sent to Google beyond normal Apps Script telemetry. Keelstone's Apps Script code runs in the customer's Google account.

Keelstone does not use advertising networks, analytics platforms, or any third-party service that receives Salesforce record data.


Vulnerability Management

Responsible disclosure

Security vulnerabilities should be reported to security@keelstone.dev. We commit to:

  • Acknowledging reports within 2 business days
  • Providing a remediation timeline within 10 business days
  • Notifying affected customers if a vulnerability affected production data

Dependency management

Server-side dependencies are audited on every deployment. Critical and high-severity findings are remediated before deployment. The Salesforce package has no third-party Apex dependencies.

Penetration testing

Keelstone has not yet conducted formal third-party penetration testing. We intend to commission an external assessment prior to general availability on AppExchange. Key design mitigations:

  • Authentication bypass: All relay endpoints require a valid Bearer session ID. Session IDs are cryptographically random 128-bit UUIDs and are not guessable or enumerable.
  • IDOR: Session IDs are the only key used to scope requests. There are no sequential numeric identifiers exposed in any API.
  • Injection: All database queries use parameterized statements. No user-supplied input is concatenated into queries.
  • XSS: The relay service returns JSON only. No HTML is rendered server-side from user input.

Customers and AppExchange security reviewers may request our internal security review notes by contacting security@keelstone.dev.


Compliance and Certifications

FrameworkStatus
Salesforce AppExchange Security ReviewIn progress
OWASP Top 10 (2021)Self-assessed — design controls in place; formal third-party pen test planned pre-GA
SOC 2 Type IINot currently certified. Infrastructure provider maintains SOC 2 Type II certification.
GDPRKeelstone processes no personal data beyond Salesforce user IDs. No special category data is processed. Contact security@keelstone.dev for a Data Processing Agreement if required.
HIPAANot certified. Customers subject to HIPAA must not use Keelstone to process PHI without a signed BAA. Contact security@keelstone.dev.

Incident Response

In the event of a confirmed security incident affecting customer data:

  1. The relay service is taken offline within 1 hour of confirmation to contain the incident
  2. All active sessions are invalidated
  3. Affected customers are notified within 24 hours with a description of the impact and remediation steps
  4. A post-incident report is published within 14 days

Customers who believe their Keelstone account has been compromised should contact security@keelstone.dev immediately and revoke the Keelstone ECA in their Salesforce org (Setup → External Client Apps → Keelstone → Revoke).


Security Checklist for Administrators

Before deploying Keelstone in a production org, administrators should:

  • Confirm the Keelstone_User permission set is assigned only to users who need access
  • Review the Keelstone Action records to ensure only approved flows are exposed as action tiles
  • Confirm that the flows referenced by Action records follow your org's data access policies
  • Review which Salesforce fields are wired into Keelstone action inputs — only pass the minimum data needed
  • Confirm Remote Site Settings includes https://app.keelstone.dev and no other Keelstone-related entries exist
  • If using document generation with public links (externalLink = true), confirm your data classification policy permits public distribution of the generated content
  • If using org branding, confirm the logo uploaded via the Setup page does not contain sensitive information (it is stored as a publicly accessible Salesforce ContentDistribution URL)

Contact

Security issues: security@keelstone.dev
Privacy questions: privacy@keelstone.dev
General support: support@keelstone.dev
Documentation: https://docs.keelstone.dev