You can use this article to secure the external URLs used by your custo-manifest extensions. You will see how to declare trusted domains, configure CORS or Local Network Access when needed, and diagnose blocked requests.
Overview
Custo-manifest extensions can reach external URLs: REST API calls, web applications embedded in a Rainbow frame, or dynamic content loading. To control which third-party servers can be contacted, Rainbow enforces a trusted domain allowlist configured in the Rainbow administration console.
Any domain not declared in this list is blocked. Depending on the type of extension involved, the block manifests differently β which is why understanding this mechanism is essential before deploying a manifest.
Configuring trusted domains
The list is managed in the Rainbow administration console:
Company β Information β Customization β Custo-manifest domains
|
|
Rainbow console β Customization β Custom manifest domains tab
Add one entry per origin to allow. Each entry must follow this format:
<protocol>://<domain>[:<port>]| Part | Rules |
| protocol | https or http β mandatory |
| domain | Exact hostname or wildcard (*.example.com) |
| port | Optional β omit for standard ports (443 / 80) |
| Trailing slash / | Not allowed β the entry will not match |
Valid examples
| Entry | Matches |
| https://crm.example.com | https://crm.example.com/any/path |
| https://crm.example.com:8443 | Non-standard port |
| https://*.example.com | All subdomains |
| http://192.168.1.100:3300 | Local server on private network |
Invalid examples
| Entry | Problem |
| crm.example.com | Missing protocol |
| https://crm.example.com/ | Trailing slash β rejected |
| https://crm.example.com/api | Path not allowed β declare the origin only |
Trusted domain scope
The trusted domain check applies consistently to URLs used by Rainbow Extensions on Web and Desktop.
| Manifest field or usage | Trusted domain impact |
|---|---|
command.url |
Checked for REST calls, web navigation and file/navigation use cases that reference a URL. |
on-main-window-actions |
The embedded application URL must be trusted unless Popup: true is used. |
adaptiveCardSubmitUrl |
The POST endpoint used by Action.Submit must be trusted. |
urlConfig |
Configuration URLs used by widgets or embedded applications must be trusted. |
Impact on REST API calls
Extensions that invoke a REST API (commandType: "rest") go through the browser. Two independent security layers apply:
Trusted domain check (Rainbow side)
If the REST server's origin is not declared in the Rainbow console, Rainbow shows a warning when the manifest loads. If the warning is dismissed, the call will silently fail at runtime β no error message is displayed inside Rainbow.
Fix: declare the origin in Company β Customization β Custo-manifest domains.
CORS (REST server side)
Even if the domain is trusted by Rainbow, the browser also enforces CORS. The REST server must return the following headers in its responses:
Access-Control-Allow-Origin: https://web.openrainbow.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, AuthorizationIf you do not need to restrict access to a specific origin, you can use the wildcard:
Access-Control-Allow-Origin: *If the server does not return these headers, the browser blocks the call with no message in Rainbow. If you control the server, add the CORS headers. Otherwise, ask the server owner to update its configuration.
Local Network Access (LNA)
If the REST server runs on a local or private network (e.g. http://192.168.1.100:3300), the browser may block the call under the Local Network Access policy.
When the browser detects a request to a private network, it first sends a preflight OPTIONS request with:
Access-Control-Request-Private-Network: trueThe server must respond by adding Access-Control-Allow-Private-Network: true to its CORS headers:
Access-Control-Allow-Origin: https://web.openrainbow.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Private-Network: trueIf this header is missing, the browser blocks the request even if the standard CORS headers are correct.
Solutions depending on context:
| Approach | When to use |
| Access-Control-Allow-Private-Network: true | You control the local server and want it to work on Rainbow Web |
| Expose over HTTPS + resolvable hostname | Production deployment |
| Reserve the extension for Rainbow Desktop only | You do not control the local server |
Impact on embedded applications
The on-main-window-actions extension displays a third-party web application inside the Rainbow interface. Two modes are available depending on the Popup value.
Without Popup β application inside the Rainbow frame
The application is loaded in an <iframe> inside Rainbow. Three security layers apply:
Trusted domains
The application URL must be declared in the Rainbow console. If not, the frame appears but the page stays blank or shows a browser security error.
CSP / X-Frame-Options from the application
The target application may itself refuse to be embedded in an iframe:
| Header | Typical value | Effect |
| X-Frame-Options | DENY or SAMEORIGIN | Refuses embedding β blank frame |
| Content-Security-Policy | frame-ancestors 'self' or 'none' | Same effect, modern mechanism |
How to check: Developer tools β Network tab β response from the application URL β inspect headers.
Fix: If you control the application, allow the Rainbow origin in frame-ancestors. Otherwise, switch to Popup: true (see Β§3.2).
SSO / OAuth flow through a third-party domain
If the application uses an authentication flow (SSO, OAuth 2.0, SAMLβ¦), the identity provider (IdP) typically lives on a different domain than the application. Rainbow loads these redirects inside the same frame β so all domains in the flow must be declared:
https://app.example.com β the application
https://login.microsoftonline.com β Microsoft IdP
https://login.example.com β your internal IdPWith Popup: true β application in a dedicated window
When Popup: true is set, the URL opens in a dedicated browser window, outside the Rainbow frame. In this mode:
- Rainbow's trusted domain check is disabled for that URL.
- The application's X-Frame-Options and CSP frame-ancestors restrictions are irrelevant.
- SSO / OAuth flows work normally in their own window.
"on-main-window-actions": [{
"name": "My App",
"icon": "${custo.path}\\app.png",
"Popup": true,
"command": {
"url": "https://app.example.com/",
"params": "user=${localUser.email}"
}
}]Local execution special case
Local application or script execution with commandType: "file" on Rainbow Desktop is not controlled by browser CORS, Local Network Access or iframe security headers.
Common issues and troubleshooting
A warning appears when loading the manifest
The manifest references one or more URLs whose origin is not declared in the console.
Fix: Add the missing origin in Company β Customization β Custo-manifest domains.
A REST call produces no result
| Likely cause | How to check | Fix |
| Domain not declared | Warning at manifest load | Declare the origin in the console |
| Missing CORS headers | Developer tools β Network tab β CORS error | Add Access-Control-Allow-Origin on the server |
| LNA (local server) | Works on Desktop, not on Web | Expose over HTTPS or use Desktop |
The frame stays blank
| Likely cause | How to check | Fix |
| Domain not declared | Warning at manifest load | Declare the origin in the console |
| Restrictive X-Frame-Options or CSP | Developer tools β response headers | Modify headers on app side or use Popup: true |
| SSO IdP domain not declared | Frame goes blank at login step | Declare the IdP domain as well |
| IdP refuses iframes | Frame stays blank after domain declaration | Switch to Popup: true |
Diagnostic checklist
- Origin is declared in Company β Customization β Custo-manifest domains
- REST server returns CORS headers (Access-Control-Allow-Origin)
- Server is not on a local/private network (LNA β Web only)
- Embedded app does not return restrictive X-Frame-Options or CSP: frame-ancestors
- For SSO / OAuth: IdP domains are also declared as trusted
- If nothing else works: Popup: true tested for frames, Desktop tested for local REST calls