Script Policy

Custom scripts are disabled by default and must be enabled by a tenant administrator.

Why Scripts Are Opt-In

A custom script (onFormLoad, onBeforeSave, and functions called from rules and buttons) is JavaScript that runs in the browser of every form user with their permissions and is not sandboxed. Anyone allowed to modify the form configuration could therefore run arbitrary code in other users' sessions. For this reason, scripts do not run unless a tenant administrator explicitly allows them.

Expressions remain safe without enabling the policy. Formulas in the setExpression rule action and button actions are evaluated by a custom parser that does not use eval or new Function and has no access to window, fetch, or anything outside field values. Expressions, rules, and buttons therefore work even when the policy is disabled. See Expressions & Formulas.

The Policy and Its Values

The policy is a tenant Storage Entity in the tenant App Catalog. The primary key is FormCraft365_ScriptsPolicy (values allow / deny). The legacy key SpfxFormCustomizer_ScriptPolicy (values enabled / disabled) is also read, but only when the new key does not exist in the tenant at all. The new key always takes precedence: deny in the new key disables scripts even if enabled is set in the old key.

ValueResult
allow or enabled (case-insensitive, surrounding whitespace ignored)Scripts are allowed.
deny, disabled, or any other value (including typos like off or no)Scripts are disabled.
Value missing (neither key exists)Scripts are disabled (default state, opt-in).
Error while readingScripts are disabled (fail closed).

Enabling scripts is always an explicit administrator decision. A tenant that has never configured the policy has scripts disabled.

Enabling and Disabling

In the Designer

  1. In the designer, open Security and the Custom Scripts section.
  2. The Allow custom scripts tenant-wide toggle is visible and usable only by users who have write access to the tenant App Catalog (catalog site admins). Others see only the status and the command to pass to an administrator.
  3. Confirm the change in the risk warning dialog (Confirm change). This writes allow or deny to the FormCraft365_ScriptsPolicy key.
  4. The message "The change will take effect after reloading the form (within 15 minutes at most)" is displayed.
Designer, Security, "Custom Scripts" section: status "scripts are disabled on this tenant (default)" and the "Allow custom scripts tenant-wide" toggle
Confirmation dialog before enabling scripts with risk warning text and Confirm change / Cancel buttons
"Custom Scripts" section for a user without App Catalog permissions: message "Only a tenant administrator can change this setting" and the displayed Set-PnPStorageEntity command

Via PowerShell

Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/appcatalog" -Interactive

# Allow
Set-PnPStorageEntity -Key FormCraft365_ScriptsPolicy -Value allow -Scope Tenant

# Deny (also overrides the legacy key)
Set-PnPStorageEntity -Key FormCraft365_ScriptsPolicy -Value deny -Scope Tenant

# Revert to default (disabled): remove both keys
Remove-PnPStorageEntity -Key FormCraft365_ScriptsPolicy
Remove-PnPStorageEntity -Key SpfxFormCustomizer_ScriptPolicy

For an administrator without write permissions to the App Catalog, the designer provides both the allow and deny commands to pass along.

15-Minute Cache

The browser caches the result of the last successful read for 15 minutes (localStorage, key _fc_scrpol_<tenantId>). Therefore, a change may take up to 15 minutes to reach users. You can see it immediately by deleting _fc_scrpol_* keys from localStorage and reloading the page. A read error does not extend the cache duration: on error, scripts are disabled.

Behavior When Disabled

Form opened by an administrator with the policy disabled: info banner "Custom scripts are disabled on this tenant, so they are not running"

Risks After Enabling

The policy applies tenant-wide to all forms. A script running in a form can read and modify data in the session of the user who opened the form. Enable it only after verifying that only trusted designers can modify form configurations (see Permissions: locked storage and the "site owners" role).

Accepted Risk: Site Collection App Catalog

Storage Entities are read via /_api/web/GetStorageEntity. This endpoint may return a value from a site collection App Catalog before the tenant one. A site collection administrator with their own App Catalog could thus enable scripts for their site. The same applies to reading the license key. The tenant catalog is intentionally not read directly because regular users cannot read it. This is an accepted risk: do not use site collection App Catalogs where this would be unacceptable.

CSP Errors and unsafe-eval

If the policy is enabled, but a script does not run and an error appears in the form (or console), refer to the table below:

MessageCause
The tenant or browser security policy (CSP) blocks dynamic script execution (unsafe-eval).The environment prohibits new Function. Scripts will not work here; use rules and expressions instead.
Script compilation error (invalid syntax).Syntax error in the script code. Fix it in the designer's script editor.
Script error: …Runtime exception in the script. Debug mode prints the details.

Troubleshooting steps: Troubleshooting, scripts are not working. Writing scripts is described in Scripts.