Security
Last updated September 24, 2026
Summary
- Generated code runs in a sandbox whose Content Security Policy allows requests only to Wisty's Salesforce proxy.
- Every Salesforce read and write runs as the signed-in user. Wisty holds no integration user and no service account.
- The generating AI receives org metadata, instructions, relevant attachments, and project code. Wisty does not retrieve Salesforce records for generation context.
- Salesforce tokens are stored encrypted, with the decryption key held separately in AWS KMS. Access to the stored data alone is not enough to read a token.
- Disconnecting an org removes the connection and requests OAuth grant revocation at Salesforce. Deleting a workspace starts removal of its customer data under the retention schedule below.
Company and compliance
Wisty is operated by Wisty Labs AS, org. nr. 938 423 490, Norway. It is an independent product and is not made, endorsed, or supported by Salesforce, Inc. For customer data processed through the service, Wisty acts as a processor under GDPR.
| Item | Status |
|---|---|
| GDPR | Processor for customer data. A data processing agreement is available. |
| Data location | United States for core application storage and preview sandboxes. European Union for product analytics and session replays. Delivery and AI processing depend on provider routing. Full table under Architecture. |
| Security questionnaires | Completed on request. Most rows are answered on this page. |
Wisty's security controls are built into the product and documented on this page, from the sandbox boundary on generated code to per-credential encryption of Salesforce tokens. SOC 2 and ISO 27001 certification are planned.
Related documents: Data processing agreement, Privacy policy, and Terms of service.
Architecture and data location
Wisty has four parts.
- The builder app, where builders describe apps in chat and manage their workspace.
- The backend, which stores application data, runs generation, and operates the Salesforce proxy that every read passes through.
- Preview sandboxes, where generated code runs during editing, and published apps, built once into static files and served to viewers inside Salesforce or through a link.
- AI model providers, called during generation.
Salesforce record data is read live from Salesforce when an app runs. It passes through Wisty's proxy in the United States and is never stored, cached, or logged. All other data, by provider and region:
| Data | Provider | Region |
|---|---|---|
| Application data: projects, files, generated code, chat, cached org metadata, encrypted Salesforce tokens | Convex | United States |
| Encryption keys for Salesforce tokens | AWS KMS | United States |
| Preview sandboxes | Vercel | United States |
| Published builds in storage | Convex | United States |
| Published-app delivery and runtime traffic | Cloudflare | Global network |
| Generation inputs and outputs | Anthropic, OpenAI, and Google, through Vercel AI Gateway | Provider-dependent, including the United States |
| Builder accounts | Clerk | United States |
| Billing records | Polar | United States |
| Service email to workspace administrators | Resend | United States |
| Product analytics, session replays, error reports, backend logs | PostHog | European Union |
| AI generation traces | Braintrust | European Union |
Salesforce access
Wisty connects to an org with OAuth 2.0 through a Salesforce connected app. Sign-in happens on Salesforce's own domain. Wisty never receives a password.
There is no integration user. Every read and write runs as the individual signed-in user, so field-level security, object permissions, and sharing rules apply exactly as they do in Salesforce. Wisty cannot widen access because it never holds a credential broader than the user's own.
Wisty requests these OAuth scopes:
| Scope | What it grants | Why Wisty needs it |
|---|---|---|
| api | Call the Salesforce REST API as the connected user | Reads the metadata generation works from, and carries the record reads and approved writes running apps make. |
| refresh_token | Renew access without a new sign-in | Keeps a connected org working between sessions without a new sign-in. |
| custom_permissions | Read which custom permissions the org assigned the user | Lets the Salesforce admin control who may build and publish, through permission sets. |
Wisty never creates or writes metadata. The read proxy accepts a fixed list of read-only endpoints, and writes happen only when a user using a generated app initiates one, as record operations through the write bridge. Wisty cannot create or change metadata, including objects, fields, Apex, Flows, or validation rules.
Admins decide who may build and publish through a custom permission assigned with permission sets. Access can be revoked at any time in Setup under Connected Apps OAuth Usage, independently of Wisty.
Org metadata
To generate an app, Wisty needs the shape of the org: which objects exist, their fields and types, relationships, record types, and which fields appear on layouts and list views. Wisty reads this through Salesforce's describe and layout APIs, as the connected user, and caches it so that generation does not repeat those calls on every step.
The cache holds metadata only: object and field names, labels, types, relationships, record types, and layout membership. It contains no record data. It is keyed to the connected Salesforce user, so it reflects that user's object and field permissions and is not shared with connections made as a different user.
The cache is refreshed in the background once it is older than 24 hours. It is stored in Wisty's database, encrypted at rest, and deleted when the last connection for that Salesforce user is removed or the workspace is deleted.
Generated code and the sandbox
Apps that Wisty generates run in a sandboxed iframe. The sandbox's Content Security Policy restricts requests to its own origin, and that origin exposes one endpoint: Wisty's Salesforce read proxy. The generating AI receives Salesforce metadata, not customer records. A faulty generation or an injected instruction has no request it can send anywhere else.
Reads
Generated app
Sandboxed iframe
Wisty read proxy
The sandbox's own origin
Salesforce
As the signed-in user
Writes
Generated app
Over the postMessage bridge
Wisty host
Checks the approved writes
Salesforce
As the signed-in user
Anything else
Generated app
Public internet
Requests blocked
While you build, the preview's server runs in a virtual machine. Its outbound network policy denies every connection except to Wisty's backend, including DNS.
No credential enters the sandbox. The session token that identifies the sandbox to Wisty's backend is attached at the network layer as requests leave the machine, so generated code cannot read, log, or forward it. Salesforce tokens never leave the backend. The proxy uses them there when it forwards a read.
Generated code cannot call Salesforce write APIs. A write request travels a postMessage bridge to the trusted Wisty host, which checks it against the write permissions the builder approved for that app and executes it under its own authentication.
The proxy client, the write bridge, and the sandbox helpers are platform files the AI cannot edit. Published apps are built once into immutable static files and served from a separate domain, so they stay cross-origin from the builder app.
AI processing
Wisty generates code with Anthropic and OpenAI models and images with Google models, through Vercel's AI Gateway. Providers process inputs under commercial API terms without using them to train models. Standard abuse-monitoring retention is up to 30 days, with exceptions for flagged content or legal requirements. The gateway itself does not retain prompts or outputs.
Generation models receive instructions, relevant attachments, org metadata, and project code. Personal data included in chat or attachments is processed with that content. Wisty does not retrieve Salesforce records for generation context. Image generation receives descriptions written by the generating AI, which may reflect customer instructions, rather than the full conversation or uploaded files. Stored Salesforce credentials are never sent to a model.
Generation
Chat, metadata, app code
Objects, fields, relationships
AI model
Claude, GPT, or Gemini, via AI Gateway
Runtime
Running app
As the signed-in user
Wisty read proxy
Salesforce records
Wisty records each generation as a trace in Braintrust, hosted in the European Union: the instructions, the model's steps, the Salesforce metadata it read, and the generated code. Traces are used to investigate errors and evaluate generation quality. Access is restricted to authorised personnel. Traces are deleted after 14 days; this does not delete the original project or chat.
Credential storage and encryption
All application data is encrypted at rest by Convex, and every hop runs over TLS: browser to Wisty, Wisty to Salesforce, and Wisty to each provider. Salesforce tokens carry a second, independent layer on top, with the key held in AWS KMS rather than alongside the data.
Salesforce access and refresh tokens are stored with envelope encryption. Each credential is encrypted under its own data key, and data keys are wrapped by a key held in AWS KMS on FIPS-validated hardware from which key material cannot be exported. The wrapping key is stored separately from the database. Decryption requires authorised access to KMS. The running service holds credentials that grant that access; encryption alone does not protect against compromise of those credentials.
Each ciphertext is bound to its owner through KMS encryption context and authenticated data: the app, org, user, and field it belongs to. A ciphertext moved to another row or another user's connection fails to decrypt. Plaintext tokens exist only in server memory during a Salesforce call.
Every token read is a separate KMS decrypt call, so AWS CloudTrail records each access independently of Wisty's own logs. Revoking the runtime's KMS access renders every stored token undecryptable at once. These two controls, the per-access audit trail and immediate revocation, are what protect tokens while the service is running, where encryption at rest alone would not.
In AWS, the runtime holds one identity whose only permissions are generating and decrypting data keys under one KMS key. Development and production use separate keys.
Authentication, tenancy, and staff access
Standalone builders sign in through Clerk, with multi-factor authentication available. Canvas builders and viewers authenticate through Salesforce. Viewers do not need Wisty accounts. Inside Salesforce, identity comes from Salesforce's signed request to the embedded app. On share links, viewers sign in to Salesforce itself, and the session is held in an HttpOnly cookie that page scripts cannot read. In both cases the viewer's own Salesforce permissions decide what they see.
The workspace is the tenancy boundary. Projects, Salesforce connections, and published apps are keyed to it, and every backend function checks that scope on every call. Workspace administrators control who is a member. Who may build and publish against a connected org is additionally governed by the Salesforce custom permission described under Salesforce access.
Production access is granted to Wisty staff on a need-to-know basis, through the providers' own consoles on accounts protected by multi-factor authentication. Support and diagnostic access is limited to what is needed to provide, support, or secure the service, including project files, chat history, generated code, and cached org metadata. Every use of a Salesforce token is logged in AWS CloudTrail. Development and production are separate deployments with separate credentials and keys.
Data retention and deletion
| Data | Retention |
|---|---|
| Application data: projects, files, chat, generated code | Until you delete the project or workspace. |
| Salesforce connections | Until you remove the connection or delete the workspace. |
| Cached org metadata | Refreshed after 24 hours. Deleted with the last connection for that Salesforce user, or with the workspace. |
| Salesforce record data | Never stored, cached or logged. Read live from Salesforce at runtime. |
| Database backups | Expire within 14 days. |
| Product analytics events | Until 2 years after the account's last activity. Removed in a yearly sweep. |
| Session replays | 3 months. |
| AI generation traces | 14 days. |
Every deletion trigger, from removing a project to deleting a workspace or account, routes through one deletion module. Deleting a workspace removes projects and everything under them: files, versions, published apps and their stored builds, chat threads, generation history, Salesforce connections, and the cached org catalog. Published apps are revoked in the same transaction, so viewers lose access on their next request.
Disconnecting an org requests revocation through Salesforce's revoke endpoint. Revocation is best-effort; administrators can also revoke access directly in Salesforce.
Billing and trial-abuse records also survive workspace deletion: billing data, kept for financial and audit obligations, and the Salesforce org id and sign-up email, kept so that deleting and re-creating a workspace cannot restart a free trial.
Published access is revoked immediately when deletion is processed; removal of stored data runs asynchronously. Backups and telemetry normally expire on the schedule above. Requests for return or earlier erasure are handled under the DPA and applicable law. Erasure requests for personal data go to legal@wisty.ai.
Logging, monitoring, and incident response
AWS CloudTrail holds a per-access record of credential use, independent of Wisty's logs. At the application layer, every Salesforce call through the proxy is logged with the project, the viewer surface, endpoint identity, and response status. Request paths and error messages are excluded from these application log lines. Response bodies are not logged. Write logs record object names and row counts, not field values.
Wisty's own telemetry goes to PostHog, hosted in the European Union: product events, error reports, backend logs, and session replays of the builder app. Replays mask text inputs and do not capture the cross-origin preview. The host's write-approval content is also excluded from capture. Other visible builder content, including chat text, may appear in replays. Builder accounts are identified in analytics by name, email address, and workspace name, so support can see who it is talking to. People who open apps in Salesforce are not identified by name or email. AI generation traces go to Braintrust, as described under AI processing. Retention is in the table under Data retention and deletion.
Incident containment can include requesting revocation of Salesforce grants in affected orgs and disabling the runtime's KMS access. The response depends on the incident. CloudTrail records every decrypt made with that key.
Wisty notifies affected customers of a personal data breach without undue delay and no later than 72 hours after becoming aware of it, with what is known at that time and updates as the investigation continues. The same commitment is in the data processing agreement.
Wisty runs on Convex and Vercel, which publish their own status pages.
Vulnerabilities can be reported to security@wisty.ai and are acknowledged within two business days.
Subprocessors and contact
Wisty runs on a small set of infrastructure providers, named throughout this page. The customer-data subprocessor register is Annex 3 of the data processing agreement, which also sets out how changes to the list are notified.
Questions this page does not answer, questionnaires, and DPA requests: security@wisty.ai.