Safety Mode
Safety Mode helps you control changes to B2C Commerce from the CLI, the IDE Extension, and your AI assistant through MCP. Keep investigations read-only, restrict automated scripts, or ask for approval before selected changes. Choose settings for each instance or share a policy across your projects.
All three use the same safety configuration format. Approval prompts are available for supported actions. Safety Mode is off by default (NONE). It adds controls alongside your B2C Commerce permissions; it does not grant access you do not already have.
Start with an instance policy
Add a safety object to an existing instance in dw.json. In a plain dw.json, it sits alongside fields such as hostname and your credentials. Named configurations are optional; if you use a configs array, add safety to the relevant entry. Keep your existing connection and credential fields unchanged. For example, this safety section blocks DELETE requests:
{
"safety": {
"level": "NO_DELETE"
}
}This still allows creating and updating records. For an investigation where you want to restrict writes, choose READ_ONLY instead. See Configuration for single-instance files, named instances, and shared defaults.
Choose a safety level
Choose a starting level, then add rules for exceptions. These settings apply across supported B2C operations, including catalog data, code deployment, jobs, and sandbox management.
| Level | Default behavior | Useful for |
|---|---|---|
NONE | No level-based restrictions; explicit rules still apply. | Confirm or block only the operations you select with rules. |
NO_DELETE | Blocks DELETE; POST, PUT, and PATCH remain allowed. | Allow writes while blocking DELETE requests. |
READ_ONLY | Blocks POST, PUT, PATCH, and DELETE. | Inspect data, then allow or approve selected changes. |
For "ask before changes, block deletes," start with the shared SCAPI approval example. It uses READ_ONLY with rules for the changes you want to review.
The method names describe API requests: GET usually reads data, PUT and PATCH change it, POST can start tasks or run searches, and DELETE usually removes data. Safety Mode checks these methods, so a POST search also needs an exception under READ_ONLY. Likewise, NO_DELETE does not block data removal performed through another method.
Existing configurations using NO_UPDATE
NO_UPDATE is a legacy setting that does not prevent all updates. It blocks DELETE and POST requests whose paths contain /reset, /stop, /restart, or /operations; PUT, PATCH, and other POST requests remain allowed. For new configurations, use one of the levels above with rules for your needs.
Use it in your tools
CLI
For a terminal session:
export SFCC_SAFETY_LEVEL=READ_ONLY
b2c code listThe listing is allowed; a request to activate or delete a code version is blocked. The environment setting also applies to subsequent B2C commands launched from that terminal. Use the instance's safety configuration when you want different policies for different targets.
To review a particular command before it starts, add a command rule to the safety section in dw.json:
{
"safety": {
"rules": [{"command": "code:deploy", "action": "confirm"}]
}
}An interactive b2c code deploy asks for confirmation. With piped input or in CI, it is blocked because nobody can answer the prompt. Approving the command does not override other safety rules that apply to its actions.
MCP and AI assistants
You can ask your assistant to investigate data without changing it, or require your approval before selected changes. Add the safety settings to the dw.json your assistant uses; this works with both plugin and manual installation.
With READ_ONLY, SCAPI Code Mode can inspect products, catalogs, and other data through GET requests, while requests to create, update, or delete records are blocked. A POST-based search needs an explicit exception, as shown below.
Which products in my New Arrivals category are offline?
For data tasks handled by SCAPI Code Mode, your assistant can ask you to review each change that needs approval. Check the target and proposed change, then approve to continue or decline to stop. See the product creation example.
Your assistant app must support approval prompts from connected tools. If it cannot show the prompt, the change is blocked. Other B2C MCP tools currently block actions that require Safety Mode approval. Your app may also ask permission to use a tool; that separate permission does not approve the specific change.
SCAPI Code Mode uses the same safety settings from dw.json, global safety configuration, and environment variables. No separate code mode setup is needed. See how settings combine.
IDE extension: VS Code and compatible editors
The Salesforce B2C Commerce IDE Extension applies the safety policy for its selected instance. Add the safety object to its dw.json; there is no separate safety-level setting to configure in VS Code Settings. Switching the selected instance refreshes the policy with the connection.
For example, block sandbox deletion from the extension and ask before stopping one:
{
"safety": {
"rules": [
{"command": "b2c-dx.sandbox.delete", "action": "block"},
{"command": "b2c-dx.sandbox.stop", "action": "confirm"}
]
}
}Choosing Delete in the Sandbox Explorer shows a safety-policy error and does not run the command. Choosing Stop shows a modal warning with Proceed; dismissing it cancels the action. Ordinary action confirmations may still appear. Other safety rules still apply after you approve a command.
The extension also supports approval for sandbox deletion, reset, and start/stop actions. If an action needs approval but has no approval dialog, it stops with an error.
CLI and extension command names differ. A code:deploy rule applies to the CLI; it does not select an IDE command or MCP tool. See extension configuration for selecting the intended instance.
Add rules for specific tasks
Rules are checked in order. The first matching rule wins.
| Action | Result |
|---|---|
allow | Allows the matching action, even if the safety level would block it. |
block | Blocks the matching action. Approval cannot override this rule. |
confirm | Asks for approval. If the tool cannot ask, the action is blocked. |
An allow rule does not override an earlier matching block. If no rule matches, the safety level determines the result.
Allow a search without enabling other writes
For job investigation through SCAPI code mode, add this policy to the instance:
{
"safety": {
"level": "READ_ONLY",
"rules": [
{
"method": "POST",
"path": "/operation/jobs/v1/organizations/*/job-execution-search",
"action": "allow"
}
]
}
}This allows searching job history while keeping job starts and other POST requests blocked. When adding an exception, use the request path shown in the error message.
Approve product changes with your assistant
SCAPI Code Mode can create a product, assign it to a storefront category, and verify both changes in one task. Use this instance policy to review product creation or replacement and category assignments across all products. For a broader shared policy, see approve SCAPI changes across instances.
Instance policy (dw.json): Add this safety section to your dw.json, keeping its existing connection and credential fields.
{
"safety": {
"level": "READ_ONLY",
"rules": [
{
"method": "PUT",
"path": "/product/products/v1/organizations/*/products/*",
"action": "confirm"
},
{
"method": "PUT",
"path": "/product/catalogs/v1/organizations/*/catalogs/*/categories/*/products/*",
"action": "confirm"
}
]
}
}The rules apply to every product ID and catalog/category assignment. Reading products does not prompt for approval; other changes remain blocked by READ_ONLY. These rules work without adding confirm: true.
Use your own catalog and category names in this example:
Create an offline test product in my master catalog and add it to the New Arrivals category in my storefront catalog.
Expect one approval prompt to create the product and another to assign it to the category. Each prompt shows the target organization, action, and a short preview of the data being sent. Checking whether the product exists and verifying the result do not need approval.
Approve to continue or decline to stop the task. If you decline the category assignment after approving product creation, the product remains. The B2C tools do not set a time limit for your answer, but your assistant app may. Keep the session connected while you decide.
Approve SCAPI changes across instances
Use one shared policy to review SCAPI changes across your instances. This example asks before PUT, POST, and PATCH requests, allows GET requests without prompting, and blocks DELETE. Save it as your global safety.json:
{
"level": "READ_ONLY",
"rules": [
{
"method": "PUT",
"path": "/*/*/*/organizations/*/**",
"action": "confirm"
},
{
"method": "POST",
"path": "/*/*/*/organizations/*/**",
"action": "confirm"
},
{
"method": "PATCH",
"path": "/*/*/*/organizations/*/**",
"action": "confirm"
}
]
}The * patterns cover SCAPI organization paths across APIs, versions, and organizations, including products, catalogs, jobs, and custom APIs. POST searches also ask for approval. READ_ONLY blocks DELETE and changes outside these paths.
Use this with SCAPI Code Mode and an assistant app that supports approval prompts. If the tool or app cannot ask for approval, it blocks the action.
Save the file in your B2C configuration directory, or select it in the environment that launches your CLI or MCP server:
export SFCC_SAFETY_CONFIG=/path/to/safety.jsonUnlike dw.json, this file has no outer safety key. To use it for just one instance, place the policy under that instance's safety key in dw.json instead. Instance rules take priority over global rules, so an instance-specific allow rule can still permit deletion. Review how settings combine if you use both files.
Run b2c setup inspect to see the settings in use and where they came from. Add --verbose to see all rules in order. SafetyFile in the source column refers to the global file whose path appears in Sources.
Rule matchers
Each example below is one rule in the rules array. For HTTP requests, path matches the part of the URL after the hostname, without query parameters.
HTTP requests: Ask before PUT requests to the SCAPI Products API. Both fields must match; omit either
methodorpathto match on the other alone:json{ "method": "PUT", "path": "/product/products/**", "action": "confirm" }Jobs: Match a job ID in SCAPI or OCAPI job execution requests:
json{ "job": "sfcc-site-archive-import", "action": "block" }CLI commands: Use colons between command words. For example, ask before deploying:
json{ "command": "code:deploy", "action": "confirm" }IDE commands: Use the command ID for a supported extension action:
json{ "command": "b2c-dx.sandbox.delete", "action": "block" }
Patterns support wildcards: * matches within a path segment; ** can span multiple segments.
Require confirmation
Use a confirm rule when you want to approve a specific action. To ask for approval for everything your chosen safety level normally blocks, set confirm: true. For example, this changes NO_DELETE from blocking DELETE requests to asking for approval where the tool supports it:
{
"safety": {
"level": "NO_DELETE",
"confirm": true
}
}An explicit block rule still blocks the action. Requests already allowed by the safety level do not need approval.
| Where you work | What happens |
|---|---|
| CLI in a terminal | Command rules ask in the terminal. Individual API requests can also ask where supported; otherwise the action is blocked. |
| IDE Extension | Supported commands and sandbox actions show a Proceed dialog. Actions that need approval but have no dialog are blocked. |
| Assistant data tasks through SCAPI Code Mode | Asks before each action that needs approval. Your assistant app must support these prompts; otherwise the action is blocked. |
| Other B2C MCP tools | Actions that require Safety Mode approval are currently blocked. |
| Automated scripts and CI without user input | Actions that require approval are blocked because nobody can answer the prompt. |
For assistant tasks, approving one change does not approve later changes. Declining stops the task, but does not undo changes already made.
SFCC_SAFETY_CONFIRM=true or 1 has the same effect as confirm: true. If any configuration source enables it, setting it to false elsewhere does not turn it off. See how settings combine.
Use different policies per instance
Add safety settings to the corresponding entries in your existing configs array. This abbreviated example omits credentials:
{
"configs": [
{
"name": "sandbox",
"active": true,
"hostname": "abcd-001.dx.commercecloud.salesforce.com",
"safety": {"level": "NONE"}
},
{
"name": "production",
"hostname": "production-eu01-example.demandware.net",
"safety": {"level": "READ_ONLY"}
}
]
}Confirm the target before requesting a change. CLI -i production, your assistant's selected target, and the IDE's instance picker can each select a different instance. A stricter environment or global level still applies.
Global safety configuration
The CLI and MCP look for safety.json in their B2C configuration directory:
| Platform | Default location |
|---|---|
| macOS / Linux | ~/.config/b2c/safety.json |
| Windows | %LOCALAPPDATA%\b2c\safety.json |
B2C_CONFIG_DIR or XDG_CONFIG_HOME overrides the base directory, in that order; the file is then <base>/b2c/safety.json.
Use SFCC_SAFETY_CONFIG to select an explicit file, including when sharing it with the IDE extension. The extension currently needs this explicit path to load a separate safety file; an instance's dw.json safety settings need no such setting.
export SFCC_SAFETY_CONFIG=/path/to/safety.jsonSet it in the environment used to launch the tool. For the IDE, restart the editor after changing its launch environment. For the MCP, restart the server connection. The file contains the safety object directly:
{
"level": "NO_DELETE",
"rules": [
{"command": "sandbox:delete", "action": "block"},
{"command": "b2c-dx.sandbox.delete", "action": "block"}
]
}How settings combine
- Safety level: the strictest level from your instance, global file, or environment variables applies.
- Approval for blocked requests: if any source sets
confirm: true, requests blocked by the level can ask for approval. Explicitblockrules still block. - Rules: instance rules are checked before global rules. The first match decides the outcome, so an instance rule can make an exception to a global rule.
- No matching rule: the safety level decides whether the request can proceed.
For example, an instance's NONE level cannot lower a global READ_ONLY level. An instance's explicit allow rule can still permit a particular request. If another source enables confirm: true, DELETE requests blocked by READ_ONLY can ask for approval too. Use an explicit {"method":"DELETE","action":"block"} rule when DELETE must stay blocked even with that setting enabled.
When an operation is blocked
Check the selected instance, the reason in the error, and the applicable rule or level. If the operation is intended, adjust the narrowest relevant rule; changing a broad level may permit more than the current task needs.
For multi-step work, a later blocked request does not undo earlier successful changes. Review what completed before retrying a job, deployment, or API workflow.
Safety Mode controls supported B2C operations. It is not a general restriction on an assistant's other tools or local activity. Keep account permissions, credential handling, and assistant approvals aligned with your intended access. See MCP Security and Access for those controls.
To enforce limits outside the CLI and MCP process, keep your API client secret out of the agent's environment, and record an audit log of every request, run your tools in a sandbox. See Agent Sandboxing.
Environment variables reference
| Variable | Purpose |
|---|---|
SFCC_SAFETY_LEVEL | NONE, NO_DELETE, NO_UPDATE, or READ_ONLY. |
SFCC_SAFETY_CONFIRM | true or 1 enables confirmation mode. |
SFCC_SAFETY_CONFIG | Path to the shared safety JSON file. |