From ec0e5af69271c38c0a63f0c7f30738b5590ef5c8 Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 11:45:21 -0400 Subject: [PATCH 1/8] Add b2c-setup skill and Realm Setup guide Orchestrator skill for sandbox and realm setup (storefront datasets, search indexes, Storefront Next storefronts, replication) with confirmation before changes to shared instances. Featured in the MCP skill listing and server instructions. --- .changeset/b2c-setup-skill.md | 6 + .changeset/realm-setup-guide.md | 5 + docs/.vitepress/config.mts | 1 + docs/guide/operations.md | 2 + docs/guide/realm-setup.md | 158 ++++++++++++++++++ docs/guide/safety.md | 2 + docs/guide/storefront-next.md | 2 + docs/guide/workflows.md | 1 + .../b2c-dx-mcp/skills/b2c-mcp-server/SKILL.md | 1 + packages/b2c-dx-mcp/skills/collections.json | 1 + packages/b2c-dx-mcp/src/commands/mcp.ts | 1 + packages/b2c-dx-mcp/test/e2e/guidance.test.ts | 11 +- .../b2c-tooling-sdk/data/tooling/index.json | 11 +- skills/b2c-cli/README.md | 1 + .../b2c-cli/skills/b2c-replication/SKILL.md | 1 + skills/b2c-cli/skills/b2c-sandbox/SKILL.md | 2 + skills/b2c-cli/skills/b2c-setup/SKILL.md | 66 ++++++++ .../skills/b2c-setup/evals/trigger-evals.json | 30 ++++ .../skills/b2c-setup/references/DATASETS.md | 68 ++++++++ .../skills/b2c-setup/references/REALM.md | 60 +++++++ .../skills/b2c-setup/references/SAFETY.md | 53 ++++++ .../skills/b2c-setup/references/SANDBOX.md | 50 ++++++ .../skills/b2c-site-import-export/SKILL.md | 1 + .../b2c-cli/skills/b2c-storefronts/SKILL.md | 1 + 24 files changed, 532 insertions(+), 3 deletions(-) create mode 100644 .changeset/b2c-setup-skill.md create mode 100644 .changeset/realm-setup-guide.md create mode 100644 docs/guide/realm-setup.md create mode 100644 skills/b2c-cli/skills/b2c-setup/SKILL.md create mode 100644 skills/b2c-cli/skills/b2c-setup/evals/trigger-evals.json create mode 100644 skills/b2c-cli/skills/b2c-setup/references/DATASETS.md create mode 100644 skills/b2c-cli/skills/b2c-setup/references/REALM.md create mode 100644 skills/b2c-cli/skills/b2c-setup/references/SAFETY.md create mode 100644 skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md diff --git a/.changeset/b2c-setup-skill.md b/.changeset/b2c-setup-skill.md new file mode 100644 index 000000000..7e6b91d27 --- /dev/null +++ b/.changeset/b2c-setup-skill.md @@ -0,0 +1,6 @@ +--- +'@salesforce/b2c-agent-plugins': minor +'@salesforce/b2c-dx-mcp': minor +--- + +New `b2c-setup` skill guides your assistant through setting up a sandbox or realm: sample storefront datasets, search indexes, Storefront Next storefronts, and replication to production, with confirmation before changes to shared instances. The MCP server features it in its skill listing. diff --git a/.changeset/realm-setup-guide.md b/.changeset/realm-setup-guide.md new file mode 100644 index 000000000..193379fde --- /dev/null +++ b/.changeset/realm-setup-guide.md @@ -0,0 +1,5 @@ +--- +'@salesforce/b2c-dx-docs': patch +--- + +New Realm Setup guide covers sandbox and realm setup with the storefront datasets, Storefront Next storefronts, replication, and Safety Mode policies for shared instances. diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index ddafba74b..a42f1db1c 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -165,6 +165,7 @@ const guidesSidebar: DefaultTheme.SidebarItem[] = [ text: 'Operations & Administration', collapsed: false, items: [ + {text: 'Realm Setup', link: '/guide/realm-setup'}, {text: 'Operations', link: '/guide/operations'}, {text: 'Account Manager', link: '/guide/account-manager'}, {text: 'Analytics Reports', link: '/guide/analytics-reports-cip-ccac'}, diff --git a/docs/guide/operations.md b/docs/guide/operations.md index 1997082ab..d5b55394b 100644 --- a/docs/guide/operations.md +++ b/docs/guide/operations.md @@ -27,6 +27,8 @@ investigations also need the [B2C CLI](./installation), Business Manager access, or information from an integration provider. See [authentication](./authentication) and [Safety Mode](./safety) for access and operation controls. +To set up a new sandbox or realm, see [Realm Setup](./realm-setup). + ## Understand settings and procedures Use [documentation search](../mcp/#b2c-commerce-documentation) to understand diff --git a/docs/guide/realm-setup.md b/docs/guide/realm-setup.md new file mode 100644 index 000000000..ff2d7c8d6 --- /dev/null +++ b/docs/guide/realm-setup.md @@ -0,0 +1,158 @@ +--- +description: Set up a new sandbox or realm with sample storefront data, search indexes, Storefront Next storefronts, and replication from staging to production. +--- + +# Realm Setup + +Take a new sandbox or realm from an empty instance to a working storefront with the B2C CLI and your AI assistant. Load a sample site from the storefront datasets, rebuild search indexes, set up a Storefront Next storefront, and replicate from staging to production. + +The `b2c-setup` skill guides your assistant through these steps. The [B2C MCP](../mcp/) features it, and the [b2c-cli plugin](./agent-skills#available-plugins) includes it. + +## Before You Start + +- Configure each instance: see [Configuration](./configuration). For a realm, add a named instance for staging, production, and any development instance. +- Use an API client with access to every instance. See [Account Manager](./account-manager) and [Authentication](./authentication). +- Check the setup with `b2c setup inspect -i `. + +### Protect Shared Instances + +Staging, production, and development are shared instances. A site import there can change global settings, such as active locales and the instance time zone, for every site. Production and development get code and data from staging by replication; do not import site data on them directly. + +Add a [Safety Mode](./safety) policy to each shared instance. With `confirm: true`, the CLI asks before an action the safety level blocks: + +```json +{ + "configs": [ + { + "name": "sandbox", + "hostname": "abcd-001.dx.commercecloud.salesforce.com", + "safety": {"level": "NONE"} + }, + { + "name": "staging", + "hostname": "staging-abcd-example.demandware.net", + "safety": {"level": "NO_DELETE", "confirm": true} + }, + { + "name": "production", + "hostname": "production-abcd-example.demandware.net", + "safety": {"level": "READ_ONLY", "confirm": true} + } + ] +} +``` + +See [per-instance policies](./safety#per-instance-configuration) and [confirmation](./safety#confirmation-mode). The `b2c-setup` skill also tells your assistant to name the target instance and wait for your approval before each change to a shared instance. + +## Storefront Datasets + +Salesforce publishes sample data for the reference storefronts in [storefront-datasets](https://github.com/SalesforceCommerceCloud/storefront-datasets). Each dataset is a site archive with a site, catalogs, price books, inventory, content, and promotions. + +| Dataset directory | Site ID | +| ------------------ | -------------- | +| `foundations-data` | `Foundations` | +| `marketstreet` | `MarketStreet` | +| `beautynext` | `BeautyNext` | +| `footwear-data` | `Footwear` | +| `furniture-data` | `Furniture` | +| `luxury-data` | `Luxury` | + +Releases are tagged with the Storefront Next template version they target, such as `v1.4.0`. Use the release that matches your storefront's template. Each release also attaches a ZIP per dataset. + +```bash +git clone --branch v1.4.0 --depth 1 https://github.com/SalesforceCommerceCloud/storefront-datasets.git +``` + +`b2c job import` accepts a directory, so you do not need to zip a dataset first. Add `--split` if the upload is too large for one import. On an instance that already has sites, review the dataset's `preferences.xml` and other top-level files before you import it. + +## Set Up a Sandbox + +Sandboxes have no replication: import data and set up the storefront directly. + +```bash +# Create a sandbox (billable) and save a connection for it +b2c sandbox create --realm abcd --ttl 0 --wait +b2c setup instance create my-sandbox --hostname abcd-001.dx.commercecloud.salesforce.com --active + +# Import a dataset and rebuild search indexes +b2c job import ./storefront-datasets/marketstreet --show-log +b2c job run Reindex --wait +b2c sites list + +# Create a Storefront Next storefront for the site +b2c mrt project create "Market Street" --site MarketStreet --mrt-backend scapi +``` + +The Foundations, Market Street, and Beauty Next datasets include a `Reindex` job. For other sites, run the system search index jobs; see [system jobs with custom request bodies](/cli/jobs#system-jobs-with-custom-request-bodies). + +Storefront creation runs asynchronously. Check progress with `b2c mrt project get -p --mrt-backend scapi`, then get the project configuration from the storefront in Business Manager. You can also use **storefront setup in Business Manager** instead of `mrt project create`; see [Storefront Next](./storefront-next#start-with-storefront-setup). + + + +> Set up my sandbox my-sandbox with the Market Street dataset for Storefront Next 1.4.0: import it, rebuild the search indexes, and create a Storefront Next storefront for the site. + + + +## Set Up a Realm + +Set up staging completely, then replicate to production and development, then connect the storefront on each target. + +### 1. Prepare Staging + +Import your site data, or a dataset for a demo site, rebuild the search indexes, and create the storefront: + +```bash +b2c job import ./storefront-datasets/marketstreet -i staging --show-log +b2c job run Reindex -i staging --wait +b2c mrt project create "Market Street" --site MarketStreet -i staging --mrt-backend scapi +``` + +For cartridge storefronts, deploy and activate a code version; see [code commands](/cli/code). + +### 2. Replicate to Production + +Replicate from staging with replication jobs in three steps: code, global data, then site data. Global data creates the site on the target, so on the first replication, run it before site data. The `b2c-replication` skill has the job definitions. + +```bash +b2c job run Replicate-Code -i staging --wait --show-log +b2c job run Replicate-Global -i staging --wait --show-log +b2c job run Replicate-MarketStreet -i staging --wait --show-log +``` + +Replication changes production. Review what each job replicates before you run it. + +### 3. Connect the Storefront + +Storefronts do not replicate. Creating a storefront on production makes a second Managed Runtime project. To keep staging and production in one project, export the storefront from staging and import it on production: + +```bash +b2c job export --storefront market-street -i staging --output ./storefront-export +b2c job import ./storefront-export/ -i production --wait-for-storefront --show-log +``` + +The storefront import requires the `user-id` in the export to be an Account Manager user who is authorized for the target. An export made with client credentials records the API client's service user; edit `user-id` before importing. Verify with `b2c mrt env list -p -i production --mrt-backend scapi`. + + + +> Our new realm has staging and production configured. Set up the Market Street dataset on staging with a Storefront Next storefront, then replicate it to production and connect the same Managed Runtime project there. Ask me before each change. + + + +## Troubleshooting + +| Problem | What to check | +| --------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| Import fails with a generic error | Rerun with `--show-log`; the cause is in the `[DATAERROR]` lines. | +| `There must be a root directory with the same name as the archive` | Rename the ZIP or its root folder to match. | +| Search returns no products | Rebuild the search indexes on that instance. | +| First site replication fails with `Optimistic locking failure` or a generic error | Replicate global data first, then site data, as separate jobs. | +| Storefront import reports a user that is not authorized | Set `user-id` in the exported storefront XML to an authorized user. | + +When something fails after launch, see [Operations](./operations). + +## Related + +- [Storefront Next](./storefront-next) — environment variables, logs, and deployments after setup +- [Operations](./operations) — job health and incident investigation +- [Safety Mode](./safety) — policies and confirmation for shared instances +- [Sandbox commands](/cli/sandbox), [Job commands](/cli/jobs), [MRT commands](/cli/mrt) diff --git a/docs/guide/safety.md b/docs/guide/safety.md index 8c37359a0..6c5aa9002 100644 --- a/docs/guide/safety.md +++ b/docs/guide/safety.md @@ -413,6 +413,8 @@ array. This abbreviated example omits credentials: } ``` +For a realm setup example, see [Realm Setup](./realm-setup#protect-shared-instances). + 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. diff --git a/docs/guide/storefront-next.md b/docs/guide/storefront-next.md index be36ff703..6410a03b6 100644 --- a/docs/guide/storefront-next.md +++ b/docs/guide/storefront-next.md @@ -18,6 +18,8 @@ Use **storefront setup in Business Manager** to create your storefront and its A - [Create Storefront Next with a GitHub repository](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-bm-github.html) - [Create Storefront Next with local code](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-bm.html) +To load a sample site first, or to set up a new sandbox or realm end to end, see [Realm Setup](./realm-setup). + Use the generated configuration for local development and the existing MRT resources for the operations below. For additional environments and production launch, follow [Launch Your Storefront Next](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-mrt-launch-storefront.html). ## Prerequisites diff --git a/docs/guide/workflows.md b/docs/guide/workflows.md index a83e015af..0bf22a11d 100644 --- a/docs/guide/workflows.md +++ b/docs/guide/workflows.md @@ -26,6 +26,7 @@ See [Project Setup](./project-setup) for optional assistant instructions and tea ## Operations and administration +- [Realm setup](./realm-setup) - Set up a sandbox or realm with sample data, storefronts, and replication. - [Operations](./operations) - Review job health, investigate incidents, and prepare team or Support handoffs. - [Account Manager](./account-manager) - Manage users, organizations, roles, and API clients. - [Analytics reports](./analytics-reports-cip-ccac) - Query B2C Commerce data and run reports. diff --git a/packages/b2c-dx-mcp/skills/b2c-mcp-server/SKILL.md b/packages/b2c-dx-mcp/skills/b2c-mcp-server/SKILL.md index 5422574e4..adfb7906c 100644 --- a/packages/b2c-dx-mcp/skills/b2c-mcp-server/SKILL.md +++ b/packages/b2c-dx-mcp/skills/b2c-mcp-server/SKILL.md @@ -11,6 +11,7 @@ Read only the skill that matches the task; each links its own references. | Task | Skill | | --- | --- | +| Set up a sandbox or realm: sample data, storefronts, replication | `skill://b2c-cli/b2c-setup/SKILL.md` | | Commerce API reads/writes (required before `scapi_search` / `scapi_execute`) | `skill://mcp/b2c-mcp-scapi/SKILL.md` | | Warehouse reports and SQL (required before `cip_query`) | `skill://mcp/b2c-mcp-cip/SKILL.md` | | Configuration, credentials, access grants, wrong target | `skill://mcp/b2c-mcp-config/SKILL.md` | diff --git a/packages/b2c-dx-mcp/skills/collections.json b/packages/b2c-dx-mcp/skills/collections.json index b1ab825d0..4b92f7cbc 100644 --- a/packages/b2c-dx-mcp/skills/collections.json +++ b/packages/b2c-dx-mcp/skills/collections.json @@ -2,6 +2,7 @@ "version": 1, "featuredResources": [ "mcp/b2c-mcp-server", + "b2c-cli/b2c-setup", "mcp/b2c-mcp-debugger", "mcp/b2c-mcp-config", "mcp/b2c-mcp-scapi", diff --git a/packages/b2c-dx-mcp/src/commands/mcp.ts b/packages/b2c-dx-mcp/src/commands/mcp.ts index 400e73514..bdbe4c05d 100644 --- a/packages/b2c-dx-mcp/src/commands/mcp.ts +++ b/packages/b2c-dx-mcp/src/commands/mcp.ts @@ -464,6 +464,7 @@ export default class McpServerCommand extends BaseCommand"}). ' + 'SCAPI: first read skill://mcp/b2c-mcp-scapi/SKILL.md. ' + 'Analytics: cip_discover/cip_query; skill://mcp/b2c-mcp-cip/SKILL.md. ' + + 'New sandbox or realm setup (sample data, storefronts, replication): first read skill://b2c-cli/b2c-setup/SKILL.md. ' + 'Production incidents (slow or failing storefront/APIs, external service failures, jobs, orders): first read skill://b2c-ops/b2c-production-triage/SKILL.md. ' + 'Missing credentials in config do not mean unauthenticated: instance tools may sign in through Account Manager in the browser; resolution.auth and config_inspect show how. ' + 'Config, auth and deploy prerequisites skill://mcp/b2c-mcp-config/SKILL.md; debugging skill://mcp/b2c-mcp-debugger/SKILL.md; artifacts or dashboards skill://mcp/b2c-mcp-claude-artifacts/SKILL.md; ' + diff --git a/packages/b2c-dx-mcp/test/e2e/guidance.test.ts b/packages/b2c-dx-mcp/test/e2e/guidance.test.ts index 6a896d247..2d3a71f96 100644 --- a/packages/b2c-dx-mcp/test/e2e/guidance.test.ts +++ b/packages/b2c-dx-mcp/test/e2e/guidance.test.ts @@ -203,11 +203,16 @@ describe('guidance over real stdio', function () { 'b2c-mcp-debugger', 'b2c-mcp-scapi', 'b2c-mcp-server', + 'b2c-setup', 'skill-index', ]); for (const resource of listed.resources) { expect(resource.uri).to.equal( - resource.name === 'skill-index' ? 'skill://index' : `skill://mcp/${resource.name}/SKILL.md`, + resource.name === 'skill-index' + ? 'skill://index' + : resource.name === 'b2c-setup' + ? 'skill://b2c-cli/b2c-setup/SKILL.md' + : `skill://mcp/${resource.name}/SKILL.md`, ); expect(resource.description.length).to.be.within(1, 1024); } @@ -243,9 +248,11 @@ describe('guidance over real stdio', function () { 'b2c-mcp-debugger', 'b2c-mcp-scapi', 'b2c-mcp-server', + 'b2c-setup', ]); for (const skill of skills) { - expect(skill.uri).to.equal(`skill://mcp/${skill.frontmatter.name}/SKILL.md`); + const collection = skill.frontmatter.name === 'b2c-setup' ? 'b2c-cli' : 'mcp'; + expect(skill.uri).to.equal(`skill://${collection}/${skill.frontmatter.name}/SKILL.md`); expect(skill.resources.map((resource) => resource.uri)).to.include(skill.uri); for (const resource of skill.resources) { const {contents} = (await client.call('resources/read', {uri: resource.uri})) as {contents: {text: string}[]}; diff --git a/packages/b2c-tooling-sdk/data/tooling/index.json b/packages/b2c-tooling-sdk/data/tooling/index.json index e7982fcde..5d399d7d8 100644 --- a/packages/b2c-tooling-sdk/data/tooling/index.json +++ b/packages/b2c-tooling-sdk/data/tooling/index.json @@ -1,6 +1,6 @@ { "version": "2.0.0", - "generatedAt": "2026-10-29T20:38:17.710Z", + "generatedAt": "2026-10-29T22:13:29.774Z", "entries": [ { "id": "cli-account-manager", @@ -443,6 +443,15 @@ "headings": "Give your assistant project context • Salesforce B2C Commerce • Add your team's conventions", "preview": "Optional project recommendations for working with the Agentic B2C Developer Toolkit and your AI assistant." }, + { + "id": "guide-realm-setup", + "title": "Realm Setup", + "category": "tooling", + "url": "https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/realm-setup.html", + "sourceUrl": "https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/realm-setup.md", + "headings": "Before You Start • Protect Shared Instances • Storefront Datasets • Set Up a Sandbox • Set Up a Realm • 1. Prepare Staging • 2. Replicate to Production • 3. Connect the Storefront • Troubleshooting • Related", + "preview": "Set up a new sandbox or realm with sample storefront data, search indexes, Storefront Next storefronts, and replication from staging to production." + }, { "id": "guide-safety", "title": "Safety Mode", diff --git a/skills/b2c-cli/README.md b/skills/b2c-cli/README.md index 87a8cd35a..f045f8ea2 100644 --- a/skills/b2c-cli/README.md +++ b/skills/b2c-cli/README.md @@ -26,6 +26,7 @@ For file-copy install to any supported IDE, use `b2c setup skills b2c-cli`. See Skills covering the major B2C CLI surfaces: +- **`b2c-setup`** — start here to set up a sandbox or realm: sample data, storefronts, and replication - **`b2c-code`** — cartridge deploy, code version management, watch mode - **`b2c-sandbox`** — On-Demand Sandbox lifecycle - **`b2c-job`** — job execution and monitoring diff --git a/skills/b2c-cli/skills/b2c-replication/SKILL.md b/skills/b2c-cli/skills/b2c-replication/SKILL.md index 5c27531d5..96a193b4f 100644 --- a/skills/b2c-cli/skills/b2c-replication/SKILL.md +++ b/skills/b2c-cli/skills/b2c-replication/SKILL.md @@ -114,6 +114,7 @@ Keep the global and site jobs separate so the same jobs work for new and existin ## Related Skills +- `b2c-cli:b2c-setup` — end-to-end realm setup, including where replication fits - `b2c-cli:b2c-job` — run, wait for, and inspect jobs - `b2c:b2c-custom-job-steps` — `jobs.xml` format, triggers, and custom steps - `b2c-cli:b2c-storefronts` — moving Storefront Next storefronts between instances diff --git a/skills/b2c-cli/skills/b2c-sandbox/SKILL.md b/skills/b2c-cli/skills/b2c-sandbox/SKILL.md index 62ede43a4..3385e362e 100644 --- a/skills/b2c-cli/skills/b2c-sandbox/SKILL.md +++ b/skills/b2c-cli/skills/b2c-sandbox/SKILL.md @@ -11,6 +11,8 @@ Use the `b2c` CLI plugin to manage Salesforce B2C Commerce On-demand sandboxes ( > **Tip:** If `b2c` is not installed globally, use `npx @salesforce/b2c-cli` instead (e.g., `npx @salesforce/b2c-cli sandbox list`). +> **Setup:** To load sample data and a storefront on a new sandbox, use `b2c-cli:b2c-setup`. + > **Alias:** The `ods` prefix is still supported as a backward-compatible alias (e.g., `b2c ods list` works the same as `b2c sandbox list`). ## Configuration & Authentication diff --git a/skills/b2c-cli/skills/b2c-setup/SKILL.md b/skills/b2c-cli/skills/b2c-setup/SKILL.md new file mode 100644 index 000000000..440b8d623 --- /dev/null +++ b/skills/b2c-cli/skills/b2c-setup/SKILL.md @@ -0,0 +1,66 @@ +--- +name: b2c-setup +description: Plan and run end-to-end setup of a B2C Commerce sandbox or realm (staging, production, development) with the b2c CLI — sample storefront data, sites, search indexes, code, Storefront Next storefronts, and replication — with confirmation before changes to shared instances. Use this skill whenever the user wants to set up a new sandbox or realm, load demo or sample data, stand up a storefront on a fresh instance, or get production ready from staging — even if they just say "set up my new realm" or "get Market Street running on my sandbox". For CLI connection settings alone, use b2c-cli:b2c-config. +--- + +# B2C Setup Skill + +Set up a B2C Commerce sandbox or realm from an empty instance to a working storefront. This skill is an index: pick the path for the target, follow its reference, and use the workflow catalog for product- or feature-specific steps. + +> **Tip:** If `b2c` is not installed globally, use `npx @salesforce/b2c-cli` instead (for example, `npx @salesforce/b2c-cli sites list`). + +## Safety First + +Classify every target before changing it. Staging, production, and development instances are shared and can serve live traffic; imports and replication there change global settings for every site on the instance. + +| Target | Before each change | +| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- | +| Sandbox | Confirm creating (billable) or deleting a sandbox. Imports and storefront setup can proceed once the user asked. | +| Staging, production, development instances | State the instance hostname and the exact change, then wait for explicit approval. Ask again for each separate change. | + +- Never infer that a target is a sandbox from a configuration name; check the hostname (see [safety](references/SAFETY.md)). +- Approval for one instance or step does not carry to the next. +- Production and development receive code and data by replication from staging. Do not import site data there directly; the storefront record is the exception (see `b2c-cli:b2c-storefronts`). + +Recommend Safety Mode for shared instances: [safety](references/SAFETY.md). + +## Choose a Path + +| Goal | Path | +| --------------------------------------------------------- | --------------------------------------------- | +| A development sandbox with sample data and a storefront | [Sandbox setup](references/SANDBOX.md) | +| A new realm: staging first, then production / development | [Realm setup](references/REALM.md) | +| Sample sites, catalogs, and content for any instance | [Storefront datasets](references/DATASETS.md) | +| Add an instance to an existing Storefront Next project | `b2c-cli:b2c-storefronts` | + +Every path starts the same way: + +1. **Connect.** Configure the instance and API client, then check with `b2c setup inspect`. See `b2c-cli:b2c-config`; API clients and roles: `b2c-cli:b2c-am`. +2. **Check what exists.** `b2c sites list` and `b2c code list` show existing sites and code versions. Do not overwrite existing sites or settings without approval. +3. **Load data** (staging or sandbox only), then **rebuild search indexes**. +4. **Deploy code** for the storefront type (cartridges, or a Storefront Next storefront). +5. **Verify** each step before starting the next. + +## Workflow Catalog + +Steps that depend on the product line, license, or feature. Use only the rows that apply to the user's realm. + +| Workflow | Applies to | Guidance | +| ------------------------------------------ | ------------------------------------------ | -------------------------------------------------------------------- | +| Instance connection, API clients, roles | All | `b2c-cli:b2c-config`, `b2c-cli:b2c-am`, `b2c-cli:b2c-bm-users-roles` | +| Sample data and search indexes | All | [Storefront datasets](references/DATASETS.md), `b2c-cli:b2c-job` | +| Site archives and custom data | All | `b2c-cli:b2c-site-import-export` | +| Code and data replication | Realms (staging to production/development) | `b2c-cli:b2c-replication` | +| Storefront Next storefront and MRT project | Storefront Next | `b2c-cli:b2c-storefronts`, `b2c-cli:b2c-mrt` | +| Cartridge storefronts (SFRA) | Cartridge-based storefronts | `b2c-cli:b2c-code`, `b2c-cli:b2c-sites` | +| Shopper authentication (SLAS) | Headless and composable storefronts | `b2c-cli:b2c-slas` | +| Commerce apps | Commerce apps | `b2c-cli:b2c-cap` | +| eCDN zones and certificates | Storefronts on eCDN | `b2c-cli:b2c-ecdn` | + +## Related Skills + +- [Realm Setup guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/realm-setup.md) (`b2c docs read guide-realm-setup`) — the user-facing version of this skill +- `b2c-cli:b2c-sandbox` — create, start, stop, and clone sandboxes +- `b2c-cli:b2c-storefronts` — create or import Storefront Next storefronts +- `b2c-cli:b2c-replication` — replication jobs for staging +- `b2c-ops:b2c-production-triage` — investigate problems after launch diff --git a/skills/b2c-cli/skills/b2c-setup/evals/trigger-evals.json b/skills/b2c-cli/skills/b2c-setup/evals/trigger-evals.json new file mode 100644 index 000000000..478c4b3a2 --- /dev/null +++ b/skills/b2c-cli/skills/b2c-setup/evals/trigger-evals.json @@ -0,0 +1,30 @@ +[ + { + "query": "We just got a new realm provisioned. Walk me through getting staging and production set up with a working Storefront Next storefront.", + "should_trigger": true + }, + {"query": "Get Market Street running on my new sandbox — data, search, and the storefront.", "should_trigger": true}, + { + "query": "How do I load the sample storefront datasets onto my instance before I set up the storefront?", + "should_trigger": true + }, + { + "query": "I want a demo sandbox with sample products and a Storefront Next storefront. What are the steps with the b2c CLI?", + "should_trigger": true + }, + { + "query": "Staging is set up with our site and storefront. What's the order of steps to get production ready?", + "should_trigger": true + }, + { + "query": "Which dataset release should I use for Storefront Next template 1.4 and how do I import it?", + "should_trigger": true + }, + {"query": "Delete my sandbox abcd-003.", "should_trigger": false}, + { + "query": "My storefront import on production failed with 'is not authorized to import storefront'. What do I fix?", + "should_trigger": false + }, + {"query": "Add my client secret to dw.json for the staging instance.", "should_trigger": false}, + {"query": "Checkout conversion dropped on production in the last hour. Help me investigate.", "should_trigger": false} +] diff --git a/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md b/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md new file mode 100644 index 000000000..2769ecf82 --- /dev/null +++ b/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md @@ -0,0 +1,68 @@ +# Storefront Datasets + +Salesforce publishes sample data for the reference storefronts in [storefront-datasets](https://github.com/SalesforceCommerceCloud/storefront-datasets). Each dataset is a site archive with a site, catalogs, price books, inventory, content, promotions, and import jobs. + +| Dataset directory | Site ID | Contents | +| ------------------ | -------------- | ---------------------------------------------------- | +| `foundations-data` | `Foundations` | Small default dataset for the Foundations storefront | +| `marketstreet` | `MarketStreet` | Fashion catalog for the Market Street storefront | +| `beautynext` | `BeautyNext` | Cosmetics catalog with shade variants and bundles | +| `footwear-data` | `Footwear` | Footwear vertical | +| `furniture-data` | `Furniture` | Furniture vertical | +| `luxury-data` | `Luxury` | Luxury vertical | + +Check the repository README for the current list. + +## Pick a Version + +Releases are tagged with the Storefront Next template version they target (`vX.Y.Z`; dataset-only fixes are `vX.Y.Z-data.N`). Match the template version of your storefront. Each GitHub release attaches one ZIP per dataset, images included. + +```bash +# Clone the datasets for template 1.4.0 +git clone --branch v1.4.0 --depth 1 https://github.com/SalesforceCommerceCloud/storefront-datasets.git +``` + +## Import + +Import on a **sandbox** or **staging** instance only; production and development get the data by replication. On staging, confirm first (see [safety](SAFETY.md)). + +```bash +# Directory import: no zip needed +b2c job import ./storefront-datasets/marketstreet --show-log + +# A release ZIP works too (the root folder matches the zip name) +b2c job import ./marketstreet.zip --show-log +``` + +If a directory with images exceeds the instance upload limit, add `--split` to import the XML first and the static files in later parts. + +A dataset contains global data as well as its site: preferences (active locales, instance time zone), customer lists, geolocations, and jobs. On an instance that already has sites, review `preferences.xml` and the other top-level files before importing, and remove what should not change. + +## Rebuild Search Indexes + +Products are not searchable until the indexes are rebuilt. The Foundations, Market Street, and Beauty Next datasets include a `Reindex` job: + +```bash +b2c job run Reindex --wait +``` + +For any site, run the system index jobs: + +```bash +b2c job run sfcc-search-index-product-full-update --wait --body '{"site_scope":["MarketStreet"]}' +b2c job run sfcc-search-index-content-full-update --wait --body '{"site_scope":["MarketStreet"]}' +``` + +## Verify + +```bash +b2c sites list +``` + +The dataset's site should be listed. Then set up the storefront: `b2c-cli:b2c-storefronts` for Storefront Next. + +## Common Problems + +- **"There must be a root directory with the same name as the archive."** Rename the ZIP or its root folder so they match. +- **Inventory quota errors on `allocation-timestamp`.** Remove the field from custom inventory files or set it to the current UTC time. +- **Import failed with a generic error.** Rerun with `--show-log`; the cause is in the `[DATAERROR]` lines. diff --git a/skills/b2c-cli/skills/b2c-setup/references/REALM.md b/skills/b2c-cli/skills/b2c-setup/references/REALM.md new file mode 100644 index 000000000..2242063ee --- /dev/null +++ b/skills/b2c-cli/skills/b2c-setup/references/REALM.md @@ -0,0 +1,60 @@ +# Realm Setup + +A realm's staging instance is the source of code and data; production and development receive them by replication. Set up staging completely, then replicate, then connect the storefront on each target. + +Every step below changes a shared instance. Before each one, give the hostname and command and wait for approval (see [safety](SAFETY.md)). + +## 1. Connect All Instances + +Configure a named instance for staging, production, and development, with Safety Mode policies (see [safety](SAFETY.md)). Use the same API client on every instance where possible. + +```bash +b2c setup instance list +b2c setup inspect -i staging +``` + +## 2. Prepare Staging + +1. **Data.** Import your site archives, or a [storefront dataset](DATASETS.md) for a demo site, then rebuild the search indexes. + + ```bash + b2c job import ./storefront-datasets/marketstreet -i staging --show-log + b2c job run Reindex -i staging --wait + ``` + +2. **Code.** For cartridge storefronts, deploy and activate a code version (`b2c-cli:b2c-code`). Staging code uploads may need a certificate: see the [Hyperforce guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/hyperforce.md) (`b2c docs read guide-hyperforce`). +3. **Storefront.** For Storefront Next, create the storefront on staging (Business Manager storefront setup, or `b2c mrt project create "My Storefront" --site MySite -i staging --mrt-backend scapi`). See `b2c-cli:b2c-storefronts`. +4. **Verify** the site on staging before replicating. + +## 3. Replicate to Production or Development + +Use replication jobs on staging (`b2c-cli:b2c-replication`): + +1. Code (if staging has a code version to replicate). +2. Global data, which creates the site on the target. +3. Site data. + +The first replication of a site must run global data before site data; a combined run fails. Replication applies to everything the configuration selects, so confirm the tasks with the user. + +```bash +b2c job run Replicate-Code -i staging --wait --show-log +b2c job run Replicate-Global -i staging --wait --show-log +b2c job run Replicate-MySite -i staging --wait --show-log +``` + +## 4. Connect the Storefront on Each Target + +Storefronts do not replicate. To keep production and staging in one MRT project, export the storefront from staging and import it on the target; creating a storefront there makes a second project. + +```bash +b2c job export --storefront my-storefront -i staging --output ./storefront-export +b2c job import ./storefront-export/ -i production --wait-for-storefront --show-log +``` + +Requirements and troubleshooting: `b2c-cli:b2c-storefronts`. + +## 5. Verify + +- `b2c sites list -i production` shows the replicated site. +- `b2c mrt env list -p -i production --mrt-backend scapi` shows a production environment in the same project as staging. +- Rebuild search indexes on the target if search returns no products. diff --git a/skills/b2c-cli/skills/b2c-setup/references/SAFETY.md b/skills/b2c-cli/skills/b2c-setup/references/SAFETY.md new file mode 100644 index 000000000..e867bf4c2 --- /dev/null +++ b/skills/b2c-cli/skills/b2c-setup/references/SAFETY.md @@ -0,0 +1,53 @@ +# Setup Safety + +## Identify the Instance + +Check the configured hostname (`b2c setup inspect`), not the configuration name. + +| Hostname | Instance | +| -------------------------------------------------- | ----------- | +| `-.dx.commercecloud.salesforce.com` | Sandbox | +| Starts with `staging-` (on `demandware.net`) | Staging | +| Starts with `production-` (on `demandware.net`) | Production | +| Starts with `development-` (on `demandware.net`) | Development | + +Use `b2c sandbox list` to confirm a sandbox belongs to the expected realm. Hosts on a custom domain or another pattern count as shared instances until the user confirms otherwise. + +## Confirm Changes + +On staging, production, and development, describe and get approval before: + +- importing any site archive or dataset (imports change global settings such as locales, time zone, and preferences); +- running replication, search index rebuilds, or other jobs that change data; +- deploying or activating a code version; +- creating, importing, or deleting a storefront or MRT project. + +Include the hostname, the exact command, and what changes. Ask again if the plan changes. A job that reports OK can still leave data incomplete; verify before the next step. + +## Safety Mode + +Safety Mode adds a second check that also applies to your assistant. Add a policy to each shared instance in `dw.json`: + +```json +{ + "configs": [ + { + "name": "sandbox", + "hostname": "abcd-001.dx.commercecloud.salesforce.com", + "safety": {"level": "NONE"} + }, + { + "name": "staging", + "hostname": "staging-abcd-example.demandware.net", + "safety": {"level": "NO_DELETE", "confirm": true} + }, + { + "name": "production", + "hostname": "production-abcd-example.demandware.net", + "safety": {"level": "READ_ONLY", "confirm": true} + } + ] +} +``` + +With `confirm: true`, blocked actions ask for approval in an interactive terminal and are blocked in CI. To require approval for specific commands everywhere, add command rules such as `{"command": "job:import", "action": "confirm"}`. An assistant running commands has no terminal to answer the prompt, so those commands are blocked. Give the user the command to run in their own terminal; do not change or remove the safety policy to get past a block. See the [Safety Mode guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/safety.md) (`b2c docs read guide-safety`). diff --git a/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md b/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md new file mode 100644 index 000000000..99b681ca9 --- /dev/null +++ b/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md @@ -0,0 +1,50 @@ +# Sandbox Setup + +A development sandbox with a sample site and a Storefront Next storefront. Sandboxes have no replication; load data and set up the storefront directly. + +## 1. Create and Connect + +Create a sandbox only when the user asks (it can be billable); see `b2c-cli:b2c-sandbox`. + +```bash +b2c sandbox create --realm abcd --ttl 0 --wait --json +``` + +`--ttl 0` keeps the sandbox until deleted; the default is 24 hours. The sandbox grants OCAPI and WebDAV permissions to your API client by default. + +Save a connection for the new host and select it: + +```bash +b2c setup instance create my-sandbox --hostname abcd-001.dx.commercecloud.salesforce.com --active +b2c setup inspect +``` + +See `b2c-cli:b2c-config` for credentials and the SCAPI short code and tenant ID. + +## 2. Load Sample Data + +Import a storefront dataset and rebuild its search indexes: [storefront datasets](DATASETS.md). + +```bash +b2c job import ./storefront-datasets/marketstreet --show-log +b2c job run Reindex --wait +b2c sites list +``` + +## 3. Set Up the Storefront + +For Storefront Next, create the storefront for the imported site. Business Manager storefront setup also works. + +```bash +b2c mrt project create "Market Street" --site MarketStreet --mrt-backend scapi +``` + +Setup provisions the MRT project and environment, API and SLAS clients, and eCDN. It runs asynchronously; check progress with `b2c mrt project get -p --mrt-backend scapi`. Then download the project configuration from the storefront's detail page in Business Manager. Details: `b2c-cli:b2c-storefronts`. + +For a cartridge storefront, deploy the cartridges and set the site's cartridge path instead (`b2c-cli:b2c-code`, `b2c-cli:b2c-sites`). + +## 4. Verify + +- `b2c sites list` shows the site online. +- `b2c mrt env list -p --mrt-backend scapi` shows the storefront's environment. +- A storefront search returns products (indexes rebuilt). diff --git a/skills/b2c-cli/skills/b2c-site-import-export/SKILL.md b/skills/b2c-cli/skills/b2c-site-import-export/SKILL.md index 335c8003b..1a78c8875 100644 --- a/skills/b2c-cli/skills/b2c-site-import-export/SKILL.md +++ b/skills/b2c-cli/skills/b2c-site-import-export/SKILL.md @@ -54,6 +54,7 @@ review and trim before committing, preserving XSD-required fields. - Export flags, data units, and compact JSON results: the export reference in the `b2c-job` skill. - Ordered migrations, naming, history, and recovery: `b2c-cli:b2c-import-set-migrations`. - Service configuration XML: `b2c:b2c-webservices`. +- Sample storefront datasets and new-instance setup: `b2c-cli:b2c-setup`. Jobs prefer SCAPI; `--api-backend auto` can fall back to OCAPI on supported rejections. Archive transfer uses WebDAV in either case. For job scopes, backend diff --git a/skills/b2c-cli/skills/b2c-storefronts/SKILL.md b/skills/b2c-cli/skills/b2c-storefronts/SKILL.md index e68eb362a..1af09f680 100644 --- a/skills/b2c-cli/skills/b2c-storefronts/SKILL.md +++ b/skills/b2c-cli/skills/b2c-storefronts/SKILL.md @@ -79,6 +79,7 @@ To develop locally or configure CI against a storefront, download its project co ## Related Skills +- `b2c-cli:b2c-setup` — end-to-end sandbox and realm setup - `b2c-cli:b2c-mrt` — MRT projects, environments, bundles, and environment variables - `b2c-cli:b2c-site-import-export` — site archive layout and other export data units - `b2c-cli:b2c-job` — job execution, logs, and waiting From e979b3b6573a438710539e772ed0bf26495c8483 Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 11:56:46 -0400 Subject: [PATCH 2/8] Note GitHub repository access for storefront datasets --- docs/guide/realm-setup.md | 2 ++ skills/b2c-cli/skills/b2c-setup/references/DATASETS.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/guide/realm-setup.md b/docs/guide/realm-setup.md index ff2d7c8d6..80588cfd3 100644 --- a/docs/guide/realm-setup.md +++ b/docs/guide/realm-setup.md @@ -48,6 +48,8 @@ See [per-instance policies](./safety#per-instance-configuration) and [confirmati Salesforce publishes sample data for the reference storefronts in [storefront-datasets](https://github.com/SalesforceCommerceCloud/storefront-datasets). Each dataset is a site archive with a site, catalogs, price books, inventory, content, and promotions. +The repository is available to Commerce Cloud customers and partners. To get access, link your GitHub account through Account Manager; see [Salesforce Commerce Cloud GitHub Repositories and Access](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-github-repo-access.html). Without access, GitHub shows a 404 page for the repository. + | Dataset directory | Site ID | | ------------------ | -------------- | | `foundations-data` | `Foundations` | diff --git a/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md b/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md index 2769ecf82..1a6eff5a1 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md +++ b/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md @@ -2,6 +2,8 @@ Salesforce publishes sample data for the reference storefronts in [storefront-datasets](https://github.com/SalesforceCommerceCloud/storefront-datasets). Each dataset is a site archive with a site, catalogs, price books, inventory, content, promotions, and import jobs. +The repository is private to Commerce Cloud customers and partners. Link your GitHub account through Account Manager first; without access, GitHub returns 404 for the repository and `git clone` fails. See [GitHub repositories and access](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-github-repo-access.md) (`b2c docs read b2c-github-repo-access`). + | Dataset directory | Site ID | Contents | | ------------------ | -------------- | ---------------------------------------------------- | | `foundations-data` | `Foundations` | Small default dataset for the Foundations storefront | From 59cb1e1efc7ecb7293d1528b0e01780ab078daf5 Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 12:03:39 -0400 Subject: [PATCH 3/8] Use the full docs ID for GitHub repository access --- skills/b2c-cli/skills/b2c-setup/references/DATASETS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md b/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md index 1a6eff5a1..0840c346c 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md +++ b/skills/b2c-cli/skills/b2c-setup/references/DATASETS.md @@ -2,7 +2,7 @@ Salesforce publishes sample data for the reference storefronts in [storefront-datasets](https://github.com/SalesforceCommerceCloud/storefront-datasets). Each dataset is a site archive with a site, catalogs, price books, inventory, content, promotions, and import jobs. -The repository is private to Commerce Cloud customers and partners. Link your GitHub account through Account Manager first; without access, GitHub returns 404 for the repository and `git clone` fails. See [GitHub repositories and access](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-github-repo-access.md) (`b2c docs read b2c-github-repo-access`). +The repository is private to Commerce Cloud customers and partners. Link your GitHub account through Account Manager first; without access, GitHub returns 404 for the repository and `git clone` fails. See [GitHub repositories and access](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-github-repo-access.md) (`b2c docs read b2c-commerce/b2c-github-repo-access`). | Dataset directory | Site ID | Contents | | ------------------ | -------------- | ---------------------------------------------------- | From e7b63825b6de5059ca1a782727e1d104a9903146 Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 12:09:01 -0400 Subject: [PATCH 4/8] Document CLI storefront setup in the Storefront Next guide --- .changeset/realm-setup-guide.md | 2 +- docs/guide/realm-setup.md | 2 +- docs/guide/storefront-next.md | 64 ++++++++++++++++++- .../b2c-tooling-sdk/data/tooling/index.json | 6 +- 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/.changeset/realm-setup-guide.md b/.changeset/realm-setup-guide.md index 193379fde..e8864f835 100644 --- a/.changeset/realm-setup-guide.md +++ b/.changeset/realm-setup-guide.md @@ -2,4 +2,4 @@ '@salesforce/b2c-dx-docs': patch --- -New Realm Setup guide covers sandbox and realm setup with the storefront datasets, Storefront Next storefronts, replication, and Safety Mode policies for shared instances. +New Realm Setup guide covers sandbox and realm setup with the storefront datasets, Storefront Next storefronts, replication, and Safety Mode policies for shared instances. The Storefront Next guide now shows how to create a storefront from the CLI and add production to an existing Managed Runtime project. diff --git a/docs/guide/realm-setup.md b/docs/guide/realm-setup.md index 80588cfd3..a69b4919f 100644 --- a/docs/guide/realm-setup.md +++ b/docs/guide/realm-setup.md @@ -132,7 +132,7 @@ b2c job export --storefront market-street -i staging --output ./storefront-expor b2c job import ./storefront-export/ -i production --wait-for-storefront --show-log ``` -The storefront import requires the `user-id` in the export to be an Account Manager user who is authorized for the target. An export made with client credentials records the API client's service user; edit `user-id` before importing. Verify with `b2c mrt env list -p -i production --mrt-backend scapi`. +The storefront import requires the `user-id` in the export to be an Account Manager user who is authorized for the target. An export made with client credentials records the API client's service user; edit `user-id` before importing. Verify with `b2c mrt env list -p -i production --mrt-backend scapi`. For all import requirements, see [Add Another Instance](./storefront-next#add-another-instance). diff --git a/docs/guide/storefront-next.md b/docs/guide/storefront-next.md index 6410a03b6..a4d5e7c8b 100644 --- a/docs/guide/storefront-next.md +++ b/docs/guide/storefront-next.md @@ -1,5 +1,5 @@ --- -description: Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Manage environment variables, tail logs, and work with deployments. +description: Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Create storefronts, add instances to an MRT project, manage environment variables, tail logs, and work with deployments. --- # Storefront Next @@ -22,6 +22,68 @@ To load a sample site first, or to set up a new sandbox or realm end to end, see Use the generated configuration for local development and the existing MRT resources for the operations below. For additional environments and production launch, follow [Launch Your Storefront Next](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-mrt-launch-storefront.html). +## Set Up Storefronts from the CLI + +Choose between creating and importing by whether the Managed Runtime (MRT) project should already exist: + +| Goal | Use | +| -------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| A new storefront with a new MRT project | Storefront setup in Business Manager, or `b2c mrt project create` | +| Add another instance, such as production, to an existing MRT project | Export the storefront from the source instance and import it on the target | + +Creating a storefront always provisions a new MRT project, even when one with the same name and sites exists. Storefronts are not included in code and data replication. To keep staging and production in one project, create the storefront once, then export and import it on each other instance. + +### Create a Storefront + +Create a storefront for one or more existing sites with the SCAPI Storefronts API: + +```bash +b2c mrt project create "My Storefront" --site MySite --mrt-backend scapi + +# Creation runs asynchronously; check setupStatus. +b2c mrt project get -p --mrt-backend scapi +``` + +Setup creates the storefront's API and SLAS clients, eCDN configuration, MRT project, and default environment. When it completes, download the project configuration and credentials from the storefront's detail page in Business Manager. See [project create](/cli/mrt#b2c-mrt-project-create) for the required scope. + +### Add Another Instance + +Exporting and importing storefronts requires B2C Commerce 26.10 or later on both instances. + +```bash +# Export the storefront record from staging, by storefront name. +b2c job export --storefront my-storefront -i staging --output ./storefront-export + +# Import it on production and wait for storefront setup. +b2c job import ./storefront-export/ -i production --wait-for-storefront --show-log +``` + +The export contains only the storefront record: its name, type, sites, MRT project (`mrt-site`), MRT organization (`org-slug`), and the acting `user-id`. The import creates the storefront and runs the `sfcc-post-import-setup-storefront` job. That job provisions the instance's API and SLAS clients, eCDN, and a new MRT environment in the existing project. Setup can take 20 minutes or more. + +The import fails unless all of these are true on the target: + +- **The sites exist** and do not belong to another storefront. Replicate or import them first. +- **The storefront name is free.** Do not delete a storefront to retry an import. Deleting it removes its MRT project for every instance. +- **The MRT organization matches** the target instance's organization. +- **The user is authorized.** An import with client credentials uses the archive's `user-id`, which must be an Account Manager user with a Managed Runtime role in the organization. An export made with client credentials records the API client's service user instead; change `user-id` in `storefronts/.xml` before you import. + +When an import fails, the summary error is generic. Check the `[DATAERROR]` lines in the job log, which `--show-log` prints. + +Source repository links are not imported; connect the new environment to source control separately. Verify that both instances show the same project, each with its own environment: + +```bash +b2c mrt env list -p -i staging --mrt-backend scapi +b2c mrt env list -p -i production --mrt-backend scapi +``` + +The project ID is the `mrt-site` value in the export, not the storefront name. + + + +> Our Storefront Next storefront runs on staging. Connect production to the same Managed Runtime project: check the import requirements, export the storefront from staging, and import it on production. Ask me before changing production. + + + ## Prerequisites Use an existing Storefront Next project and an MRT API key with access to its project and target environment. See [CLI installation](/guide/installation) and [MRT configuration](/guide/configuration#mrt-api-key) for credentials and defaults. You can also replace `b2c` in these examples with `npx @salesforce/b2c-cli`. diff --git a/packages/b2c-tooling-sdk/data/tooling/index.json b/packages/b2c-tooling-sdk/data/tooling/index.json index 5d399d7d8..1fd09fc92 100644 --- a/packages/b2c-tooling-sdk/data/tooling/index.json +++ b/packages/b2c-tooling-sdk/data/tooling/index.json @@ -1,6 +1,6 @@ { "version": "2.0.0", - "generatedAt": "2026-10-29T22:13:29.774Z", + "generatedAt": "2026-10-30T16:05:59.651Z", "entries": [ { "id": "cli-account-manager", @@ -512,8 +512,8 @@ "category": "tooling", "url": "https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/storefront-next.html", "sourceUrl": "https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/storefront-next.md", - "headings": "Start with Storefront Setup • Prerequisites • Manage Environment Variables • Update Several Values Together • Apply an Environment File • Tail Application Logs • Work with Deployments • Work with Your AI Assistant • Next Steps", - "preview": "Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Manage environment variables, tail logs, and work with deployments." + "headings": "Start with Storefront Setup • Set Up Storefronts from the CLI • Create a Storefront • Add Another Instance • Prerequisites • Manage Environment Variables • Update Several Values Together • Apply an Environment File • Tail Application Logs • Work with Deployments • Work with Your AI Assistant • Next Steps", + "preview": "Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Create storefronts, add instances to an MRT project, manage environment variables, tail logs, and work with deployments." }, { "id": "guide-third-party-plugins", From 2303ebc8ee3f091f84964ce1fb1d4f3f3f4e75ec Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 12:57:42 -0400 Subject: [PATCH 5/8] Add Storefront Next project and API client setup guidance Cover the API client and scopes for CLI storefront creation, generating project code with create-storefront, and getting the .env file (one-time Business Manager download, or rebuilding non-secret values from the instance) in the b2c-setup skill and the Storefront Next guide. --- .changeset/b2c-setup-skill.md | 2 +- .changeset/realm-setup-guide.md | 2 +- docs/cli/sfnext.md | 2 +- docs/guide/authentication.md | 4 + docs/guide/storefront-next.md | 61 +++++++++- .../b2c-tooling-sdk/data/tooling/index.json | 6 +- skills/b2c-cli/skills/b2c-setup/SKILL.md | 37 +++--- .../skills/b2c-setup/references/REALM.md | 2 +- .../skills/b2c-setup/references/SANDBOX.md | 4 +- .../b2c-setup/references/STOREFRONT-NEXT.md | 113 ++++++++++++++++++ .../b2c-cli/skills/b2c-storefronts/SKILL.md | 4 +- 11 files changed, 207 insertions(+), 30 deletions(-) create mode 100644 skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md diff --git a/.changeset/b2c-setup-skill.md b/.changeset/b2c-setup-skill.md index 7e6b91d27..fc8394659 100644 --- a/.changeset/b2c-setup-skill.md +++ b/.changeset/b2c-setup-skill.md @@ -3,4 +3,4 @@ '@salesforce/b2c-dx-mcp': minor --- -New `b2c-setup` skill guides your assistant through setting up a sandbox or realm: sample storefront datasets, search indexes, Storefront Next storefronts, and replication to production, with confirmation before changes to shared instances. The MCP server features it in its skill listing. +New `b2c-setup` skill guides your assistant through setting up a sandbox or realm: sample storefront datasets, search indexes, Storefront Next storefronts and project code, and replication to production, with confirmation before changes to shared instances. The MCP server features it in its skill listing. diff --git a/.changeset/realm-setup-guide.md b/.changeset/realm-setup-guide.md index e8864f835..a6b5bb9af 100644 --- a/.changeset/realm-setup-guide.md +++ b/.changeset/realm-setup-guide.md @@ -2,4 +2,4 @@ '@salesforce/b2c-dx-docs': patch --- -New Realm Setup guide covers sandbox and realm setup with the storefront datasets, Storefront Next storefronts, replication, and Safety Mode policies for shared instances. The Storefront Next guide now shows how to create a storefront from the CLI and add production to an existing Managed Runtime project. +New Realm Setup guide covers sandbox and realm setup with the storefront datasets, Storefront Next storefronts, replication, and Safety Mode policies for shared instances. The Storefront Next guide now shows how to create a storefront and its API client from the CLI, generate the project code, get the `.env` file, and add production to an existing Managed Runtime project. diff --git a/docs/cli/sfnext.md b/docs/cli/sfnext.md index 6a8afd50b..a3825cc45 100644 --- a/docs/cli/sfnext.md +++ b/docs/cli/sfnext.md @@ -18,7 +18,7 @@ To explore the template locally, use `npx` from outside an existing project: npx @salesforce/b2c-cli sfnext create-storefront ``` -This creates local project files; it does not provision the storefront's B2C Commerce and MRT resources. See [Explore Storefront Next Code Locally](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-sf.html) for the local workflow. +This creates local project files; it does not provision the storefront's B2C Commerce and MRT resources. To connect a generated project to a storefront on your instance, see [Generate the Project Code](/guide/storefront-next#generate-the-project-code). See [Explore Storefront Next Code Locally](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-sf.html) for the local workflow. ## In-Project Commands diff --git a/docs/guide/authentication.md b/docs/guide/authentication.md index 4bd7f704d..faa3310d9 100644 --- a/docs/guide/authentication.md +++ b/docs/guide/authentication.md @@ -156,6 +156,10 @@ SCAPI Admin APIs need a client secret or JWT; browser sign-in isn't supported ye | `b2c sites list`, `sites cartridges list` | `sfcc.sites` or `sfcc.sites.rw` | [Sites](/cli/sites) | | `b2c sites cartridges add/remove/set` | `sfcc.sites.rw` | [Sites](/cli/sites) | | Catalog discovery used by export/VS Code | `sfcc.catalogs` or `sfcc.catalogs.rw` | [Jobs](/cli/jobs) | +| `b2c mrt project list/get` (SCAPI backend) | `sfcc.storefront.storefronts` or `.rw` | [MRT Backends](/cli/mrt#mrt-backends) | +| `b2c mrt project create/update/delete` (SCAPI) | `sfcc.storefront.storefronts.rw` | [MRT Backends](/cli/mrt#mrt-backends) | +| `b2c mrt env`, `env var` reads (SCAPI backend) | `sfcc.storefront.environments` | [MRT Backends](/cli/mrt#mrt-backends) | +| `b2c mrt env`, `env var` writes (SCAPI backend) | `sfcc.storefront.environments.rw` | [MRT Backends](/cli/mrt#mrt-backends) | | `b2c mrt bundle history` (SCAPI backend) | `sfcc.storefront.deployments` or `.rw` | [MRT Backends](/cli/mrt#mrt-backends) | | `b2c mrt bundle deploy ` (SCAPI backend) | `sfcc.storefront.deployments.rw` | [MRT Backends](/cli/mrt#mrt-backends) | diff --git a/docs/guide/storefront-next.md b/docs/guide/storefront-next.md index a4d5e7c8b..b11d1583b 100644 --- a/docs/guide/storefront-next.md +++ b/docs/guide/storefront-next.md @@ -1,5 +1,5 @@ --- -description: Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Create storefronts, add instances to an MRT project, manage environment variables, tail logs, and work with deployments. +description: Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Create storefronts and their API client, generate project code, get the environment file, add instances to an MRT project, manage environment variables, tail logs, and work with deployments. --- # Storefront Next @@ -44,7 +44,64 @@ b2c mrt project create "My Storefront" --site MySite --mrt-backend scapi b2c mrt project get -p --mrt-backend scapi ``` -Setup creates the storefront's API and SLAS clients, eCDN configuration, MRT project, and default environment. When it completes, download the project configuration and credentials from the storefront's detail page in Business Manager. See [project create](/cli/mrt#b2c-mrt-project-create) for the required scope. +Setup creates the storefront's API and SLAS clients, eCDN configuration, MRT project, and default environment. It can take up to 30 minutes. The returned `storefrontId` is the MRT project ID. + +#### API Client + +Creating a storefront from the CLI uses the SCAPI Storefronts API, which needs an Account Manager API client with the `Salesforce Commerce API` role and the storefront scopes. The API client that storefront setup creates doesn't have these scopes. If your configured client lacks them, create one (requires the API Administrator or Account Administrator role in Account Manager): + +```bash +b2c am clients create \ + --name "Storefront automation" \ + --orgs \ + --password "" \ + --roles SALESFORCE_COMMERCE_API \ + --role-tenant-filter "SALESFORCE_COMMERCE_API:abcd_001" \ + --scopes "mail,roles,tenantFilter,openid,sfcc.storefront.storefronts.rw,sfcc.storefront.environments.rw,sfcc.storefront.deployments.rw" \ + --default-scopes "mail,roles,tenantFilter,openid,sfcc.storefront.storefronts.rw,sfcc.storefront.environments.rw,sfcc.storefront.deployments.rw" \ + --active +``` + +Add `sfcc.jobs.rw` and `sfcc.sites` to import data and rebuild search indexes with the same client. Then add the client ID, secret, short code, and tenant ID to your [configuration](./configuration). See [Scopes by Command](./authentication#scopes-by-command) and [Account Manager](./account-manager). + +The user who sets up the storefront also needs the Managed Runtime User or Managed Runtime Admin role in Account Manager and Business Manager access to storefronts. + +### Generate the Project Code + +Generate the storefront code with the Storefront Next CLI, outside an existing project: + +```bash +pnpm dlx @salesforce/storefront-next-dev create-storefront -n my-storefront -V fashion --defaults +# or, with the B2C CLI +b2c sfnext create-storefront -n my-storefront -V fashion --defaults + +cd my-storefront +pnpm install +pnpm run dev +``` + +Choose the `--vertical` (`-V`) that matches your site's data, such as `fashion` for the Market Street dataset or `cosmetic` for Beauty Next. Pin a template release with `--template-branch` to match your [dataset version](./realm-setup#storefront-datasets). Without `--defaults`, the command asks for extensions and configuration values. The default values point to a public demo instance, so replace the project's `.env` before you connect it to your own instance. + +### Get the Environment File + +On the storefront's detail page in Business Manager (**Administration > Storefronts**), click **Download .env**. The file contains your instance settings, MRT project and environment IDs, and the storefront's Account Manager and SLAS client credentials. Replace the project's `.env` with its contents and keep it out of source control. + +::: warning +The client secrets are available for download only once. No CLI command or API returns the file or its secrets: storefront and MRT environment variable values and SLAS client secrets are masked. +::: + +Without the download, rebuild the non-secret values from your instance: + +| Variable | Where to find it | +| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | +| `MRT_PROJECT` | `storefrontId` from `b2c mrt project list --mrt-backend scapi` | +| `MRT_TARGET` | The environment ID from `b2c mrt env list -p --mrt-backend scapi` | +| `PUBLIC__app__commerce__api__clientId` | The SLAS client named `Automated Storefront Step: ` in `b2c slas client list` | +| `PUBLIC__app__commerce__api__organizationId` | `f_ecom_` followed by your tenant ID, such as `f_ecom_abcd_001` | +| `PUBLIC__app__commerce__api__shortCode` | Your instance's SCAPI short code | +| `PUBLIC__app__defaultSiteId`, `PUBLIC__app__commerce__sites` | Your storefront's sites | + +To replace a lost SLAS client secret, rotate it with `b2c slas client update --secret `, then update it everywhere the storefront uses it, including the MRT environment. See [SLAS commands](/cli/slas). For the full SCAPI walkthrough, see [Create Storefront Next with SCAPI](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-scapi-create-storefront.html). ### Add Another Instance diff --git a/packages/b2c-tooling-sdk/data/tooling/index.json b/packages/b2c-tooling-sdk/data/tooling/index.json index 1fd09fc92..800e007be 100644 --- a/packages/b2c-tooling-sdk/data/tooling/index.json +++ b/packages/b2c-tooling-sdk/data/tooling/index.json @@ -1,6 +1,6 @@ { "version": "2.0.0", - "generatedAt": "2026-10-30T16:05:59.651Z", + "generatedAt": "2026-10-30T16:42:08.019Z", "entries": [ { "id": "cli-account-manager", @@ -512,8 +512,8 @@ "category": "tooling", "url": "https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/storefront-next.html", "sourceUrl": "https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/storefront-next.md", - "headings": "Start with Storefront Setup • Set Up Storefronts from the CLI • Create a Storefront • Add Another Instance • Prerequisites • Manage Environment Variables • Update Several Values Together • Apply an Environment File • Tail Application Logs • Work with Deployments • Work with Your AI Assistant • Next Steps", - "preview": "Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Create storefronts, add instances to an MRT project, manage environment variables, tail logs, and work with deployments." + "headings": "Start with Storefront Setup • Set Up Storefronts from the CLI • Create a Storefront • API Client • Generate the Project Code • Get the Environment File • Add Another Instance • Prerequisites • Manage Environment Variables • Update Several Values Together • Apply an Environment File • Tail Application Logs • Work with Deployments • Work with Your AI Assistant • Next Steps", + "preview": "Support Storefront Next development and operations with the B2C CLI, MCP, and agent skills. Create storefronts and their API client, generate project code, get the environment file, add instances to an MRT project, manage environment variables, tail logs, and work with deployments." }, { "id": "guide-third-party-plugins", diff --git a/skills/b2c-cli/skills/b2c-setup/SKILL.md b/skills/b2c-cli/skills/b2c-setup/SKILL.md index 440b8d623..985a08168 100644 --- a/skills/b2c-cli/skills/b2c-setup/SKILL.md +++ b/skills/b2c-cli/skills/b2c-setup/SKILL.md @@ -26,16 +26,17 @@ Recommend Safety Mode for shared instances: [safety](references/SAFETY.md). ## Choose a Path -| Goal | Path | -| --------------------------------------------------------- | --------------------------------------------- | -| A development sandbox with sample data and a storefront | [Sandbox setup](references/SANDBOX.md) | -| A new realm: staging first, then production / development | [Realm setup](references/REALM.md) | -| Sample sites, catalogs, and content for any instance | [Storefront datasets](references/DATASETS.md) | -| Add an instance to an existing Storefront Next project | `b2c-cli:b2c-storefronts` | +| Goal | Path | +| --------------------------------------------------------- | ------------------------------------------------------ | +| A development sandbox with sample data and a storefront | [Sandbox setup](references/SANDBOX.md) | +| A new realm: staging first, then production / development | [Realm setup](references/REALM.md) | +| Sample sites, catalogs, and content for any instance | [Storefront datasets](references/DATASETS.md) | +| A Storefront Next storefront, project code, and `.env` | [Storefront Next setup](references/STOREFRONT-NEXT.md) | +| Add an instance to an existing Storefront Next project | `b2c-cli:b2c-storefronts` | Every path starts the same way: -1. **Connect.** Configure the instance and API client, then check with `b2c setup inspect`. See `b2c-cli:b2c-config`; API clients and roles: `b2c-cli:b2c-am`. +1. **Connect.** Configure the instance and API client, then check with `b2c setup inspect`. See `b2c-cli:b2c-config`; API clients and roles: `b2c-cli:b2c-am`. Creating a Storefront Next storefront from the CLI needs storefront scopes on the client: [Storefront Next setup](references/STOREFRONT-NEXT.md#1-api-client-for-the-cli). 2. **Check what exists.** `b2c sites list` and `b2c code list` show existing sites and code versions. Do not overwrite existing sites or settings without approval. 3. **Load data** (staging or sandbox only), then **rebuild search indexes**. 4. **Deploy code** for the storefront type (cartridges, or a Storefront Next storefront). @@ -45,17 +46,17 @@ Every path starts the same way: Steps that depend on the product line, license, or feature. Use only the rows that apply to the user's realm. -| Workflow | Applies to | Guidance | -| ------------------------------------------ | ------------------------------------------ | -------------------------------------------------------------------- | -| Instance connection, API clients, roles | All | `b2c-cli:b2c-config`, `b2c-cli:b2c-am`, `b2c-cli:b2c-bm-users-roles` | -| Sample data and search indexes | All | [Storefront datasets](references/DATASETS.md), `b2c-cli:b2c-job` | -| Site archives and custom data | All | `b2c-cli:b2c-site-import-export` | -| Code and data replication | Realms (staging to production/development) | `b2c-cli:b2c-replication` | -| Storefront Next storefront and MRT project | Storefront Next | `b2c-cli:b2c-storefronts`, `b2c-cli:b2c-mrt` | -| Cartridge storefronts (SFRA) | Cartridge-based storefronts | `b2c-cli:b2c-code`, `b2c-cli:b2c-sites` | -| Shopper authentication (SLAS) | Headless and composable storefronts | `b2c-cli:b2c-slas` | -| Commerce apps | Commerce apps | `b2c-cli:b2c-cap` | -| eCDN zones and certificates | Storefronts on eCDN | `b2c-cli:b2c-ecdn` | +| Workflow | Applies to | Guidance | +| ------------------------------------------ | ------------------------------------------ | ---------------------------------------------------------------------------------------------------- | +| Instance connection, API clients, roles | All | `b2c-cli:b2c-config`, `b2c-cli:b2c-am`, `b2c-cli:b2c-bm-users-roles` | +| Sample data and search indexes | All | [Storefront datasets](references/DATASETS.md), `b2c-cli:b2c-job` | +| Site archives and custom data | All | `b2c-cli:b2c-site-import-export` | +| Code and data replication | Realms (staging to production/development) | `b2c-cli:b2c-replication` | +| Storefront Next storefront and MRT project | Storefront Next | [Storefront Next setup](references/STOREFRONT-NEXT.md), `b2c-cli:b2c-storefronts`, `b2c-cli:b2c-mrt` | +| Cartridge storefronts (SFRA) | Cartridge-based storefronts | `b2c-cli:b2c-code`, `b2c-cli:b2c-sites` | +| Shopper authentication (SLAS) | Headless and composable storefronts | `b2c-cli:b2c-slas` | +| Commerce apps | Commerce apps | `b2c-cli:b2c-cap` | +| eCDN zones and certificates | Storefronts on eCDN | `b2c-cli:b2c-ecdn` | ## Related Skills diff --git a/skills/b2c-cli/skills/b2c-setup/references/REALM.md b/skills/b2c-cli/skills/b2c-setup/references/REALM.md index 2242063ee..a976cf764 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/REALM.md +++ b/skills/b2c-cli/skills/b2c-setup/references/REALM.md @@ -23,7 +23,7 @@ b2c setup inspect -i staging ``` 2. **Code.** For cartridge storefronts, deploy and activate a code version (`b2c-cli:b2c-code`). Staging code uploads may need a certificate: see the [Hyperforce guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/hyperforce.md) (`b2c docs read guide-hyperforce`). -3. **Storefront.** For Storefront Next, create the storefront on staging (Business Manager storefront setup, or `b2c mrt project create "My Storefront" --site MySite -i staging --mrt-backend scapi`). See `b2c-cli:b2c-storefronts`. +3. **Storefront.** For Storefront Next, create the storefront on staging (Business Manager storefront setup, or `b2c mrt project create "My Storefront" --site MySite -i staging --mrt-backend scapi`). Scopes, project code, and `.env`: [Storefront Next setup](STOREFRONT-NEXT.md). 4. **Verify** the site on staging before replicating. ## 3. Replicate to Production or Development diff --git a/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md b/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md index 99b681ca9..caa56d195 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md +++ b/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md @@ -39,7 +39,9 @@ For Storefront Next, create the storefront for the imported site. Business Manag b2c mrt project create "Market Street" --site MarketStreet --mrt-backend scapi ``` -Setup provisions the MRT project and environment, API and SLAS clients, and eCDN. It runs asynchronously; check progress with `b2c mrt project get -p --mrt-backend scapi`. Then download the project configuration from the storefront's detail page in Business Manager. Details: `b2c-cli:b2c-storefronts`. +This needs an API client with the storefront scopes. Setup provisions the MRT project and environment, API and SLAS clients, and eCDN. It runs asynchronously; check progress with `b2c mrt project get -p --mrt-backend scapi`. + +Then generate the project code with `create-storefront` and fill in its `.env` from the storefront's **Download .env** in Business Manager. API client, scaffolding, and `.env`: [Storefront Next setup](STOREFRONT-NEXT.md). For a cartridge storefront, deploy the cartridges and set the site's cartridge path instead (`b2c-cli:b2c-code`, `b2c-cli:b2c-sites`). diff --git a/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md b/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md new file mode 100644 index 000000000..e00fd902c --- /dev/null +++ b/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md @@ -0,0 +1,113 @@ +# Storefront Next Setup + +Create the storefront on the instance, generate the project code, and fill in the project's `.env`. For the storefront record itself (create or import, moving to another instance), see `b2c-cli:b2c-storefronts`. + +## 1. API Client for the CLI + +Business Manager storefront setup needs only the user's roles. Creating a storefront from the CLI (`b2c mrt project create --mrt-backend scapi`) and the SCAPI MRT commands need an Account Manager API client. The client that storefront setup creates does not have the storefront scopes, so do not use it for these commands. + +Check the configured client first: + +```bash +b2c setup inspect +b2c mrt project list --mrt-backend scapi +``` + +If the client is missing or the call returns 401/403, create or update one. Creating a client requires browser sign-in with the Account Manager **API Administrator** or **Account Administrator** role, and changes the organization; confirm with the user first. + +```bash +b2c am clients create \ + --name "Storefront automation" \ + --orgs \ + --password "<12+ character secret>" \ + --roles SALESFORCE_COMMERCE_API \ + --role-tenant-filter "SALESFORCE_COMMERCE_API:abcd_001" \ + --scopes "mail,roles,tenantFilter,openid,sfcc.storefront.storefronts.rw,sfcc.storefront.environments.rw,sfcc.storefront.deployments.rw,sfcc.jobs.rw,sfcc.sites" \ + --default-scopes "mail,roles,tenantFilter,openid,sfcc.storefront.storefronts.rw,sfcc.storefront.environments.rw,sfcc.storefront.deployments.rw,sfcc.jobs.rw,sfcc.sites" \ + --active +``` + +| Scope | Used by | +| --------------------------------- | ----------------------------------------------------------- | +| `sfcc.storefront.storefronts.rw` | `mrt project create`, `get`, `list`, `update`, `delete` | +| `sfcc.storefront.environments.rw` | `mrt env` and `mrt env var` commands | +| `sfcc.storefront.deployments.rw` | `mrt bundle` commands and `sfnext push --mrt-backend scapi` | +| `sfcc.jobs.rw`, `sfcc.sites` | Dataset import, `Reindex`, `sites list` | + +Add the tenant ID of every instance the client should reach to the tenant filter (`abcd_001,abcd_002`). Save the client ID and secret with `short-code` and `tenant-id` in the instance configuration (`b2c-cli:b2c-config`); never print the secret. Client management: `b2c-cli:b2c-am`. Scope reference: [Authentication guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/authentication.md) (`b2c docs read guide-authentication`). + +The user who runs storefront setup, or whose login is the storefront's `user-id`, also needs the **Managed Runtime User** or **Managed Runtime Admin** role in Account Manager and Business Manager access to storefronts (Business Administrator, or a role with read-write access to storefronts). + +## 2. Create the Storefront + +```bash +b2c mrt project create "Market Street" --site MarketStreet --mrt-backend scapi +b2c mrt project get -p --mrt-backend scapi # until setupStatus is success +``` + +Setup takes up to 30 minutes and creates the MRT project and environment, the storefront's Account Manager and SLAS clients, and eCDN. The response's `storefrontId` is the MRT project ID; it differs from the storefront name. + +## 3. Generate the Project Code + +Run the scaffolding CLI outside an existing project. Both forms run the same `create-storefront` command: + +```bash +pnpm dlx @salesforce/storefront-next-dev create-storefront -n market-street -V fashion --defaults +# or +b2c sfnext create-storefront -n market-street -V fashion --defaults +``` + +| Flag | Use | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| `-n, --name` | Project folder name | +| `-V, --vertical` | Template vertical: match the dataset (`fashion` for Market Street, `cosmetic` for Beauty Next, `foundations`, `footwear`, `furniture`, `luxury`) | +| `-b, --template-branch` | Template release tag; pin it to match the [dataset](DATASETS.md) version | +| `-d, --defaults` | Skip prompts and use the template's `.env.default` values | +| `-o, --output-dir` | Parent directory for the project | + +Without `--defaults`, the command prompts for extensions and each configuration value. `.env.default` points to a public demo instance, so a project generated with defaults runs but does not use the user's instance until the `.env` is replaced (step 4). + +```bash +cd market-street +pnpm install +pnpm run dev +``` + +Template features: [Storefront Next Template Features](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-template-compare.md) (`b2c docs read sfnext/sfnext-template-compare`). Command reference: [Storefront Next CLI](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-cli.md) (`b2c docs read sfnext/sfnext-cli`). For project-level setup and configuration, use the `storefront-next:sfnext-project-setup` skill if it is installed. + +## 4. Get the `.env` File + +**Business Manager is the only source of the complete file.** On the storefront's detail page (**Administration > Storefronts > _storefront_**), **Download .env** saves `env.txt` with the instance settings, MRT project and environment IDs, and the storefront's Account Manager and SLAS credentials. Replace the project's `.env` with its contents. + +The client secrets in that file can be downloaded only once; later downloads omit them. Ask the user to download it; do not read, print, or commit its secrets. Keep `.env` out of source control. + +No CLI command or API returns the file or its secrets: the Storefronts API returns no credentials, MRT environment variable values are masked, and SLAS client secrets are masked. If the download is not available, rebuild the non-secret values from the instance: + +| `.env` key | Source | +| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- | +| `MRT_PROJECT` | `storefrontId` from `b2c mrt project list --mrt-backend scapi` | +| `MRT_TARGET` | Environment ID from `b2c mrt env list -p --mrt-backend scapi` | +| `PUBLIC__app__commerce__api__clientId` | SLAS client named `Automated Storefront Step: ` in `b2c slas client list --json` | +| `PUBLIC__app__commerce__api__organizationId` | `f_ecom_`, for example `f_ecom_abcd_001` | +| `PUBLIC__app__commerce__api__shortCode` | The instance's SCAPI short code | +| `PUBLIC__app__defaultSiteId`, `PUBLIC__app__commerce__sites` | The storefront's sites (`b2c sites list`) | + +The storefront's SLAS client is private. A lost secret cannot be read back: rotate it with `b2c slas client update --secret ` (confirm first, then update `COMMERCE_API_SLAS_SECRET` wherever the old secret is set, including the MRT environment), or create a separate SLAS client for local development (`b2c-cli:b2c-slas`). + +## 5. Deploy + +Push from the project with the template's `push` script and the MRT project and environment from `.env`: + +```bash +pnpm sfnext push --project --environment --mrt-backend scapi --wait +``` + +`--mrt-backend scapi` uses the API client from step 1 (`SFCC_OAUTH_CLIENT_ID` / `SFCC_OAUTH_CLIENT_SECRET`, short code, tenant ID); without it, `push` uses an MRT API key. See [Deploy Storefront Next to MRT](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-push-mrt-auto.md) (`b2c docs read sfnext/sfnext-push-mrt-auto`) and `b2c-cli:b2c-mrt`. + +## Salesforce Guides + +- [Create Storefront Next with SCAPI](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-scapi-create-storefront.md) (`b2c docs read sfnext/sfnext-scapi-create-storefront`) — API client, create, generate, deploy +- [Create Storefront Next in Business Manager with Local Code](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-bm.md) (`b2c docs read sfnext/sfnext-quick-start-create-bm`) +- [Create Storefront Next with a GitHub Repository](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-bm-github.md) (`b2c docs read sfnext/sfnext-quick-start-create-bm-github`) +- [Explore Storefront Next Code Locally](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-sf.md) (`b2c docs read sfnext/sfnext-quick-start-create-sf`) — demo instance, no setup +- [Automate Storefront Administration with APIs](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-mrt-api.md) (`b2c docs read sfnext/sfnext-mrt-api`) — storefront API scopes diff --git a/skills/b2c-cli/skills/b2c-storefronts/SKILL.md b/skills/b2c-cli/skills/b2c-storefronts/SKILL.md index 1af09f680..091dfa581 100644 --- a/skills/b2c-cli/skills/b2c-storefronts/SKILL.md +++ b/skills/b2c-cli/skills/b2c-storefronts/SKILL.md @@ -30,7 +30,7 @@ Business Manager storefront setup is the primary path; it also scaffolds the pro b2c mrt project create "My Storefront" --site MySite --mrt-backend scapi ``` -Creation runs asynchronously. See the `b2c-cli:b2c-mrt` skill for SCAPI backend setup and scopes (`sfcc.storefront.storefronts.rw`). +Creation runs asynchronously. It needs an Account Manager API client with `sfcc.storefront.storefronts.rw`; the client that storefront setup creates does not have it. See the `b2c-cli:b2c-mrt` skill for SCAPI backend setup. ## Move a Storefront to Another Instance @@ -75,7 +75,7 @@ The MRT project ID is the `mrt-site` value in the export, not the storefront nam ## Project Configuration and Credentials -To develop locally or configure CI against a storefront, download its project configuration and credentials from the storefront's detail page in Business Manager. Use that file for the storefront project rather than copying values by hand. See the [Storefront Next guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/storefront-next.md) (`b2c docs read guide-storefront-next`) for how the CLI uses common Storefront Next project variables. +To develop locally or configure CI against a storefront, use **Download .env** on the storefront's detail page in Business Manager. Use that file for the storefront project rather than copying values by hand. Its client secrets download only once, and no CLI command or API returns them; to rebuild the other values or rotate a lost SLAS secret, see the Storefront Next setup reference in `b2c-cli:b2c-setup` or [Get the Environment File](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/storefront-next.md#get-the-environment-file). See the [Storefront Next guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/storefront-next.md) (`b2c docs read guide-storefront-next`) for how the CLI uses common Storefront Next project variables. ## Related Skills From c6c1f410ee79137e0f1e74eb1c211fd73c5ca1bd Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 13:12:49 -0400 Subject: [PATCH 6/8] Use the sfnext CLI for project generation; drop b2c sfnext create-storefront The skills drift test rejects b2c sfnext create-storefront (a JIT plugin command), and the Storefront Next CLI reference documents only pnpm dlx. --- docs/guide/storefront-next.md | 6 ++---- skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md | 2 +- .../b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md | 6 ++---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/guide/storefront-next.md b/docs/guide/storefront-next.md index b11d1583b..dc6f99057 100644 --- a/docs/guide/storefront-next.md +++ b/docs/guide/storefront-next.md @@ -68,19 +68,17 @@ The user who sets up the storefront also needs the Managed Runtime User or Manag ### Generate the Project Code -Generate the storefront code with the Storefront Next CLI, outside an existing project: +Generate the storefront code with the `sfnext` CLI's `create-storefront` command. Because it runs before a project exists, run it with `pnpm dlx` outside any project; other `sfnext` commands run from the project's own dependency: ```bash pnpm dlx @salesforce/storefront-next-dev create-storefront -n my-storefront -V fashion --defaults -# or, with the B2C CLI -b2c sfnext create-storefront -n my-storefront -V fashion --defaults cd my-storefront pnpm install pnpm run dev ``` -Choose the `--vertical` (`-V`) that matches your site's data, such as `fashion` for the Market Street dataset or `cosmetic` for Beauty Next. Pin a template release with `--template-branch` to match your [dataset version](./realm-setup#storefront-datasets). Without `--defaults`, the command asks for extensions and configuration values. The default values point to a public demo instance, so replace the project's `.env` before you connect it to your own instance. +Choose the `--vertical` (`-V`) that matches your site's data, such as `fashion` for the Market Street dataset or `cosmetic` for Beauty Next. Pin a template release with `--template-branch` to match your [dataset version](./realm-setup#storefront-datasets). Without `--defaults`, the command asks for extensions and configuration values. See the [`sfnext` CLI reference](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-cli.html) for all options. The default values point to a public demo instance, so replace the project's `.env` before you connect it to your own instance. ### Get the Environment File diff --git a/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md b/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md index caa56d195..2747104c4 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md +++ b/skills/b2c-cli/skills/b2c-setup/references/SANDBOX.md @@ -41,7 +41,7 @@ b2c mrt project create "Market Street" --site MarketStreet --mrt-backend scapi This needs an API client with the storefront scopes. Setup provisions the MRT project and environment, API and SLAS clients, and eCDN. It runs asynchronously; check progress with `b2c mrt project get -p --mrt-backend scapi`. -Then generate the project code with `create-storefront` and fill in its `.env` from the storefront's **Download .env** in Business Manager. API client, scaffolding, and `.env`: [Storefront Next setup](STOREFRONT-NEXT.md). +Then generate the project code with the `sfnext` CLI (`pnpm dlx @salesforce/storefront-next-dev create-storefront`) and fill in its `.env` from the storefront's **Download .env** in Business Manager. API client, scaffolding, and `.env`: [Storefront Next setup](STOREFRONT-NEXT.md). For a cartridge storefront, deploy the cartridges and set the site's cartridge path instead (`b2c-cli:b2c-code`, `b2c-cli:b2c-sites`). diff --git a/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md b/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md index e00fd902c..fe580e622 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md +++ b/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md @@ -49,12 +49,10 @@ Setup takes up to 30 minutes and creates the MRT project and environment, the st ## 3. Generate the Project Code -Run the scaffolding CLI outside an existing project. Both forms run the same `create-storefront` command: +Use the `sfnext` CLI from `@salesforce/storefront-next-dev`. Other `sfnext` commands run from the project's own dependency (`pnpm sfnext ...`); `create-storefront` runs before a project exists, so run it with `pnpm dlx` outside any project: ```bash pnpm dlx @salesforce/storefront-next-dev create-storefront -n market-street -V fashion --defaults -# or -b2c sfnext create-storefront -n market-street -V fashion --defaults ``` | Flag | Use | @@ -73,7 +71,7 @@ pnpm install pnpm run dev ``` -Template features: [Storefront Next Template Features](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-template-compare.md) (`b2c docs read sfnext/sfnext-template-compare`). Command reference: [Storefront Next CLI](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-cli.md) (`b2c docs read sfnext/sfnext-cli`). For project-level setup and configuration, use the `storefront-next:sfnext-project-setup` skill if it is installed. +Template features: [Storefront Next Template Features](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-template-compare.md) (`b2c docs read sfnext/sfnext-template-compare`). `sfnext` command reference: [Command-Line Interface (CLI) Reference](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-cli.md) (`b2c docs read sfnext/sfnext-cli`). For project-level setup and configuration, use the `storefront-next:sfnext-project-setup` skill if it is installed. ## 4. Get the `.env` File From d989fdb08c3a179efce123c050bfae1072cb8bb3 Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 16:16:00 -0400 Subject: [PATCH 7/8] Confirm before creating Account Manager API clients and guide client setup b2c am clients create now shows the client's details and asks for confirmation (--force skips it; required with --json or when not interactive), and defaults the token endpoint auth method to client_secret_basic so new clients work with their secret. Skills and docs explain how to create an API client with the user's own sign-in, and require agents to confirm every detail with the user first. --- .changeset/am-clients-create-confirm.md | 6 + docs/cli/account-manager.md | 11 +- docs/guide/account-manager.md | 28 +++-- docs/guide/authentication.md | 2 + docs/guide/storefront-next.md | 2 +- .../b2c-cli/src/commands/am/clients/create.ts | 64 +++++++++- .../test/commands/am/clients/create.test.ts | 115 +++++++++++++++++- skills/b2c-cli/skills/b2c-am/SKILL.md | 61 +++++++--- skills/b2c-cli/skills/b2c-config/SKILL.md | 2 +- skills/b2c-cli/skills/b2c-setup/SKILL.md | 3 +- .../b2c-setup/references/STOREFRONT-NEXT.md | 4 +- 11 files changed, 257 insertions(+), 41 deletions(-) create mode 100644 .changeset/am-clients-create-confirm.md diff --git a/.changeset/am-clients-create-confirm.md b/.changeset/am-clients-create-confirm.md new file mode 100644 index 000000000..e02ee84b9 --- /dev/null +++ b/.changeset/am-clients-create-confirm.md @@ -0,0 +1,6 @@ +--- +'@salesforce/b2c-cli': minor +'@salesforce/b2c-agent-plugins': patch +--- + +`b2c am clients create` now shows the new client's details and asks for confirmation before creating it. Pass `--force` to skip the prompt; scripts and `--json` runs must add `--force`. New clients now default to `client_secret_basic`, so they work with their secret; previously Account Manager made them `private_key_jwt` and the secret was rejected. The `b2c-am` skill now walks your assistant through creating an API client when you don't have one, after you approve every detail. diff --git a/docs/cli/account-manager.md b/docs/cli/account-manager.md index 707dc2e33..800e0f7a5 100644 --- a/docs/cli/account-manager.md +++ b/docs/cli/account-manager.md @@ -826,6 +826,8 @@ When not using `--json`, displays formatted API client information including: Create a new Account Manager API client. Clients are created inactive by default and must be explicitly activated (e.g. via update). +Before creating the client, the command shows its details (name, organizations, roles, role tenant filter, scopes, redirect URLs, auth method, and active state, but not the password) and asks for confirmation. Pass `--force` to skip the prompt in scripts; with `--json` or in a non-interactive session, `--force` is required. + #### Usage ```bash @@ -852,9 +854,10 @@ b2c am clients create [FLAGS] | `--scopes` | Comma-separated OAuth scopes | | `--default-scopes` | Comma-separated default OAuth scopes | | `--version-control` | Comma-separated version control system identifiers | -| `--token-endpoint-auth-method` | Token endpoint auth method: `private_key_jwt`, `client_secret_post`, `client_secret_basic`, or `none` | +| `--token-endpoint-auth-method` | Token endpoint auth method: `private_key_jwt`, `client_secret_post`, `client_secret_basic` (default), or `none` | | `--jwt-public-key` | Public key for JWT authentication (PEM or inline) | -| `--json` | Output results as JSON | +| `--force`, `-f` | Skip the confirmation prompt | +| `--json` | Output results as JSON (requires `--force`) | #### Examples @@ -862,6 +865,9 @@ b2c am clients create [FLAGS] b2c am clients create --name my-client --orgs org-id-1 --password "SecureP@ss123" b2c am clients create -n my-client -o "My Organization" -p "SecureP@ss123" -r SALESFORCE_COMMERCE_API b2c am clients create -n my-client -o org-id-1 -p "SecureP@ss123" --scopes "mail,openid" --default-scopes "mail" + +# In a script, skip the confirmation prompt +b2c am clients create -n my-client -o org-id-1 -p "SecureP@ss123" --force --json ``` #### Notes @@ -870,6 +876,7 @@ b2c am clients create -n my-client -o org-id-1 -p "SecureP@ss123" --scopes "mail - Password must be 12–128 characters - Role tenant filter must match pattern: `ROLE:realm_instance(,realm_instance)*(;ROLE:...)*` (e.g. SALESFORCE_COMMERCE_API:abcd_prd) - At least one organization ID is required +- The token endpoint auth method defaults to `client_secret_basic`, so the client can authenticate with its password (client secret). Pass `--token-endpoint-auth-method private_key_jwt` with `--jwt-public-key` for [JWT authentication](/guide/authentication#jwt-authentication-certificate-based) --- diff --git a/docs/guide/account-manager.md b/docs/guide/account-manager.md index d423b7161..5d39a496b 100644 --- a/docs/guide/account-manager.md +++ b/docs/guide/account-manager.md @@ -157,21 +157,33 @@ b2c am users get developer@example.com --expand-all ### API Client Provisioning -Create and configure API clients for your team or automation: +Jobs, sites, Storefront Next storefronts, and other API commands need an API client. If you don't have one, create it with your own sign-in. You need the API Administrator or Account Administrator role in Account Manager. ```bash -# Create an API client -b2c am clients create \ +# Find your organization ID +b2c am orgs list --user-auth + +# Create the client; the command shows its details and asks before creating it +b2c am clients create --user-auth \ --name "CI/CD Pipeline" \ --orgs $ORG_ID \ - --password "SecureP@ssword123" \ + --password "$CLIENT_SECRET" \ --roles SALESFORCE_COMMERCE_API \ - --role-tenant-filter "SALESFORCE_COMMERCE_API:zzxy_prd" - -# Activate the client -b2c am clients update $CLIENT_ID --active + --role-tenant-filter "SALESFORCE_COMMERCE_API:abcd_prd" \ + --scopes "mail,roles,tenantFilter,openid,sfcc.jobs.rw,sfcc.sites" \ + --default-scopes "mail,roles,tenantFilter,openid,sfcc.jobs.rw,sfcc.sites" \ + --active + +# Save it for your instance +b2c setup instance create staging --hostname staging-abcd-example.demandware.net \ + --client-id $CLIENT_ID --client-secret "$CLIENT_SECRET" \ + --short-code kv7kzm78 --tenant-id abcd_prd ``` +Grant only the tenants and scopes the client needs; [Scopes by Command](./authentication#scopes-by-command) lists them. Clients are inactive unless you pass `--active`; activate one later with `b2c am clients update $CLIENT_ID --active`. A client can be deleted only after it has been disabled for 7 days. For commands that use OCAPI, also add the client ID to [Open Commerce API Settings](./authentication#ocapi-configuration). + +When an AI assistant creates a client for you, the agent skills tell it to show you every detail and wait for your approval first. + ### Bulk Operations with JSON Output Use `--json` output for scripting and integration with other tools: diff --git a/docs/guide/authentication.md b/docs/guide/authentication.md index faa3310d9..2e2c9d9b1 100644 --- a/docs/guide/authentication.md +++ b/docs/guide/authentication.md @@ -54,6 +54,8 @@ Account Manager commands that manage organizations and API clients need roles on ### Creating an API Client +To create the client from the CLI with your own sign-in, use [`b2c am clients create`](/cli/account-manager#b2c-am-clients-create). This requires the API Administrator or Account Administrator role; see [API Client Provisioning](./account-manager#api-client-provisioning). To create one in Account Manager: + 1. Log in to [Account Manager](https://account.demandware.com). 2. Navigate to **API Client** in the left menu. 3. Click **Add API Client**. diff --git a/docs/guide/storefront-next.md b/docs/guide/storefront-next.md index dc6f99057..1e6a12b94 100644 --- a/docs/guide/storefront-next.md +++ b/docs/guide/storefront-next.md @@ -51,7 +51,7 @@ Setup creates the storefront's API and SLAS clients, eCDN configuration, MRT pro Creating a storefront from the CLI uses the SCAPI Storefronts API, which needs an Account Manager API client with the `Salesforce Commerce API` role and the storefront scopes. The API client that storefront setup creates doesn't have these scopes. If your configured client lacks them, create one (requires the API Administrator or Account Administrator role in Account Manager): ```bash -b2c am clients create \ +b2c am clients create --user-auth \ --name "Storefront automation" \ --orgs \ --password "" \ diff --git a/packages/b2c-cli/src/commands/am/clients/create.ts b/packages/b2c-cli/src/commands/am/clients/create.ts index 42da31d1c..b3b93ebfe 100644 --- a/packages/b2c-cli/src/commands/am/clients/create.ts +++ b/packages/b2c-cli/src/commands/am/clients/create.ts @@ -7,6 +7,7 @@ import {Flags} from '@oclif/core'; import {AmCommand} from '@salesforce/b2c-tooling-sdk/cli'; import {isValidRoleTenantFilter, type AccountManagerApiClient, type APIClientCreate} from '@salesforce/b2c-tooling-sdk'; import {t} from '../../../i18n/index.js'; +import {confirm} from '../../../prompts.js'; import {resolveOrgId} from '../../../utils/am/resolve-org.js'; function splitCommaSeparated(s: string): string[] { @@ -27,6 +28,7 @@ export default class ClientCreate extends AmCommand { static examples = [ '<%= config.bin %> <%= command.id %> --name my-client --orgs org-id-1 --password "SecureP@ss123"', '<%= config.bin %> <%= command.id %> --name my-client --orgs "My Organization" --password "SecureP@ss123" --roles SALESFORCE_COMMERCE_API', + '<%= config.bin %> <%= command.id %> --name my-client --orgs org-id-1 --password "SecureP@ss123" --force', ]; static flags = { @@ -74,15 +76,25 @@ export default class ClientCreate extends AmCommand { description: 'Comma-separated version control system identifiers', }), 'token-endpoint-auth-method': Flags.string({ - description: 'Token endpoint auth method: private_key_jwt, client_secret_post, client_secret_basic, or none', + description: + 'Token endpoint auth method: private_key_jwt, client_secret_post, client_secret_basic, or none (default: client_secret_basic)', options: ['private_key_jwt', 'client_secret_post', 'client_secret_basic', 'none'], }), 'jwt-public-key': Flags.string({ description: 'Public key for JWT authentication (PEM or inline)', }), + force: Flags.boolean({ + char: 'f', + description: 'Skip confirmation prompt', + default: false, + }), }; - async run(): Promise { + protected operations = { + confirm, + }; + + async run(): Promise { const flags = this.flags; const nameTrimmed = flags.name.trim(); const orgInputs = splitCommaSeparated(flags.orgs); @@ -93,6 +105,23 @@ export default class ClientCreate extends AmCommand { const body = this.buildCreateBody(flags, nameTrimmed, orgIds); + if (!flags.force) { + // A --json consumer can't answer a prompt, and stdout must stay clean JSON. + if (this.jsonEnabled()) { + this.error( + t( + 'commands.client.create.jsonRequiresForce', + 'Confirmation is required to create an API client. Re-run with --force in --json (non-interactive) mode.', + ), + ); + } + const confirmed = await this.operations.confirm(this.formatConfirmation(body)); + if (!confirmed) { + this.log(t('commands.client.create.cancelled', 'API client creation cancelled')); + return undefined; + } + } + this.log(t('commands.client.create.creating', 'Creating API client {{name}}...', {name: flags.name})); const client = await this.accountManagerClient.createApiClient(body); @@ -139,15 +168,40 @@ export default class ClientCreate extends AmCommand { if (flags['version-control']) { body.versionControl = splitCommaSeparated(flags['version-control']); } - if (flags['token-endpoint-auth-method']) { - body.tokenEndpointAuthMethod = flags['token-endpoint-auth-method'] as APIClientCreate['tokenEndpointAuthMethod']; - } + // Account Manager otherwise defaults new clients to private_key_jwt, which rejects the client secret. + body.tokenEndpointAuthMethod = (flags['token-endpoint-auth-method'] ?? + 'client_secret_basic') as APIClientCreate['tokenEndpointAuthMethod']; if (flags['jwt-public-key'] !== undefined) { body.jwtPublicKey = flags['jwt-public-key'].trim().length > 0 ? flags['jwt-public-key'].trim() : null; } return body; } + /** + * Summarizes the client to be created for the confirmation prompt. Never includes the password. + */ + private formatConfirmation(body: APIClientCreate): string { + const none = t('commands.client.create.confirmNone', '(none)'); + const list = (values?: string[]) => (values && values.length > 0 ? values.join(', ') : none); + const lines = [ + t('commands.client.create.confirmHeader', 'API client to create in Account Manager ({{host}}):', { + host: this.accountManagerHost, + }), + ` Name: ${body.name}`, + ` Organizations: ${list(body.organizations)}`, + ` Roles: ${list(body.roles)}`, + ` Role tenant filter: ${body.roleTenantFilter ?? none}`, + ` Scopes: ${list(body.scopes)}`, + ` Default scopes: ${list(body.defaultScopes)}`, + ` Redirect URLs: ${list(body.redirectUrls)}`, + ` Token auth method: ${body.tokenEndpointAuthMethod}`, + ` Active: ${body.active ? 'yes' : 'no'}`, + t('commands.client.create.confirmNote', 'Clients cannot be deleted until they have been disabled for 7 days.'), + t('commands.client.create.confirmPrompt', 'Create the client?'), + ]; + return lines.join('\n'); + } + private validateCreateInput(flags: typeof ClientCreate.prototype.flags, nameTrimmed: string, orgIds: string[]): void { if (nameTrimmed.length === 0) { this.error(t('commands.client.create.nameRequired', 'API client name cannot be empty')); diff --git a/packages/b2c-cli/test/commands/am/clients/create.test.ts b/packages/b2c-cli/test/commands/am/clients/create.test.ts index 5d0d3d40b..aa5206d3c 100644 --- a/packages/b2c-cli/test/commands/am/clients/create.test.ts +++ b/packages/b2c-cli/test/commands/am/clients/create.test.ts @@ -180,6 +180,7 @@ describe('am clients create', () => { name: 'New Client', orgs: 'org-123', password: 'SecureP@ssword12', + force: true, }; stubCommandConfigAndLogger(command); stubJsonEnabled(command, true); @@ -198,8 +199,14 @@ describe('am clients create', () => { return HttpResponse.json({id: 'org-123', name: 'Test Org'}); }), http.post(`${BASE_URL}/apiclients`, async ({request}) => { - const body = (await request.json()) as {name?: string; organizations?: string[]; password?: string}; + const body = (await request.json()) as { + name?: string; + organizations?: string[]; + password?: string; + tokenEndpointAuthMethod?: string; + }; expect(body.name).to.equal('New Client'); + expect(body.tokenEndpointAuthMethod).to.equal('client_secret_basic'); expect(body.organizations).to.deep.equal(['org-123']); return HttpResponse.json(mockCreated); }), @@ -207,8 +214,110 @@ describe('am clients create', () => { const result = await command.run(); - expect(result.id).to.equal('new-client-id'); - expect(result.name).to.equal('New Client'); + expect(result?.id).to.equal('new-client-id'); + expect(result?.name).to.equal('New Client'); + }); + }); + + describe('confirmation', () => { + function orgHandler() { + return http.get(`${BASE_URL}/organizations/org-123`, () => HttpResponse.json({id: 'org-123', name: 'Test Org'})); + } + + function newCommand(flags: Record = {}) { + const command = new ClientCreate([], {} as any); + (command as any).flags = { + name: 'New Client', + orgs: 'org-123', + password: 'SecureP@ssword12', + roles: 'SALESFORCE_COMMERCE_API', + 'role-tenant-filter': 'SALESFORCE_COMMERCE_API:abcd_001', + scopes: 'mail,sfcc.jobs.rw', + ...flags, + }; + stubCommandConfigAndLogger(command); + stubImplicitOAuthStrategy(command); + makeCommandThrowOnError(command); + return command; + } + + it('shows the client details without the password and creates it when confirmed', async () => { + const command = newCommand(); + const confirmStub = sinon.stub().resolves(true); + (command as any).operations = {confirm: confirmStub}; + let posted = false; + server.use( + orgHandler(), + http.post(`${BASE_URL}/apiclients`, () => { + posted = true; + return HttpResponse.json({id: 'new-client-id', name: 'New Client'}); + }), + ); + + const result = await command.run(); + + expect(posted).to.be.true; + expect(result?.id).to.equal('new-client-id'); + const message = confirmStub.firstCall.args[0] as string; + expect(message).to.include('New Client'); + expect(message).to.include('org-123'); + expect(message).to.include('SALESFORCE_COMMERCE_API:abcd_001'); + expect(message).to.include('mail, sfcc.jobs.rw'); + expect(message).to.not.include('SecureP@ssword12'); + }); + + it('does not create the client when declined', async () => { + const command = newCommand(); + (command as any).operations = {confirm: sinon.stub().resolves(false)}; + server.use(orgHandler()); + + const result = await command.run(); + + expect(result).to.be.undefined; + }); + + it('keeps an explicit token endpoint auth method', async () => { + const command = newCommand({force: true, 'token-endpoint-auth-method': 'private_key_jwt'}); + let method: string | undefined; + server.use( + orgHandler(), + http.post(`${BASE_URL}/apiclients`, async ({request}) => { + method = ((await request.json()) as {tokenEndpointAuthMethod?: string}).tokenEndpointAuthMethod; + return HttpResponse.json({id: 'new-client-id', name: 'New Client'}); + }), + ); + + await command.run(); + + expect(method).to.equal('private_key_jwt'); + }); + + it('skips the prompt with --force', async () => { + const command = newCommand({force: true}); + const confirmStub = sinon.stub().resolves(false); + (command as any).operations = {confirm: confirmStub}; + server.use( + orgHandler(), + http.post(`${BASE_URL}/apiclients`, () => HttpResponse.json({id: 'new-client-id', name: 'New Client'})), + ); + + const result = await command.run(); + + expect(confirmStub.called).to.be.false; + expect(result?.id).to.equal('new-client-id'); + }); + + it('requires --force in JSON mode', async () => { + const command = newCommand(); + stubJsonEnabled(command, true); + server.use(orgHandler()); + + try { + await command.run(); + expect.fail('Should have thrown'); + } catch (error: unknown) { + expect((error as Error).message).to.match(/Re-run with --force/); + } }); }); }); diff --git a/skills/b2c-cli/skills/b2c-am/SKILL.md b/skills/b2c-cli/skills/b2c-am/SKILL.md index 175a1e56c..4b7b75730 100644 --- a/skills/b2c-cli/skills/b2c-am/SKILL.md +++ b/skills/b2c-cli/skills/b2c-am/SKILL.md @@ -55,24 +55,49 @@ b2c am clients get --expand organizations,roles ### Create Client -Clients are created inactive by default. Requires user auth. +Jobs, sites, Storefront Next storefronts, and other SCAPI and OCAPI commands need an Account Manager API client. If the user has none, or `b2c setup inspect` shows no `clientId`, you can create one with the user's own sign-in. Requires user auth (`--user-auth`) with the **API Administrator** or **Account Administrator** role. -```bash -b2c am clients create \ - --name "My API Client" \ - --orgs \ - --password "securePassword123" - -# with roles, role tenant filter, and redirect URLs -b2c am clients create \ - --name "CI/CD Pipeline" \ - --orgs \ - --password "securePassword123" \ - --roles SALESFORCE_COMMERCE_API \ - --role-tenant-filter "SALESFORCE_COMMERCE_API:zzxy_prd" \ - --redirect-urls "https://example.com/callback" \ - --active -``` +**Always confirm the client in detail with the user before creating it.** A new client is a credential for the organization, and it cannot be deleted until it has been disabled for 7 days. Before running `create`, show the user every value — name, organization, roles, role tenant filter (the tenant IDs it can reach), scopes and default scopes, redirect URLs, and whether it is active — and wait for explicit approval. Ask again for each client; do not reuse an approval. Let the user choose the password, or generate one and tell them where it is stored; never print it. + +1. **Find the organization:** `b2c am orgs list --user-auth` (or `b2c am orgs get `). +2. **Choose access** for what the user needs: + + | Need | Roles and tenant filter | Scopes | + | -------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------- | + | Every client | | `mail,roles,tenantFilter,openid` | + | Jobs, sites, and other SCAPI commands | `SALESFORCE_COMMERCE_API` with tenant IDs (`abcd_001`) | Per command: `sfcc.jobs.rw`, `sfcc.sites`, ... (`b2c docs read guide-authentication`) | + | Storefront Next storefronts (SCAPI) | `SALESFORCE_COMMERCE_API` with tenant IDs | `sfcc.storefront.storefronts.rw`, `sfcc.storefront.environments.rw`, `sfcc.storefront.deployments.rw` | + | Sandboxes and SLAS clients | `Sandbox API User` with realm or tenant IDs | | + + Add the same scopes to `--scopes` and `--default-scopes`. Only grant the tenants and scopes the user asked for. + +3. **Create it** after the user approves. The command prints the details and asks for confirmation; when the agent cannot answer the prompt, pass `--force` only after the user approved those exact details. + + ```bash + b2c am clients create --user-auth \ + --name "CI/CD Pipeline" \ + --orgs \ + --password "" \ + --roles SALESFORCE_COMMERCE_API \ + --role-tenant-filter "SALESFORCE_COMMERCE_API:abcd_001,abcd_002" \ + --scopes "mail,roles,tenantFilter,openid,sfcc.jobs.rw,sfcc.sites" \ + --default-scopes "mail,roles,tenantFilter,openid,sfcc.jobs.rw,sfcc.sites" \ + --active + ``` + + The client authenticates with its secret (`client_secret_basic`) unless `--token-endpoint-auth-method` says otherwise; a client set to `private_key_jwt` rejects the secret with `invalid_client` ("Invalid authentication method"). Clients are created inactive unless `--active` is set; activate later with `b2c am clients update --active`. + +4. **Save it** in the instance configuration with the client ID from the output (`b2c-cli:b2c-config`): + + ```bash + b2c setup instance create staging --hostname staging.example.com \ + --client-id --client-secret "" \ + --short-code kv7kzm78 --tenant-id abcd_001 + ``` + +5. **Verify:** `b2c setup inspect`, then a read such as `b2c sites list`. + +Commands that use OCAPI (for example, with `--api-backend ocapi`) also need the client ID in the instance's Open Commerce API Settings, and WebDAV with client credentials needs WebDAV Client Permissions; see the [Authentication guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/authentication.md). ### Update Client @@ -91,7 +116,7 @@ b2c am clients password --current "oldPass" --new "newSecurePass ### Delete Client -Client must be disabled for 7+ days before deletion. Destructive operation (safe mode check). +Client must be disabled for 7+ days before deletion. Destructive operation (safe mode check); confirm with the user first. ```bash b2c am clients delete diff --git a/skills/b2c-cli/skills/b2c-config/SKILL.md b/skills/b2c-cli/skills/b2c-config/SKILL.md index 4da87fc2e..e33fc1bc1 100644 --- a/skills/b2c-cli/skills/b2c-config/SKILL.md +++ b/skills/b2c-cli/skills/b2c-config/SKILL.md @@ -116,7 +116,7 @@ For the full field reference, see the [Configuration guide](https://salesforceco Most commands that interact with a B2C Commerce instance require authentication. The CLI supports several methods: -- **Client credentials (API client):** Configure `clientId` and `clientSecret` in dw.json or environment variables. This is the default for automated/CI use. +- **Client credentials (API client):** Configure `clientId` and `clientSecret` in dw.json or environment variables. This is the default for automated/CI use. No API client yet? The user can create one with their own sign-in (`b2c-cli:b2c-am`, Create Client); confirm every detail with them first. - **Sign in with your account:** Use `--user-auth` on any OAuth-enabled command to sign in with your Account Manager account in the browser. - **Basic auth:** Configure `username` and `password` for WebDAV operations. - **Stateful sessions:** Use `b2c auth login` to stay signed in; later commands reuse the saved session when no other client is configured. Client credentials need no session (each command gets a token); `b2c auth client` exists for `sfcc-ci client:auth` compatibility. diff --git a/skills/b2c-cli/skills/b2c-setup/SKILL.md b/skills/b2c-cli/skills/b2c-setup/SKILL.md index 985a08168..bd4791186 100644 --- a/skills/b2c-cli/skills/b2c-setup/SKILL.md +++ b/skills/b2c-cli/skills/b2c-setup/SKILL.md @@ -17,6 +17,7 @@ Classify every target before changing it. Staging, production, and development i | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- | | Sandbox | Confirm creating (billable) or deleting a sandbox. Imports and storefront setup can proceed once the user asked. | | Staging, production, development instances | State the instance hostname and the exact change, then wait for explicit approval. Ask again for each separate change. | +| Account Manager (API clients, users, roles) | Show every detail (organization, roles, tenant filter, scopes) and wait for explicit approval. Ask again for each client. | - Never infer that a target is a sandbox from a configuration name; check the hostname (see [safety](references/SAFETY.md)). - Approval for one instance or step does not carry to the next. @@ -36,7 +37,7 @@ Recommend Safety Mode for shared instances: [safety](references/SAFETY.md). Every path starts the same way: -1. **Connect.** Configure the instance and API client, then check with `b2c setup inspect`. See `b2c-cli:b2c-config`; API clients and roles: `b2c-cli:b2c-am`. Creating a Storefront Next storefront from the CLI needs storefront scopes on the client: [Storefront Next setup](references/STOREFRONT-NEXT.md#1-api-client-for-the-cli). +1. **Connect.** Configure the instance and API client, then check with `b2c setup inspect`. See `b2c-cli:b2c-config`. Jobs, sites, and storefront commands need an API client; if the user has none, create one with their sign-in (`b2c-cli:b2c-am`, Create Client), and only after they approve every detail of it. Creating a Storefront Next storefront from the CLI needs storefront scopes on the client: [Storefront Next setup](references/STOREFRONT-NEXT.md#1-api-client-for-the-cli). 2. **Check what exists.** `b2c sites list` and `b2c code list` show existing sites and code versions. Do not overwrite existing sites or settings without approval. 3. **Load data** (staging or sandbox only), then **rebuild search indexes**. 4. **Deploy code** for the storefront type (cartridges, or a Storefront Next storefront). diff --git a/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md b/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md index fe580e622..01d54569c 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md +++ b/skills/b2c-cli/skills/b2c-setup/references/STOREFRONT-NEXT.md @@ -13,10 +13,10 @@ b2c setup inspect b2c mrt project list --mrt-backend scapi ``` -If the client is missing or the call returns 401/403, create or update one. Creating a client requires browser sign-in with the Account Manager **API Administrator** or **Account Administrator** role, and changes the organization; confirm with the user first. +If the client is missing or the call returns 401/403, create or update one. Creating a client requires browser sign-in with the Account Manager **API Administrator** or **Account Administrator** role and adds a credential to the organization. **Before creating it, show the user every value (organization, roles, tenant filter, scopes, active) and wait for explicit approval.** The full procedure is in `b2c-cli:b2c-am` (Create Client). ```bash -b2c am clients create \ +b2c am clients create --user-auth \ --name "Storefront automation" \ --orgs \ --password "<12+ character secret>" \ From b099fb909260c5c00c90ca9da612a7f50c1328d4 Mon Sep 17 00:00:00 2001 From: Charles Lavery Date: Fri, 30 Oct 2026 20:19:07 -0400 Subject: [PATCH 8/8] Note staging two-factor code upload and the hooks feature switch in setup guidance --- .changeset/staging-code-upload-notes.md | 6 ++++++ docs/guide/realm-setup.md | 4 ++++ skills/b2c-cli/skills/b2c-code/SKILL.md | 4 ++++ skills/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md | 2 +- skills/b2c-cli/skills/b2c-setup/references/REALM.md | 4 +++- 5 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 .changeset/staging-code-upload-notes.md diff --git a/.changeset/staging-code-upload-notes.md b/.changeset/staging-code-upload-notes.md new file mode 100644 index 000000000..e485940c0 --- /dev/null +++ b/.changeset/staging-code-upload-notes.md @@ -0,0 +1,6 @@ +--- +'@salesforce/b2c-agent-plugins': patch +'@salesforce/b2c-dx-docs': patch +--- + +Setup and code skills, and the Realm Setup guide, now explain that staging code upload normally requires a client certificate (a Salesforce Support CA bundle on legacy realms, or a self-registered eCDN CA on Hyperforce). They also cover the feature switch that Commerce API hooks need and how to reload when an instance has only one code version. diff --git a/docs/guide/realm-setup.md b/docs/guide/realm-setup.md index a69b4919f..1b1e0092e 100644 --- a/docs/guide/realm-setup.md +++ b/docs/guide/realm-setup.md @@ -111,6 +111,10 @@ b2c mrt project create "Market Street" --site MarketStreet -i staging --mrt-back For cartridge storefronts, deploy and activate a code version; see [code commands](/cli/code). +Staging instances normally require two-factor (mTLS) code upload, so cartridge uploads without a client certificate fail, usually with `403 Forbidden`. On legacy realms, the client certificate is signed by a CA bundle from Salesforce Support and uploads go to the `cert.staging` hostname. On Hyperforce realms, you register your own CA through eCDN; see [Set Up Two-Factor Code Upload](/guide/hyperforce#set-up-two-factor-code-upload). To configure the certificate, see [Two-Factor Authentication](/guide/configuration#two-factor-authentication-mtls). + +If your cartridges register hooks for the Commerce API, also turn on hook execution in **Administration > Global Preferences > Feature Switches**. Otherwise the hooks don't run. + ### 2. Replicate to Production Replicate from staging with replication jobs in three steps: code, global data, then site data. Global data creates the site on the target, so on the first replication, run it before site data. The `b2c-replication` skill has the job definitions. diff --git a/skills/b2c-cli/skills/b2c-code/SKILL.md b/skills/b2c-cli/skills/b2c-code/SKILL.md index 3a6924f25..f5da05c0f 100644 --- a/skills/b2c-cli/skills/b2c-code/SKILL.md +++ b/skills/b2c-cli/skills/b2c-code/SKILL.md @@ -27,6 +27,10 @@ The CLI auto-discovers the target instance and credentials from `SFCC_*` environ With only a server configured, the first command opens a browser for the user to sign in with their Account Manager account and waits until they do; tell the user to finish signing in. Their Business Manager roles decide access, and a 403 names the missing permission (for example `WebDAV_Manage_Customization` for `Cartridges`). Code goes to the active code version; activating one (`code activate`, `--activate`, `--reload`) needs an API client. +**Staging code upload needs a client certificate.** Staging instances normally require two-factor (mTLS) code upload, so a deploy without a certificate fails, usually with `403 Forbidden` on writes under `Cartridges`. Set `certificate` and `certificate-passphrase` (`SFCC_CERTIFICATE`, `SFCC_CERTIFICATE_PASSPHRASE`). Legacy realms use a certificate signed by a CA bundle from Salesforce Support and the `cert.staging.*` WebDAV hostname. Hyperforce realms use a CA the user registers through eCDN (`b2c-cli:b2c-ecdn`, `b2c ecdn mtls`). See [Two-Factor Authentication](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/configuration.md#two-factor-authentication-mtls). + +**Reload needs a second code version.** `--reload` toggles activation through another code version. If the instance has only one, create an empty one first (`b2c webdav mkdir --root cartridges version2`). + Run `b2c setup inspect` to see the resolved configuration and which source provided each value (use `--json` for scripting; secrets stay masked by default). For precedence rules and troubleshooting, see the `b2c-cli:b2c-config` skill. ## Examples diff --git a/skills/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md b/skills/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md index 199470f99..30fedfd1a 100644 --- a/skills/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md +++ b/skills/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md @@ -41,7 +41,7 @@ b2c ecdn mrt-rules delete --zone my-zone ## mTLS Certificates -Code upload certificates enable two-factor (mTLS) code upload to staging instances (`_stg` tenants only). There are two kinds: CAs registered with eCDN for the tenant (typically one, but several can be active, e.g. during renewal), which only sign certificates; and client certificates (`.p12`) signed by a CA (typically one per CI pipeline or developer, any number allowed), which the CLI sends on code upload. CI pipelines are the primary use case. Use `create --generate --name --client-name ` once to create + register the CA and issue the first (CI) client cert, then `issue` for each additional pipeline/developer. `setup` is a guided, interactive version of `create --generate` with defaults and an optional dw.json update. `create` with `--certificate-file`/`--private-key-file` registers a bring-your-own CA. The code upload hostname is provisioned by Salesforce and linked automatically; users don't configure it. The CA private key must be kept secret (treat like a password); the CA certificate bundle must have a maximum validity of 1 year and be renewed before expiry. On Hyperforce, use the `staging--.demandware.net` code upload hostname (not legacy `cert.staging.*`). +Code upload certificates enable two-factor (mTLS) code upload to staging instances (`_stg` tenants only). These commands are for **Hyperforce realms only**. Legacy realms use a CA bundle from Salesforce Support and the `cert.staging.*` hostname; don't register an eCDN CA for them. There are two kinds: CAs registered with eCDN for the tenant (typically one, but several can be active, e.g. during renewal), which only sign certificates; and client certificates (`.p12`) signed by a CA (typically one per CI pipeline or developer, any number allowed), which the CLI sends on code upload. CI pipelines are the primary use case. Use `create --generate --name --client-name ` once to create + register the CA and issue the first (CI) client cert, then `issue` for each additional pipeline/developer. `setup` is a guided, interactive version of `create --generate` with defaults and an optional dw.json update. `create` with `--certificate-file`/`--private-key-file` registers a bring-your-own CA. The code upload hostname is provisioned by Salesforce and linked automatically; users don't configure it. The CA private key must be kept secret (treat like a password); the CA certificate bundle must have a maximum validity of 1 year and be renewed before expiry. On Hyperforce, use the `staging--.demandware.net` code upload hostname (not legacy `cert.staging.*`). For the complete workflow, security guidance, and renewal instructions, see [Deploying to Hyperforce: Set Up Two-Factor Code Upload](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/hyperforce.md#set-up-two-factor-code-upload) (`b2c docs read guide-hyperforce`). diff --git a/skills/b2c-cli/skills/b2c-setup/references/REALM.md b/skills/b2c-cli/skills/b2c-setup/references/REALM.md index a976cf764..e87151ab6 100644 --- a/skills/b2c-cli/skills/b2c-setup/references/REALM.md +++ b/skills/b2c-cli/skills/b2c-setup/references/REALM.md @@ -22,7 +22,9 @@ b2c setup inspect -i staging b2c job run Reindex -i staging --wait ``` -2. **Code.** For cartridge storefronts, deploy and activate a code version (`b2c-cli:b2c-code`). Staging code uploads may need a certificate: see the [Hyperforce guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/hyperforce.md) (`b2c docs read guide-hyperforce`). +2. **Code.** For cartridge storefronts, deploy and activate a code version (`b2c-cli:b2c-code`). + - **Staging requires two-factor code upload.** Staging instances normally reject cartridge uploads without a client certificate (mTLS). The symptom is usually `403 Forbidden` on writes under `Cartridges` while reads and `Impex` writes succeed. Ask the user which setup their realm uses. On legacy realms, Salesforce Support provides a CA bundle and code goes to the `cert.staging.*` hostname. On Hyperforce realms, the user registers their own CA through eCDN (`b2c ecdn mtls create`, Hyperforce only). See [Two-Factor Authentication](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/configuration.md#two-factor-authentication-mtls) and [Set Up Two-Factor Code Upload](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/hyperforce.md#set-up-two-factor-code-upload) (`b2c docs read guide-hyperforce`). + - **Hooks need a feature switch.** If the code registers order or basket hooks, Commerce API hook execution must be on (**Administration > Global Preferences > Feature Switches**). Without it, hooks are skipped and the warn log shows `SCAPI hook invoked but feature is disabled`. 3. **Storefront.** For Storefront Next, create the storefront on staging (Business Manager storefront setup, or `b2c mrt project create "My Storefront" --site MySite -i staging --mrt-backend scapi`). Scopes, project code, and `.env`: [Storefront Next setup](STOREFRONT-NEXT.md). 4. **Verify** the site on staging before replicating.