Customize the Content Security Policy for apps
Configure custom Content Security Policy rules to allow or restrict behavior for your apps.
A Content Security Policy (CSP) is a feature that helps to prevent or minimize the risk of certain types of security threats. It consists of a series of instructions from a website to a browser, which instruct the browser to place restrictions on the things that the code comprising the site is allowed to do.
Retool enforces a strict CSP on all apps by default. Admins can customize this policy org-wide to free their apps to do more things, or to tighten the policy and restrict app behavior further. This page explains the default policy, what you can change, and the exact effect of each change.
Editing the CSP can enable your apps to import SDKs, make themselves embedded, and many other things.
Custom CSP applies only to apps built in the app builder. They do not apply to classic apps. The policy is configured org-wide and applies to every app in your organization.
Requirements
You must be an admin or have the delegated Manage advanced settings permission to view or edit the CSP. Custom CSP is available on both Cloud and self-hosted instances.
Customize CSP
Go to Settings > App security > Content Security Policy. The page shows a table of rules grouped by directive. A rule is an instruction to add a specific source expression to a directive:
- Required rules are enforced by Retool and cannot be changed. These usually are necessary to support the editor experience, or some baseline behavior within apps.
- Default rules are automatically active. They can be deleted and re-added.
- Rules you add appear alongside the default and required rules.
Changes save automatically and are recorded in your audit logs as Updated app CSP settings.
The CSP applies to all apps built with the app builder, including in both editing and published mode. It may take up to 30 minutes for CSP customization changes to take effect across all of your apps.
Default policy
Retool's default CSP sets most directives to 'self', with these exceptions. Some of these can be removed, but some are required for Retool to function:
-
Fonts, images and media can be loaded from any origin, or from data or blob URIs.
font-src 'self' data: blob: https:
img-src 'self' data: blob: https:
media-src 'self' data: blob: https: -
Stylesheets can be defined inline, or loaded from https://fonts.googleapis.com.
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com -
Any
<object>or<embed>tags are disallowed, and other iframes are not permitted to serve your app.object-src 'none'
frame-ancestors 'none' -
Web workers can be started from blobs.
worker-src 'self' blob:
The policy differs slightly under various conditions, such as during app editing, when Retool permits extra scripts for hot-reloading, or if you are serving published apps from a self-hosted instance.
Addding a rule
To loosen CSP, you can add a rule to the existing set:
- Select Add rule and choose the directive to extend.
- Enter the host source expression you want to add to the directive, or pick one of the
https:,data:, orblob:scheme source expressions.
Your rules are appended to the directive's existing default. For example, adding https://cdn.example.com to script-src produces script-src 'self' https://cdn.example.com—the app can still load its own scripts and now also scripts from that CDN.
The following directives can have rules added for them. Each accepts a host source expression (an origin) or the https:, data:, or blob: scheme source expression:
| Directive | Sources you can add |
|---|---|
script-src | Where the app loads and executes JavaScript from. |
connect-src | Where the app can connect via fetch, XMLHttpRequest, WebSocket, or sendBeacon. |
frame-src | What the app can embed in an iframe. |
style-src | Where the app loads stylesheets from. |
worker-src | Where the app loads web workers from. |
form-action | Where the app can submit HTML forms to. |
frame-ancestors | Origins permitted to embed your apps. Adding an origin replaces the default 'none', allowing those origins to frame your apps—use this to embed apps in another site. |
img-src, font-src, media-src | Where the app loads images, fonts, and media from. These allow any HTTPS origin and the data: and blob: schemes by default. |
Source expression reference
When you add a rule, you provide a source expression—the value that tells the browser what the directive permits. Retool rules accept host source expressions (an origin, optionally with a port or path, or a single-level subdomain wildcard) and the https:, data:, and blob: scheme source expressions. Bare http:, ws:, and wss: schemes and keyword source expressions (such as 'self') can't be added.
- Accepted
- Rejected
| Accepted | Example |
|---|---|
| HTTPS, HTTP, WSS, or WS origin | https://api.example.com |
| Origin with a port | https://example.com:8443 |
| Origin with a path prefix | https://example.com/widgets/ |
| Single-level subdomain wildcard | https://*.example.com |
https:, data:, or blob: scheme | data: |
| Rejected | Reason |
|---|---|
* | Bare wildcards are not allowed. |
https://*.*.example.com | Only one wildcard level is allowed. |
example.com | A scheme is required. |
http:, ws:, wss: | Bare http:, ws:, and wss: schemes aren't allowed—use a full origin. |
https://example.com?q=1 | Query strings are not part of a source expression. |
https://example.com#section | Fragments are not part of a source expression. |
'self', 'unsafe-eval' | Keyword source expressions are managed by Retool and can't be added as rules. |
Troubleshoot blocked resources
When the browser blocks a resource, it logs a CSP violation to the developer console, naming the directive that blocked it:
Refused to connect to 'https://api.example.com/' because it violates the
following Content Security Policy directive: "connect-src 'self'".
The directive in the message (in this example, connect-src) is the one to update. Add the blocked origin to that directive, save, and reload the app. If a resource still fails after you allow its origin, confirm the scheme matches—an https:// rule does not permit a wss:// WebSocket connection, for example.
Developer tools can also help you see the CSP being served by the app, to confirm it is as you expect. Refer to your browser documentation for more information on developer tools.