feat: sandbox new low-code and raw apps by default (#11760)

* feat: sandbox new low-code and raw apps by default

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: navigate the top page from plain links in a sandboxed low-code app

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: allow clipboard and fullscreen in sandboxed raw-app frames

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: leave non-http links to the browser in the sandboxed app frame

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: let a link's own click handlers run before relaying it out of the frame

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: read link attributes so SVG anchors relay correctly

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: tidy the app deploy drawer to the brand guidelines

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: show enabled frontend api scopes as badges, rename runs-as section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep frontend api access collapsed by default, badges next to its title

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: lead the run-on-behalf-of section with the user picker

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: explain publisher execution and WM_END_USER_EMAIL in the run-on-behalf-of tooltip

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: shorten the run-on-behalf-of tooltip, mention viewer data access for raw apps

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: tell the AI what breaks in a sandboxed raw app and that turning it off is a security risk

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: warn in the deploy drawer when an app is not isolated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: drop the sandbox toggle help line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: say when to turn sandbox isolation off in the toggle tooltip

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: show who a non-deployer's app runs as, read-only

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: show a new app runs as the deployer, gray read-only user line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: read-only on-behalf-of display as an opt-in selector prop

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: show a folder's default run-as user on a new app instead of the deployer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: deploy an app under a group folder default without a mismatched email

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* revert: leave a new app's run-as user unselected, as on main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: warn in the app deploy drawer when a deploy changes the run-as user

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: snapshot the deployed policy so later edits don't change the saved app

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-10-15 12:54:00 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 4f712318c3
commit 813c080d46
17 changed files with 586 additions and 507 deletions
+1
View File
@@ -593,6 +593,7 @@ CREATE SCHEMA IF NOT EXISTS ${schemaName};
// Create raw_app.yaml with data configuration
const rawAppConfig: Record<string, unknown> = {
summary,
sandbox: true,
};
// Add data configuration if present
+3 -1
View File
@@ -6920,7 +6920,9 @@ Either one lets those people run the app's backend runnables, so never open an a
## Sandbox isolation and frontend API access
By default a deployed app's frontend runs with the viewer's own Windmill session. A sandboxed app is isolated from it: the frontend reaches Windmill only through its backend runnables, plus whatever frontend API scopes the app declares, which each viewer approves before the app runs. The scopes are \`jobs:run\`, \`jobs:read\`, \`users:read\`, \`resources:read\`, \`variables:read\`, \`flow_conversations:read\` and \`flow_conversations:write\`; grant only the ones the frontend calls.
New apps are sandboxed: the frontend is isolated from the viewer's own Windmill session and reaches Windmill only through its backend runnables, plus whatever frontend API scopes the app declares, which each viewer approves before the app runs. With isolation turned off, the frontend runs with the viewer's full session. The scopes are \`jobs:run\`, \`jobs:read\`, \`users:read\`, \`resources:read\`, \`variables:read\`, \`flow_conversations:read\` and \`flow_conversations:write\`; grant only the ones the frontend calls.
Inside the sandbox, IndexedDB is unavailable, third-party sign-in and OAuth redirects fail, and requests to other services carry \`Origin: null\`, which an API that checks the origin rejects. Work around these first: call the service from a backend runnable, keep state in a data table or \`localStorage\`, or grant the frontend API scope the code needs. Suggest turning isolation off only when none of that works, and say plainly that it is a security risk: the app's code, and any XSS bug in it, then runs with the full Windmill permissions of everyone who opens the app.
In \`raw_app.yaml\`:
\`\`\`yaml