Control what users can edit in templates by setting fine-grained permissions on individual blocks or globally across the scene with the CE.SDK Scope system.
Editing constraints let you lock specific properties of design elements while keeping others editable. Scopes cover movement, resizing, rotation, fill changes, text editing, lifecycle operations, and other editor capabilities. Use them to protect brand templates, guide template adoption, and build form-based workflows where users can personalize only selected fields.
Understanding Scopes#
What Are Scopes?#
A scope is a permission key that controls one editing capability. Each scope represents a distinct action, such as moving blocks ("layer/move"), changing fills ("fill/change"), or editing text content ("text/edit").
Scopes exist at two levels:
- Block-level scopes: Per-block permissions set with
engine.block.setScopeEnabled(...). - Global scopes: Scene-wide defaults set with
engine.editor.setGlobalScope(...).
Global scope defaults depend on the editor role. Under the default Creator role, global scopes are allowed, so block-level restrictions are not consulted. To make a block-level setting take effect, set the matching global scope to GlobalScope.DEFER, either through your editor role setup or with engine.editor.setGlobalScope(...).
Available Scope Categories#
CE.SDK groups scopes into logical categories. Retrieve the full list at runtime with engine.editor.findAllScopes().
| Category | Purpose | Example Scopes |
|---|---|---|
| Text Editing | Control text content and formatting | text/edit, text/character |
| Fill & Stroke | Manage colors, fills, and strokes | fill/change, fill/changeType, stroke/change |
| Shape | Modify shape properties | shape/change |
| Layer Transform | Control position and dimensions | layer/move, layer/resize, layer/rotate, layer/flip, layer/crop |
| Layer Appearance | Manage visual properties | layer/opacity, layer/blendMode, layer/visibility, layer/clipping |
| Effects & Filters | Apply visual effects | appearance/adjustments, appearance/filter, appearance/effect, appearance/blur, appearance/shadow |
| Lifecycle | Control deletion and duplication | lifecycle/destroy, lifecycle/duplicate |
| Editor | Manage scene-level actions | editor/add, editor/select |
Scope Configuration#
Global Scope Modes#
Global scopes set the default behavior for all blocks in the scene. They have three modes:
| Mode | Behavior |
|---|---|
GlobalScope.ALLOW |
Always allow the action, overriding block-level settings |
GlobalScope.DENY |
Always deny the action, overriding block-level settings |
GlobalScope.DEFER |
Use the block-level setting for each block |
To make block-level constraints take effect, defer the relevant global scopes to the block level:
// Keep these scopes deferred so the returned scene uses block-level constraints.engine.editor.setGlobalScope(key = "layer/move", globalScope = GlobalScope.DEFER)engine.editor.setGlobalScope(key = "layer/resize", globalScope = GlobalScope.DEFER)engine.editor.setGlobalScope(key = "lifecycle/destroy", globalScope = GlobalScope.DEFER)engine.editor.setGlobalScope(key = "lifecycle/duplicate", globalScope = GlobalScope.DEFER)Defer only the scopes that your app controls at the block level. When a block should keep a deferred capability, explicitly enable that scope on the block.
Scope Resolution Priority#
When both global and block-level scopes apply, CE.SDK resolves permissions in this order:
- Global
GlobalScope.DENYblocks the action. - Global
GlobalScope.ALLOWpermits the action. - Global
GlobalScope.DEFERuses the block-level setting for each block.
Setting Block-Level Constraints#
Locking Position#
Prevent users from moving a block while keeping resizing available:
engine.block.setScopeEnabled(positionLocked, key = "layer/resize", enabled = true)engine.block.setScopeEnabled(positionLocked, key = "layer/move", enabled = false)Disabling layer/move locks the block position. Because the full sample also defers resizing and lifecycle scopes,
the block can still resize, delete, and duplicate when those block-level scopes remain enabled.
Preventing Deletion#
Protect a block from being deleted or duplicated while keeping transform edits available:
engine.block.setScopeEnabled(deletionLocked, key = "layer/move", enabled = true)engine.block.setScopeEnabled(deletionLocked, key = "layer/resize", enabled = true)engine.block.setScopeEnabled(deletionLocked, key = "lifecycle/destroy", enabled = false)engine.block.setScopeEnabled(deletionLocked, key = "lifecycle/duplicate", enabled = false)Use this for essential template elements that must remain present. Movement and resizing can remain enabled independently because lifecycle scopes are separate permissions.
Checking Scope State#
Query the block-level setting for any scope:
val moveScopeEnabled = engine.block.isScopeEnabled(positionLocked, key = "layer/move")Log.i("SetEditingConstraints", "layer/move enabled at block level: $moveScopeEnabled")engine.block.isScopeEnabled(...) returns only the block-level flag. It does not consider the current global scope mode.
Checking Effective Permissions#
Check the effective permission after global and block-level settings resolve:
val moveAllowed = engine.block.isAllowedByScope(positionLocked, key = "layer/move")Log.i("SetEditingConstraints", "layer/move allowed: $moveAllowed")Use engine.block.isAllowedByScope(...) when your app needs to know whether an action is actually permitted.
API Reference#
| Method | Description |
|---|---|
engine.editor.findAllScopes() |
List all available scope keys |
engine.editor.setGlobalScope(key=_, globalScope=_) |
Set a scope to GlobalScope.ALLOW, GlobalScope.DENY, or GlobalScope.DEFER |
engine.editor.getGlobalScope(key=_) |
Read the global setting for one scope |
engine.block.setScopeEnabled(block=_, key=_, enabled=_) |
Enable or disable a block-level scope |
engine.block.isScopeEnabled(block=_, key=_) |
Check whether a scope is enabled at the block level |
engine.block.isAllowedByScope(block=_, key=_) |
Check the resolved permission after global and block-level settings are evaluated |
Troubleshooting#
- A disabled block scope still appears editable: Check the matching global scope.
GlobalScope.ALLOWoverrides block-level restrictions, so set that scope toGlobalScope.DEFERwhen the block setting should decide the result. - All blocks lose the same editing capability: Check for
GlobalScope.DENY. A denied global scope disables that action for every block, even when individual blocks have the scope enabled. - Constraints seem to reset after reloading: Scope settings are stored with the scene. If a reloaded scene behaves differently, verify that your app saved the constrained scene after calling
engine.block.setScopeEnabled(...). - The editor UI shows unavailable controls: The CE.SDK editor UI reflects denied scopes by disabling or hiding controls depending on the surface. Use
engine.block.isAllowedByScope(...)to confirm the resolved permission that the UI should follow.
Next Steps#
- Text Variables - Define dynamic text elements that can be populated with custom values.
- Placeholders - Mark editable image, video, or text areas within a locked template layout.
- Lock the Template - Restrict editing access to specific elements or properties in a template.
- Create From Scratch - Build reusable design templates programmatically using CE.SDK APIs.