Connect Gradial’s AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.
Gradial connects to Sitecore XP by running a lightweight Service Gateway module inside your CM’s IIS process. The gateway exposes a secured REST API at /_api/gradial/* that Gradial agents call to read items, apply edits, and trigger publishing — all without VPN tunnels, additional servers, or schema changes to your Sitecore databases.Authentication uses short-lived JWT bearer tokens issued by your existing OIDC provider (Sitecore Identity Server or a third-party IdP like Azure AD, Okta, or Keycloak). Gradial exchanges a client secret for a token on every request, so no long-lived credentials are stored on the CM server.
This page covers the on-premises / managed Sitecore XP integration. For Sitecore XM Cloud or Content Hub, see the Sitecore overview.
A Sitecore XP 10.0–10.4 CM instance reachable over HTTPS
Administrator access to the CM to install files and create a service user
Access to your OIDC provider (Sitecore Identity Server or equivalent) to register a client
A Gradial account with permission to create integrations under Settings → Integrations
The setup takes around 30 minutes for a straightforward deployment. Allow extra time if your environment uses split-horizon networking or a non-standard identity provider.
Enter the connection details and credentials in Gradial to go live
When you are done, Gradial talks to your CM over HTTPS at /_api/gradial/*, authenticated by short-lived JWT bearer tokens issued by your OIDC provider via the client-credentials grant.
The gateway ships as two DLLs and a config patch. It runs in-process inside the Sitecore CM IIS app domain — no separate service, no database changes, no schema updates.Supported versions: Sitecore XP 10.0, 10.1, 10.2, 10.3, 10.4 (CM role).Gradial provides the gateway in three formats. Pick the one that matches how you deploy Sitecore — all three land the same files in the CM webroot, after which you complete the shared post-install steps.
Sitecore package (wizard)
WDP (Azure / Web Deploy)
Drop-in zip (manual copy)
Best for a one-off manual install by a Sitecore administrator on a running CM.Artifact:Gradial.Gateway.Module-<version>-sc10.zip
1
Open the Installation Wizard
In the Sitecore Desktop, go to Sitecore → Development Tools → Installation Wizard (or Control Panel → Administration → Install a package).
2
Upload the package
Choose Upload package, select Gradial.Gateway.Module-<version>-sc10.zip, and upload it, then click Next.
3
Install
Step through the wizard and click Install. The package writes the module binaries (bin\Gradial.SitecoreXP.Gateway.*.dll, bin\Swashbuckle.Core.dll) and the config patch (App_Config\Include\Gradial\) into the webroot. On an upgrade, accept the file-overwrite prompts.
4
Restart when prompted
If the wizard offers to restart the Sitecore client or application, allow it so the new assemblies load.
Best for automated CI/CD into Azure App Service or any Web Deploy–based pipeline. You download the package from your Gradial release and add it as a step in your own pipeline — Gradial does not deploy into your environment for you.Artifact:Gradial.Gateway.Module-<version>-sc10.scwdp.zip
1
Add the package to your pipeline artifacts
Download Gradial.Gateway.Module-<version>-sc10.scwdp.zip from your Gradial gateway release and store it alongside your other Sitecore deploy artifacts.
2
Apply it with Web Deploy
Add a Web Deploy step that syncs the package to your CM web app. In Azure DevOps, use the Azure App Service deploy task with the .scwdp.zip as the package. Or call msdeploy directly:
Run the pipeline. Web Deploy lands the module binaries and config patch in the CM webroot and replaces any previous version cleanly on redeploy.
The WDP is built with the Sitecore Azure Toolkit and mirrors the same webroot layout as the other formats. It contains only the module binaries and configuration — no content items and no database changes.
Best when you deploy by copying files directly into the webroot (e.g. a scripted release).Artifact:Gradial.SitecoreXP.Gateway-<version>-sc10.zip
1
Stop the CM application pool
Stop the Sitecore CM application pool before copying files.
2
Unzip into the webroot
Unzip Gradial.SitecoreXP.Gateway-<version>-sc10.zip into the Sitecore CM webroot (e.g. C:\inetpub\wwwroot\<instance>\). The archive mirrors the webroot layout:
Once the files are in the webroot, finish the setup the same way regardless of install method:
1
Start (or restart) the CM application pool
This loads the gateway assemblies. GET https://<cm-host>/_api/gradial/health should now return 200 OK. (Authenticated endpoints return 503 until you configure identity in the next step.)If you get 404, the gateway did not initialize — check the Sitecore log for [Gradial.Gateway] entries during app pool startup.
2
Configure identity (setup page)
Browse to /sitecore/admin/Gradial.Setup.aspx on the CM (Sitecore administrator login required) and enter your OIDC values — Authority, Expected audience, Allowed client IDs, and Required scopes (from Section 2); set the optional Metadata address / discovery options only for split-horizon setups. Click Validate to confirm the values are well-formed and that your identity provider’s discovery document is reachable from the CM, then Save.
The Gradial Gateway setup page validates against your identity provider and writes an upgrade-safe customer config patch.
Save writes the values to App_Config\Include\Gradial\Gradial.CmGateway.Customer.config — a customer patch that package upgrades never overwrite — and the CM recycles automatically to apply them.
Containerized CM (Docker / Kubernetes / any topology where the CM is recreated from an image): the webroot — including App_Config — is an ephemeral container layer, so the file this page writes does not survive a container recreate. When it vanishes, gateway authentication breaks with 503 Identity provider unavailable. On containers, treat this page as a validation and smoke-test tool (the Validate button’s live discovery probe is still the fastest way to confirm the CM can reach your identity provider): make the durable configuration an install-settings.json on a persistent volume, or GRADIAL_IDENTITY_* environment variables in your compose file/manifest — both are re-applied automatically on every CM start.Precedence note: when install-settings.json or GRADIAL_IDENTITY_* variables are present, they are authoritative on every CM start for the settings they supply — values saved through this page for those same settings are overwritten at the next app-pool recycle.On a classic VM/IIS install the webroot is durable and this page is a perfectly good permanent configuration method.
Prefer configuration-as-code? You can supply the same identity values without the page: hand-edit the config patch (see Section 4), set GRADIAL_IDENTITY_* environment variables, or drop an install-settings.json in the Sitecore data folder — the last two are applied automatically on CM start. Non-identity settings such as Gradial.Security.AllowedDatabases are always edited in the config patch.
3
Create the service user and grant rights
Create the Sitecore user referenced by Gradial.Sitecore.ServiceUser (default sitecore\gradial-service) and grant the item-level rights in Section 3.
4
Verify end to end
Confirm GET https://<cm-host>/_api/gradial/health returns 200, then run the OIDC smoke test to confirm a real token is accepted.
Sitecore package / drop-in zip: stop the app pool, remove bin\Gradial.SitecoreXP.Gateway.*.dll, bin\Swashbuckle.Core.dll, and the entire App_Config\Include\Gradial\ folder, then restart the app pool.
WDP: remove the module step from your pipeline and redeploy, or delete the same files from the web app. The Gradial.CmGateway.Customer.config written by the setup page is not part of any package, so remove it by hand if you want the identity configuration gone too.
The gateway is an OAuth 2.0 resource server — it validates JWTs but never issues them. Token issuance is the job of your OIDC provider. You need to register three things there:
Concept
Purpose
API resource (audience)
Identifies the gateway as a protected resource. The token’s aud claim must match.
API scope
Permission name the caller must request to get a usable token.
Client
Gradial’s identity. Has a client_id + client_secret and is authorized for the scope above.
Gradial requests tokens with the client credentials grant and sends them on the Authorization: Bearer <token> header of every request.
Sitecore Identity Server is based on IdentityServer4 and accepts XML patch files mounted into its container. A complete Gradial registration:
<?xml version="1.0" encoding="utf-8"?><Settings> <Sitecore> <IdentityServer> <!-- The audience. Gateway's ExpectedAudience must equal Name. --> <ApiResources> <GradialGatewayResource> <Name>gradial.gateway</Name> <DisplayName>Gradial CM Gateway</DisplayName> <Scopes> <Scope1>gradial.cm.gateway</Scope1> </Scopes> </GradialGatewayResource> </ApiResources> <!-- The scope. Gateway's RequiredScopes must contain Name. --> <ApiScopes> <GradialCmGatewayScope> <Name>gradial.cm.gateway</Name> <DisplayName>Gradial CM Gateway Access</DisplayName> </GradialCmGatewayScope> </ApiScopes> <!-- One client per calling tool. Gateway's AllowedClientIds must contain ClientId. --> <Clients> <GradialClient> <ClientId>gradial</ClientId> <ClientName>Gradial Gateway Client</ClientName> <AccessTokenType>0</AccessTokenType> <AccessTokenLifetimeInSeconds>3600</AccessTokenLifetimeInSeconds> <RequireClientSecret>true</RequireClientSecret> <AllowOfflineAccess>false</AllowOfflineAccess> <AllowedGrantTypes> <AllowedGrantType1>client_credentials</AllowedGrantType1> </AllowedGrantTypes> <ClientSecrets> <ClientSecret1>$(env:GRADIAL_CLIENT_SECRET)</ClientSecret1> </ClientSecrets> <AllowedScopes> <AllowedScope1>gradial.cm.gateway</AllowedScope1> </AllowedScopes> </GradialClient> </Clients> </IdentityServer> </Sitecore></Settings>
Place this in the Identity container’s config directory (typically Config/production/ or via a mounted volume) and restart the container.
If you use a different OIDC provider (Azure AD, Okta, Auth0, Keycloak, etc.), the concepts are identical — register an API resource, an API scope, and a client-credentials client, then map the four values into the gateway’s config.
Split-horizon networks (internal vs. public issuer)
MetadataAddress exists for the case where the ID server has a different internal origin than the JWT’s public issuer URL. In simple deployments where the CM can reach the same URL clients use, leave MetadataAddress empty and the gateway will derive everything from Authority.This split is common in containerized deployments. For example:
The Sitecore Identity container is reachable from the CM container at http://id (an internal Docker DNS name, plain HTTP).
The same Identity service is reachable from the public internet at https://id.example.com (TLS, public DNS).
Tokens issued to Gradial carry iss: https://id.example.com because that’s the issuer the public clients trust.
In this case:
Setting
Value
Why
Gradial.Identity.Authority
https://id.example.com
Must match the JWT’s iss claim. The gateway compares this string to the token’s issuer during validation.
Gradial.Identity.MetadataAddress
http://id
Base URL the gateway uses to fetch the discovery document and signing keys. Use the internal hostname the CM container can actually reach. The gateway appends /.well-known/openid-configuration automatically — do not include that suffix here.
Gradial.Identity.DiscoveryRequireHttps
false
Required when MetadataAddress is plain HTTP. Leave true when both URLs are HTTPS.
Never set Authority to the internal URL. The gateway validates the token’s iss claim against Authority, and the issuer baked into the token is the public URL — using the internal URL there will fail every token with a 401.
Do not use GUIDs, Get-Random, or human-friendly password generators — they have insufficient entropy.
Store the plaintext secret in a secret manager. Inject it into the Identity container as an environment variable (the sample above reads $(env:GRADIAL_CLIENT_SECRET)). Provide the same plaintext value to Gradial when you create the integration.
The gateway executes every Sitecore operation as the configured service user (Gradial.Sitecore.ServiceUser, default sitecore\gradial-service). The OIDC client identity authorizes Gradial to call the gateway; the Sitecore user is what actually reads and writes content in Sitecore. Sitecore’s audit trail records this user, not the JWT caller — the gateway logs the JWT caller separately, with a correlation ID joining the two streams.
Grant the minimum item-level rights for the content roots the integration will operate against. Replace [TENANT] and [SITE] with your actual values; repeat for every tenant/site you want to expose.
Path
Rights
Notes
/sitecore/content/[TENANT]/[SITE]
Read, Write, Create, Delete, Rename
Content tree the integration will manage.
/sitecore/media library/Project/[TENANT]/[SITE]
Read, Write, Create, Delete, Rename
Media items associated with the same site.
/sitecore/templates
Read
Required so the gateway can resolve field definitions when reading or creating items. Do not grant Write — content operations should never mutate templates.
Apply rights with inheritance (“Descendants”) so child items inherit them. Use the Sitecore Security Editor (Desktop → Security Tools → Security Editor), or assign the user to a role that carries these rights.
The Sitecore ACLs above on the service user — anything outside the granted scope returns 403 from the underlying SDK.
The consuming application’s allowed-paths configuration (set in Gradial).
Database-level access is enforced separately by the Gradial.Security.AllowedDatabases setting. Requests targeting a database outside the allowlist are rejected before any Sitecore call is made. The setting fails closed — an empty allowlist denies all requests.
All settings live in App_Config\Include\Gradial\Gradial.CmGateway.config. Most defaults are correct out of the box; only the identity values are required.
OIDC issuer URL. The token’s iss claim must match.
Gradial.Identity.ExpectedAudience
(empty — required)
Value the token’s aud claim must equal.
Gradial.Identity.ValidateAudience
true
Disable only for diagnostics. Keep true in production.
Gradial.Identity.AllowedClientIds
gradial
Pipe-separated list of client IDs allowed to call the gateway (e.g. gradial|tool-b). The token’s client_id claim must appear here.
Gradial.Identity.RequiredScopes
gradial.cm.gateway
Pipe-separated list of scopes the token must contain.
Gradial.Identity.ClockSkewMinutes
2
Allowance for clock drift between the OIDC issuer and CM server.
Gradial.Identity.ClientIdClaimType
client_id
Claim name used to read the client ID from the token. Override only if your provider emits a non-standard claim.
Gradial.Identity.MetadataAddress
(empty)
Base URL for OIDC discovery and JWKS fetches. The gateway appends /.well-known/openid-configuration itself, so the value is just an origin (e.g. http://id) — not a full discovery URL. Leave empty to reuse Authority. Set this only when the CM cannot reach Authority directly; see Split-horizon networks.
Gradial.Identity.DiscoveryRequireHttps
true
Enforces HTTPS for the discovery endpoint. Only set false for local development against a non-TLS Identity host.
After saving, Gradial will fetch a token via the client-credentials grant and call /_api/gradial/health and /_api/gradial/whoami to verify the connection end-to-end.
Authority mismatch, signing key not loadable, or ExpectedAudience doesn’t match the token’s aud claim.
403 Forbidden with insufficient_scope
Token doesn’t include a scope listed in RequiredScopes.
403 Forbidden with client not allowed
Client ID isn’t in AllowedClientIds.
403 Forbidden on item operations
Service user lacks the required rights on the requested path. Review Section 3.
503 Service Unavailable on authenticated endpoints
Authority is empty or the gateway can’t reach the discovery document at MetadataAddress.
404 Not Found on /_api/gradial/*
Gateway didn’t initialize. Check the Sitecore log for [Gradial.Gateway] errors during app pool startup.
All gateway log entries are tagged [Gradial.Gateway] and include a correlation ID. When opening a support case, include the correlation ID from the failed request’s X-Correlation-Id response header.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Gradial Docs","colors":{"primary":"#a855f7","light":"#c084fc","dark":"#9333ea"},"logo":{"light":"https://mintcdn.com/gradial/RDiUqPSUUpbMwk4U/logo/light.svg?fit=max\u0026auto=format\u0026n=RDiUqPSUUpbMwk4U\u0026q=85\u0026s=3d465cd433ac4e5548cef9e2ca1c64f0","dark":"https://mintcdn.com/gradial/RDiUqPSUUpbMwk4U/logo/dark.svg?fit=max\u0026auto=format\u0026n=RDiUqPSUUpbMwk4U\u0026q=85\u0026s=9dd2ca4128b8734f5710af7f0ca4b65b"},"favicon":"https://mintcdn.com/gradial/jdrFNwtyKAIPgKH0/favicon.svg?fit=max\u0026auto=format\u0026n=jdrFNwtyKAIPgKH0\u0026q=85\u0026s=13e36fc9cd74b4fa6565594562d21961","navbar":{"links":[{"href":"https://app.gradial.com","label":"Log In"},{"href":"https://portal.usepylon.com/gradial","label":"Support"}],"primary":{"type":"button","label":"Request Demo","href":"https://www.gradial.com/request-demo"}},"footer":{"links":[{"header":"Gradial","items":[{"label":"Home","href":"https://www.gradial.com"},{"label":"Partners","href":"https://www.gradial.com/partnership"},{"label":"Blog","href":"https://www.gradial.com/blog"}]},{"header":"Resources","items":[{"label":"Support","href":"https://portal.usepylon.com/gradial"},{"label":"Release Notes","href":"/release-notes/overview"}]}]},"seo":{"metatags":{"canonical":"https://docs.gradial.com"}},"contextual":{"options":["copy","view","chatgpt","claude"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"gradial","hasAudioNarration":false,"actualSubdomain":"gradial","customDomains":["docs.gradial.com"],"gitSource":{"type":"github","owner":"gradial","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae3ae769e829eb16e13c101","collectionId":"42d6068c-b464-4539-b938-1c40a101b026","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae3ae769e829eb16e13c101"},"feedback":{"issues":true,"edits":true,"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae3ae769e829eb16e13c101","clientVersion":"0.0.4044","searchFilterCounts":[{"language":"default","tag":"Setup \u0026 Administration","count":57},{"language":"default","tag":"Integrations","count":42},{"language":"default","tag":"Gradial in Action","count":41},{"language":"default","tag":"Gradial ACI","count":22},{"language":"default","tag":"Documentation","count":22},{"language":"default","tag":"Getting Started","count":20},{"language":"default","tag":"CMS \u0026 DAM","count":20},{"language":"default","tag":"Content Management","count":10},{"language":"default","tag":"Ticketing Systems","count":10},{"language":"default","tag":"Marketing Automation","count":10}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"docs/integrations-administration-and-setup/integrations/sitecore-xp","slug":"/docs/integrations-administration-and-setup/integrations/sitecore-xp","pageMetadata":{"title":"Sitecore XP","description":"Connect Gradial's AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.","href":"/docs/integrations-administration-and-setup/integrations/sitecore-xp"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Connect Gradial’s AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,hr:`hr`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Frame,Heading,Info,OptimizedImage,Step,Steps,Tab,Table,Tabs,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Info)_missingMdxReference(`Info`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Gradial connects to Sitecore XP by running a lightweight `,_jsx(_components.strong,{children:`Service Gateway`}),` module inside your CM’s IIS process. The gateway exposes a secured REST API at `,_jsx(_components.code,{children:`/_api/gradial/*`}),` that Gradial agents call to read items, apply edits, and trigger publishing — all without VPN tunnels, additional servers, or schema changes to your Sitecore databases.`]}),`\n`,_jsx(_components.p,{children:`Authentication uses short-lived JWT bearer tokens issued by your existing OIDC provider (Sitecore Identity Server or a third-party IdP like Azure AD, Okta, or Keycloak). Gradial exchanges a client secret for a token on every request, so no long-lived credentials are stored on the CM server.`}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`This page covers the on-premises / managed `,_jsx(_components.strong,{children:`Sitecore XP`}),` integration. For Sitecore XM Cloud or Content Hub, see the `,_jsx(_components.a,{href:`/docs/integrations-administration-and-setup/integrations/sitecore-integration`,children:`Sitecore overview`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`what-you’ll-need`,children:`What you’ll need`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`A `,_jsx(_components.strong,{children:`Sitecore XP 10.0–10.4`}),` CM instance reachable over HTTPS`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Administrator access`}),` to the CM to install files and create a service user`]}),`\n`,_jsxs(_components.li,{children:[`Access to your `,_jsx(_components.strong,{children:`OIDC provider`}),` (Sitecore Identity Server or equivalent) to register a client`]}),`\n`,_jsxs(_components.li,{children:[`A `,_jsx(_components.strong,{children:`Gradial account`}),` with permission to create integrations under Settings → Integrations`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`The setup takes around 30 minutes for a straightforward deployment. Allow extra time if your environment uses split-horizon networking or a non-standard identity provider.`}),`\n`,_jsx(Heading,{level:`2`,id:`steps-in-this-guide`,children:`Steps in this guide`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Section`}),_jsx(_components.th,{children:`What you’ll do`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#1-install-the-service-gateway-module`,children:`1. Install the Service Gateway`})}),_jsx(_components.td,{children:`Choose an install method (Sitecore package, WDP, or drop-in zip), then configure identity via the setup page`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#2-register-gradial-as-an-oidc-client`,children:`2. Register the OIDC client`})}),_jsx(_components.td,{children:`Create an API resource, scope, and client-credentials client in your IdP`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#3-service-user-permissions`,children:`3. Service user permissions`})}),_jsx(_components.td,{children:`Create a Sitecore user and grant item-level rights on the content tree`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#4-module-configuration-reference`,children:`4. Configuration reference`})}),_jsx(_components.td,{children:`Full reference for every gateway setting`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.a,{href:`#5-create-the-integration-in-gradial`,children:`5. Create the integration in Gradial`})}),_jsx(_components.td,{children:`Enter the connection details and credentials in Gradial to go live`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`When you are done, Gradial talks to your CM over HTTPS at `,_jsx(_components.code,{children:`/_api/gradial/*`}),`, authenticated by short-lived JWT bearer tokens issued by your OIDC provider via the client-credentials grant.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`1-install-the-service-gateway-module`,children:`1. Install the Service Gateway module`}),`\n`,_jsx(_components.p,{children:`The gateway ships as two DLLs and a config patch. It runs in-process inside the Sitecore CM IIS app domain — no separate service, no database changes, no schema updates.`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Supported versions:`}),` Sitecore XP 10.0, 10.1, 10.2, 10.3, 10.4 (CM role).`]}),`\n`,_jsxs(_components.p,{children:[`Gradial provides the gateway in three formats. Pick the one that matches how you deploy Sitecore — all three land the same files in the CM webroot, after which you complete the shared `,_jsx(_components.a,{href:`#after-installing-all-methods`,children:`post-install steps`}),`.`]}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Sitecore package (wizard)`,id:`sitecore-package-wizard`,children:[_jsx(_components.p,{children:`Best for a one-off manual install by a Sitecore administrator on a running CM.`}),_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Artifact:`}),` `,_jsx(_components.code,{children:`Gradial.Gateway.Module-\u003cversion>-sc10.zip`})]}),_jsxs(Steps,{children:[_jsx(Step,{title:`Open the Installation Wizard`,children:_jsxs(_components.p,{children:[`In the Sitecore Desktop, go to `,_jsx(_components.strong,{children:`Sitecore → Development Tools → Installation Wizard`}),` (or `,_jsx(_components.strong,{children:`Control Panel → Administration → Install a package`}),`).`]})}),_jsx(Step,{title:`Upload the package`,children:_jsxs(_components.p,{children:[`Choose `,_jsx(_components.strong,{children:`Upload package`}),`, select `,_jsx(_components.code,{children:`Gradial.Gateway.Module-\u003cversion>-sc10.zip`}),`, and upload it, then click `,_jsx(_components.strong,{children:`Next`}),`.`]})}),_jsx(Step,{title:`Install`,children:_jsxs(_components.p,{children:[`Step through the wizard and click `,_jsx(_components.strong,{children:`Install`}),`. The package writes the module binaries (`,_jsx(_components.code,{children:`bin\\\\Gradial.SitecoreXP.Gateway.*.dll`}),`, `,_jsx(_components.code,{children:`bin\\\\Swashbuckle.Core.dll`}),`) and the config patch (`,_jsx(_components.code,{children:`App_Config\\\\Include\\\\Gradial\\\\`}),`) into the webroot. On an upgrade, accept the file-overwrite prompts.`]})}),_jsx(Step,{title:`Restart when prompted`,children:_jsx(_components.p,{children:`If the wizard offers to restart the Sitecore client or application, allow it so the new assemblies load.`})})]})]}),_jsxs(Tab,{title:`WDP (Azure / Web Deploy)`,id:`wdp-azure-%2F-web-deploy`,children:[_jsxs(_components.p,{children:[`Best for automated CI/CD into Azure App Service or any Web Deploy–based pipeline. You download the package from your Gradial release and add it as a step in `,_jsx(_components.strong,{children:`your own`}),` pipeline — Gradial does not deploy into your environment for you.`]}),_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Artifact:`}),` `,_jsx(_components.code,{children:`Gradial.Gateway.Module-\u003cversion>-sc10.scwdp.zip`})]}),_jsxs(Steps,{children:[_jsx(Step,{title:`Add the package to your pipeline artifacts`,children:_jsxs(_components.p,{children:[`Download `,_jsx(_components.code,{children:`Gradial.Gateway.Module-\u003cversion>-sc10.scwdp.zip`}),` from your Gradial gateway release and store it alongside your other Sitecore deploy artifacts.`]})}),_jsxs(Step,{title:`Apply it with Web Deploy`,children:[_jsxs(_components.p,{children:[`Add a Web Deploy step that syncs the package to your CM web app. In `,_jsx(_components.strong,{children:`Azure DevOps`}),`, use the `,_jsx(_components.strong,{children:`Azure App Service deploy`}),` task with the `,_jsx(_components.code,{children:`.scwdp.zip`}),` as the package. Or call `,_jsx(_components.code,{children:`msdeploy`}),` directly:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`msdeploy`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -verb:sync`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -source:package=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Gradial.Gateway.Module-\u003cversion>-sc10.scwdp.zip\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -dest:auto,computerName=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://\u003ccm-host>/msdeploy.axd?site=\u003csite-name>\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`,username=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"\u003cdeploy-user>\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`,password=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"\u003cdeploy-password>\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`,authtype=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Basic\"`})]}),`\n`]})})})]}),_jsx(Step,{title:`Deploy`,children:_jsx(_components.p,{children:`Run the pipeline. Web Deploy lands the module binaries and config patch in the CM webroot and replaces any previous version cleanly on redeploy.`})})]}),_jsx(Info,{children:_jsx(_components.p,{children:`The WDP is built with the Sitecore Azure Toolkit and mirrors the same webroot layout as the other formats. It contains only the module binaries and configuration — no content items and no database changes.`})})]}),_jsxs(Tab,{title:`Drop-in zip (manual copy)`,id:`drop-in-zip-manual-copy`,children:[_jsx(_components.p,{children:`Best when you deploy by copying files directly into the webroot (e.g. a scripted release).`}),_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Artifact:`}),` `,_jsx(_components.code,{children:`Gradial.SitecoreXP.Gateway-\u003cversion>-sc10.zip`})]}),_jsxs(Steps,{children:[_jsx(Step,{title:`Stop the CM application pool`,children:_jsx(_components.p,{children:`Stop the Sitecore CM application pool before copying files.`})}),_jsxs(Step,{title:`Unzip into the webroot`,children:[_jsxs(_components.p,{children:[`Unzip `,_jsx(_components.code,{children:`Gradial.SitecoreXP.Gateway-\u003cversion>-sc10.zip`}),` into the Sitecore CM webroot (e.g. `,_jsx(_components.code,{children:`C:\\\\inetpub\\\\wwwroot\\\\\u003cinstance>\\\\`}),`). The archive mirrors the webroot layout:`]}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`bin\\\\Gradial.SitecoreXP.Gateway.Core.dll`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`bin\\\\Gradial.SitecoreXP.Gateway.Sitecore10.dll`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`bin\\\\Swashbuckle.Core.dll`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`App_Config\\\\Include\\\\Gradial\\\\Gradial.CmGateway.config`})}),`\n`]})]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`after-installing-all-methods`,children:`After installing (all methods)`}),`\n`,_jsx(_components.p,{children:`Once the files are in the webroot, finish the setup the same way regardless of install method:`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Start (or restart) the CM application pool`,children:[_jsxs(_components.p,{children:[`This loads the gateway assemblies. `,_jsx(_components.code,{children:`GET https://\u003ccm-host>/_api/gradial/health`}),` should now return `,_jsx(_components.code,{children:`200 OK`}),`. (Authenticated endpoints return `,_jsx(_components.code,{children:`503`}),` until you configure identity in the next step.)`]}),_jsxs(_components.p,{children:[`If you get `,_jsx(_components.code,{children:`404`}),`, the gateway did not initialize — check the Sitecore log for `,_jsx(_components.code,{children:`[Gradial.Gateway]`}),` entries during app pool startup.`]})]}),_jsxs(Step,{title:`Configure identity (setup page)`,children:[_jsxs(_components.p,{children:[`Browse to `,_jsx(_components.strong,{children:_jsx(_components.code,{children:`/sitecore/admin/Gradial.Setup.aspx`})}),` on the CM (Sitecore administrator login required) and enter your OIDC values — `,_jsx(_components.strong,{children:`Authority`}),`, `,_jsx(_components.strong,{children:`Expected audience`}),`, `,_jsx(_components.strong,{children:`Allowed client IDs`}),`, and `,_jsx(_components.strong,{children:`Required scopes`}),` (from `,_jsx(_components.a,{href:`#2-register-gradial-as-an-oidc-client`,children:`Section 2`}),`); set the optional `,_jsx(_components.strong,{children:`Metadata address`}),` / discovery options only for split-horizon setups. Click `,_jsx(_components.strong,{children:`Validate`}),` to confirm the values are well-formed and that your identity provider’s discovery document is reachable from the CM, then `,_jsx(_components.strong,{children:`Save`}),`.`]}),_jsx(Frame,{caption:`The Gradial Gateway setup page validates against your identity provider and writes an upgrade-safe customer config patch.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/gradial/O6cdnKja3rFnX4t2/images/sitecore-gateway-setup.png?fit=max\u0026auto=format\u0026n=O6cdnKja3rFnX4t2\u0026q=85\u0026s=fef37567933d2b76ce03e7aebd10901e`,alt:`Gradial Gateway setup admin page`,\"data-og-width\":`2238`,width:`2238`,\"data-og-height\":`3534`,height:`3534`,\"data-path\":`images/sitecore-gateway-setup.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/gradial/O6cdnKja3rFnX4t2/images/sitecore-gateway-setup.png?w=280\u0026fit=max\u0026auto=format\u0026n=O6cdnKja3rFnX4t2\u0026q=85\u0026s=39c2543097919ee8702b2a492fa96d7d 280w, https://mintcdn.com/gradial/O6cdnKja3rFnX4t2/images/sitecore-gateway-setup.png?w=560\u0026fit=max\u0026auto=format\u0026n=O6cdnKja3rFnX4t2\u0026q=85\u0026s=3410022c21bda57a9750d940a0660525 560w, https://mintcdn.com/gradial/O6cdnKja3rFnX4t2/images/sitecore-gateway-setup.png?w=840\u0026fit=max\u0026auto=format\u0026n=O6cdnKja3rFnX4t2\u0026q=85\u0026s=7f3bae7496a5e7aad664e5e3c29a2c95 840w, https://mintcdn.com/gradial/O6cdnKja3rFnX4t2/images/sitecore-gateway-setup.png?w=1100\u0026fit=max\u0026auto=format\u0026n=O6cdnKja3rFnX4t2\u0026q=85\u0026s=68dbe115036e578f29e47269c98573f5 1100w, https://mintcdn.com/gradial/O6cdnKja3rFnX4t2/images/sitecore-gateway-setup.png?w=1650\u0026fit=max\u0026auto=format\u0026n=O6cdnKja3rFnX4t2\u0026q=85\u0026s=bea342346b0c778c707d532d60c270e1 1650w, https://mintcdn.com/gradial/O6cdnKja3rFnX4t2/images/sitecore-gateway-setup.png?w=2500\u0026fit=max\u0026auto=format\u0026n=O6cdnKja3rFnX4t2\u0026q=85\u0026s=f4744d84580d5925936bb2b5791358e6 2500w`})}),_jsxs(_components.p,{children:[`Save writes the values to `,_jsx(_components.code,{children:`App_Config\\\\Include\\\\Gradial\\\\Gradial.CmGateway.Customer.config`}),` — a customer patch that `,_jsx(_components.strong,{children:`package upgrades never overwrite`}),` — and the CM recycles automatically to apply them.`]}),_jsxs(Warning,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Containerized CM (Docker / Kubernetes / any topology where the CM is recreated from an image):`}),` the webroot — including `,_jsx(_components.code,{children:`App_Config`}),` — is an ephemeral container layer, so the file this page writes `,_jsx(_components.strong,{children:`does not survive a container recreate`}),`. When it vanishes, gateway authentication breaks with `,_jsx(_components.code,{children:`503 Identity provider unavailable`}),`. On containers, treat this page as a `,_jsx(_components.strong,{children:`validation and smoke-test tool`}),` (the Validate button’s live discovery probe is still the fastest way to confirm the CM can reach your identity provider): make the durable configuration an `,_jsx(_components.code,{children:`install-settings.json`}),` on a persistent volume, or `,_jsx(_components.code,{children:`GRADIAL_IDENTITY_*`}),` environment variables in your compose file/manifest — both are re-applied automatically on every CM start.`]}),_jsxs(_components.p,{children:[`Precedence note: when `,_jsx(_components.code,{children:`install-settings.json`}),` or `,_jsx(_components.code,{children:`GRADIAL_IDENTITY_*`}),` variables are present, they are authoritative on every CM start for the settings they supply — values saved through this page for those same settings are overwritten at the next app-pool recycle.`]}),_jsx(_components.p,{children:`On a classic VM/IIS install the webroot is durable and this page is a perfectly good permanent configuration method.`})]}),_jsx(Info,{children:_jsxs(_components.p,{children:[`Prefer configuration-as-code? You can supply the same identity values without the page: hand-edit the config patch (see `,_jsx(_components.a,{href:`#4-module-configuration-reference`,children:`Section 4`}),`), set `,_jsx(_components.code,{children:`GRADIAL_IDENTITY_*`}),` environment variables, or drop an `,_jsx(_components.code,{children:`install-settings.json`}),` in the Sitecore data folder — the last two are applied automatically on CM start. Non-identity settings such as `,_jsx(_components.code,{children:`Gradial.Security.AllowedDatabases`}),` are always edited in the config patch.`]})})]}),_jsx(Step,{title:`Create the service user and grant rights`,children:_jsxs(_components.p,{children:[`Create the Sitecore user referenced by `,_jsx(_components.code,{children:`Gradial.Sitecore.ServiceUser`}),` (default `,_jsx(_components.code,{children:`sitecore\\\\gradial-service`}),`) and grant the item-level rights in `,_jsx(_components.a,{href:`#3-service-user-permissions`,children:`Section 3`}),`.`]})}),_jsx(Step,{title:`Verify end to end`,children:_jsxs(_components.p,{children:[`Confirm `,_jsx(_components.code,{children:`GET https://\u003ccm-host>/_api/gradial/health`}),` returns `,_jsx(_components.code,{children:`200`}),`, then run the `,_jsx(_components.a,{href:`#end-to-end-smoke-test`,children:`OIDC smoke test`}),` to confirm a real token is accepted.`]})})]}),`\n`,_jsx(Heading,{level:`3`,id:`uninstall`,children:`Uninstall`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Sitecore package / drop-in zip:`}),` stop the app pool, remove `,_jsx(_components.code,{children:`bin\\\\Gradial.SitecoreXP.Gateway.*.dll`}),`, `,_jsx(_components.code,{children:`bin\\\\Swashbuckle.Core.dll`}),`, and the entire `,_jsx(_components.code,{children:`App_Config\\\\Include\\\\Gradial\\\\`}),` folder, then restart the app pool.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`WDP:`}),` remove the module step from your pipeline and redeploy, or delete the same files from the web app. The `,_jsx(_components.code,{children:`Gradial.CmGateway.Customer.config`}),` written by the setup page is not part of any package, so remove it by hand if you want the identity configuration gone too.`]}),`\n`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`2-register-gradial-as-an-oidc-client`,children:`2. Register Gradial as an OIDC client`}),`\n`,_jsxs(_components.p,{children:[`The gateway is an `,_jsx(_components.strong,{children:`OAuth 2.0 resource server`}),` — it validates JWTs but never issues them. Token issuance is the job of your OIDC provider. You need to register three things there:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Concept`}),_jsx(_components.th,{children:`Purpose`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`API resource (audience)`})}),_jsxs(_components.td,{children:[`Identifies the gateway as a protected resource. The token’s `,_jsx(_components.code,{children:`aud`}),` claim must match.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`API scope`})}),_jsx(_components.td,{children:`Permission name the caller must request to get a usable token.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Client`})}),_jsxs(_components.td,{children:[`Gradial’s identity. Has a `,_jsx(_components.code,{children:`client_id`}),` + `,_jsx(_components.code,{children:`client_secret`}),` and is authorized for the scope above.`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`Gradial requests tokens with the `,_jsx(_components.strong,{children:`client credentials grant`}),` and sends them on the `,_jsx(_components.code,{children:`Authorization: Bearer \u003ctoken>`}),` header of every request.`]}),`\n`,_jsx(Heading,{level:`3`,id:`how-the-values-map-across-the-three-sides`,children:`How the values map across the three sides`}),`\n`,_jsx(CodeBlock,{numberOfLines:`10`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`10`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`OIDC Provider Gateway config (Gradial.CmGateway.config)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`───────────── ──────────────────────────────────────────`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`API resource \"gradial.gateway\" ───► Gradial.Identity.ExpectedAudience`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`API scope \"gradial.cm.gateway\" ───► Gradial.Identity.RequiredScopes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Client id \"gradial\" ───► Gradial.Identity.AllowedClientIds`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Issuer URL https://id.example ───► Gradial.Identity.Authority`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Discovery base URL ───► Gradial.Identity.MetadataAddress`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` (gateway appends /.well-known/openid-configuration;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` leave empty to reuse Authority)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`All four values must agree on both sides, or the gateway rejects tokens with `,_jsx(_components.code,{children:`401`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`reference-sitecore-identity-server`,children:`Reference: Sitecore Identity Server`}),`\n`,_jsx(_components.p,{children:`Sitecore Identity Server is based on IdentityServer4 and accepts XML patch files mounted into its container. A complete Gradial registration:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`48`,language:`xml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`xml`,children:_jsxs(_components.code,{language:`xml`,numberOfLines:`48`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c?`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`xml`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` version`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"1.0\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` encoding`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"utf-8\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`?>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Settings`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Sitecore`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`IdentityServer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` \u003c!-- The audience. Gateway's ExpectedAudience must equal Name. -->`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ApiResources`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`GradialGatewayResource`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`gradial.gateway`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`DisplayName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Gradial CM Gateway`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`DisplayName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Scopes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Scope1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`gradial.cm.gateway`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Scope1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Scopes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`GradialGatewayResource`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ApiResources`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` \u003c!-- The scope. Gateway's RequiredScopes must contain Name. -->`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ApiScopes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`GradialCmGatewayScope`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`gradial.cm.gateway`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`DisplayName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Gradial CM Gateway Access`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`DisplayName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`GradialCmGatewayScope`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ApiScopes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` \u003c!-- One client per calling tool. Gateway's AllowedClientIds must contain ClientId. -->`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Clients`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`GradialClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`gradial`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Gradial Gateway Client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AccessTokenType`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AccessTokenType`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AccessTokenLifetimeInSeconds`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`3600`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AccessTokenLifetimeInSeconds`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`RequireClientSecret`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`RequireClientSecret`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowOfflineAccess`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowOfflineAccess`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedGrantTypes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedGrantType1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`client_credentials`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedGrantType1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedGrantTypes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientSecrets`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientSecret1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`$(env:GRADIAL_CLIENT_SECRET)`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientSecret1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ClientSecrets`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedScopes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedScope1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`gradial.cm.gateway`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedScope1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`AllowedScopes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`GradialClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Clients`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`IdentityServer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Sitecore`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Settings`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Place this in the Identity container’s config directory (typically `,_jsx(_components.code,{children:`Config/production/`}),` or via a mounted volume) and restart the container.`]}),`\n`,_jsx(Info,{children:_jsx(_components.p,{children:`If you use a different OIDC provider (Azure AD, Okta, Auth0, Keycloak, etc.), the concepts are identical — register an API resource, an API scope, and a client-credentials client, then map the four values into the gateway’s config.`})}),`\n`,_jsx(Heading,{level:`3`,id:`split-horizon-networks-internal-vs-public-issuer`,children:`Split-horizon networks (internal vs. public issuer)`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`MetadataAddress`}),` exists for the case where `,_jsx(_components.strong,{children:`the ID server has a different internal origin than the JWT’s public issuer URL`}),`. In simple deployments where the CM can reach the same URL clients use, leave `,_jsx(_components.code,{children:`MetadataAddress`}),` empty and the gateway will derive everything from `,_jsx(_components.code,{children:`Authority`}),`.`]}),`\n`,_jsx(_components.p,{children:`This split is common in containerized deployments. For example:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The Sitecore Identity container is reachable from the CM container at `,_jsx(_components.code,{children:`http://id`}),` (an internal Docker DNS name, plain HTTP).`]}),`\n`,_jsxs(_components.li,{children:[`The same Identity service is reachable from the public internet at `,_jsx(_components.code,{children:`https://id.example.com`}),` (TLS, public DNS).`]}),`\n`,_jsxs(_components.li,{children:[`Tokens issued to Gradial carry `,_jsx(_components.code,{children:`iss: https://id.example.com`}),` because that’s the issuer the public clients trust.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`In this case:`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`Value`}),_jsx(_components.th,{children:`Why`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.Authority`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`https://id.example.com`})}),_jsxs(_components.td,{children:[`Must match the JWT’s `,_jsx(_components.code,{children:`iss`}),` claim. The gateway compares this string to the token’s issuer during validation.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.MetadataAddress`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`http://id`})}),_jsxs(_components.td,{children:[`Base URL the gateway uses to fetch the discovery document and signing keys. Use the internal hostname the CM container can actually reach. The gateway appends `,_jsx(_components.code,{children:`/.well-known/openid-configuration`}),` automatically — do `,_jsx(_components.strong,{children:`not`}),` include that suffix here.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.DiscoveryRequireHttps`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`false`})}),_jsxs(_components.td,{children:[`Required when `,_jsx(_components.code,{children:`MetadataAddress`}),` is plain HTTP. Leave `,_jsx(_components.code,{children:`true`}),` when both URLs are HTTPS.`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`Sitecore patch form for `,_jsx(_components.code,{children:`MetadataAddress`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`xml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`xml`,children:_jsxs(_components.code,{language:`xml`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`setting`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Gradial.Identity.MetadataAddress\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`patch:attribute`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`http://id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`patch:attribute`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`setting`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Never set `,_jsx(_components.code,{children:`Authority`}),` to the internal URL. The gateway validates the token’s `,_jsx(_components.code,{children:`iss`}),` claim against `,_jsx(_components.code,{children:`Authority`}),`, and the issuer baked into the token is the public URL — using the internal URL there will fail every token with a `,_jsx(_components.code,{children:`401`}),`.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`generating-the-client-secret`,children:`Generating the client secret`}),`\n`,_jsxs(_components.p,{children:[`Use `,_jsx(_components.strong,{children:`32 bytes (256 bits) of cryptographic randomness`}),`, base64-encoded.`]}),`\n`,_jsx(_components.p,{children:`PowerShell:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`powershell`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`powershell`,children:_jsxs(_components.code,{language:`powershell`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`Convert`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]::ToBase64String([`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`System.Security.Cryptography.RandomNumberGenerator`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]::GetBytes(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`32`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`))`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`OpenSSL:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`openssl`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` rand`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -base64`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 32`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Do not use GUIDs, `,_jsx(_components.code,{children:`Get-Random`}),`, or human-friendly password generators — they have insufficient entropy.`]})}),`\n`,_jsxs(_components.p,{children:[`Store the plaintext secret in a secret manager. Inject it into the Identity container as an environment variable (the sample above reads `,_jsx(_components.code,{children:`$(env:GRADIAL_CLIENT_SECRET)`}),`). Provide the same plaintext value to Gradial when you create the integration.`]}),`\n`,_jsx(Heading,{level:`3`,id:`rotating-the-secret`,children:`Rotating the secret`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Generate a new secret.`}),`\n`,_jsxs(_components.li,{children:[`Add it as `,_jsx(_components.code,{children:`\u003cClientSecret2>`}),` alongside the existing one — IdentityServer4 accepts any configured secret, so old and new both work during rollover.`]}),`\n`,_jsx(_components.li,{children:`Update the integration in Gradial to use the new secret.`}),`\n`,_jsxs(_components.li,{children:[`Once traffic has migrated, remove the old `,_jsx(_components.code,{children:`\u003cClientSecret1>`}),` and restart the Identity container.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`end-to-end-smoke-test`,children:`End-to-end smoke test`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`15`,language:`powershell`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`powershell`,children:_jsxs(_components.code,{language:`powershell`,numberOfLines:`15`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$body`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` @`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` client_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"gradial\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` client_secret`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:`env:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`GRADIAL_CLIENT_SECRET`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` grant_type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"client_credentials\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` scope`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"gradial.cm.gateway\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$token`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`Invoke-RestMethod`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:\" `\"})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Uri `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://\u003cyour-id-host>/connect/token\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:\" `\"})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Method Post `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:\"`\"})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Body `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$body`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).access_token`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`Invoke-RestMethod`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:\" `\"})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Uri `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://\u003cyour-cm-host>/_api/gradial/whoami\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:\" `\"})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Headers `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`@`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Authorization`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Bearer `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$token`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`A successful `,_jsx(_components.code,{children:`/whoami`}),` response returns the client identity extracted from the token.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`3-service-user-permissions`,children:`3. Service user permissions`}),`\n`,_jsxs(_components.p,{children:[`The gateway executes every Sitecore operation as the configured service user (`,_jsx(_components.code,{children:`Gradial.Sitecore.ServiceUser`}),`, default `,_jsx(_components.code,{children:`sitecore\\\\gradial-service`}),`). The OIDC client identity authorizes Gradial to call the gateway; the Sitecore user is what actually reads and writes content in Sitecore. Sitecore’s audit trail records this user, not the JWT caller — the gateway logs the JWT caller separately, with a correlation ID joining the two streams.`]}),`\n`,_jsx(Heading,{level:`3`,id:`recommended-rights`,children:`Recommended rights`}),`\n`,_jsxs(_components.p,{children:[`Grant the minimum item-level rights for the content roots the integration will operate against. Replace `,_jsx(_components.code,{children:`[TENANT]`}),` and `,_jsx(_components.code,{children:`[SITE]`}),` with your actual values; repeat for every tenant/site you want to expose.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Path`}),_jsx(_components.th,{children:`Rights`}),_jsx(_components.th,{children:`Notes`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/sitecore/content/[TENANT]/[SITE]`})}),_jsx(_components.td,{children:`Read, Write, Create, Delete, Rename`}),_jsx(_components.td,{children:`Content tree the integration will manage.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/sitecore/media library/Project/[TENANT]/[SITE]`})}),_jsx(_components.td,{children:`Read, Write, Create, Delete, Rename`}),_jsx(_components.td,{children:`Media items associated with the same site.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/sitecore/templates`})}),_jsx(_components.td,{children:`Read`}),_jsxs(_components.td,{children:[`Required so the gateway can resolve field definitions when reading or creating items. `,_jsx(_components.strong,{children:`Do not grant Write`}),` — content operations should never mutate templates.`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`Apply rights with inheritance (“Descendants”) so child items inherit them. Use the Sitecore Security Editor (`,_jsx(_components.strong,{children:`Desktop → Security Tools → Security Editor`}),`), or assign the user to a role that carries these rights.`]}),`\n`,_jsx(Heading,{level:`3`,id:`path-level-access-control`,children:`Path-level access control`}),`\n`,_jsx(_components.p,{children:`Path-level access control is enforced by:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`The Sitecore ACLs above on the service user — anything outside the granted scope returns `,_jsx(_components.code,{children:`403`}),` from the underlying SDK.`]}),`\n`,_jsx(_components.li,{children:`The consuming application’s allowed-paths configuration (set in Gradial).`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Database-level access is enforced separately by the `,_jsx(_components.code,{children:`Gradial.Security.AllowedDatabases`}),` setting. Requests targeting a database outside the allowlist are rejected before any Sitecore call is made. The setting `,_jsx(_components.strong,{children:`fails closed`}),` — an empty allowlist denies all requests.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`4-module-configuration-reference`,children:`4. Module configuration reference`}),`\n`,_jsxs(_components.p,{children:[`All settings live in `,_jsx(_components.code,{children:`App_Config\\\\Include\\\\Gradial\\\\Gradial.CmGateway.config`}),`. Most defaults are correct out of the box; only the identity values are required.`]}),`\n`,_jsx(Heading,{level:`3`,id:`module`,children:`Module`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`Default`}),_jsx(_components.th,{children:`Description`})]})}),_jsx(_components.tbody,{children:_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Enabled`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`true`})}),_jsxs(_components.td,{children:[`Master switch. When `,_jsx(_components.code,{children:`false`}),`, the initializer skips route registration and the gateway is dormant.`]})]})})]}),`\n`,_jsx(Heading,{level:`3`,id:`identity-oidc-/-jwt-validation`,children:`Identity (OIDC / JWT validation)`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`Default`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.Authority`})}),_jsx(_components.td,{children:_jsx(_components.em,{children:`(empty — required)`})}),_jsxs(_components.td,{children:[`OIDC issuer URL. The token’s `,_jsx(_components.code,{children:`iss`}),` claim must match.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.ExpectedAudience`})}),_jsx(_components.td,{children:_jsx(_components.em,{children:`(empty — required)`})}),_jsxs(_components.td,{children:[`Value the token’s `,_jsx(_components.code,{children:`aud`}),` claim must equal.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.ValidateAudience`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`true`})}),_jsxs(_components.td,{children:[`Disable only for diagnostics. Keep `,_jsx(_components.code,{children:`true`}),` in production.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.AllowedClientIds`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`gradial`})}),_jsxs(_components.td,{children:[`Pipe-separated list of client IDs allowed to call the gateway (e.g. `,_jsx(_components.code,{children:`gradial|tool-b`}),`). The token’s `,_jsx(_components.code,{children:`client_id`}),` claim must appear here.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.RequiredScopes`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`gradial.cm.gateway`})}),_jsx(_components.td,{children:`Pipe-separated list of scopes the token must contain.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.ClockSkewMinutes`})}),_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`2`})}),_jsx(_components.td,{children:`Allowance for clock drift between the OIDC issuer and CM server.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.ClientIdClaimType`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`client_id`})}),_jsx(_components.td,{children:`Claim name used to read the client ID from the token. Override only if your provider emits a non-standard claim.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.MetadataAddress`})}),_jsx(_components.td,{children:_jsx(_components.em,{children:`(empty)`})}),_jsxs(_components.td,{children:[`Base URL for OIDC discovery and JWKS fetches. The gateway appends `,_jsx(_components.code,{children:`/.well-known/openid-configuration`}),` itself, so the value is just an origin (e.g. `,_jsx(_components.code,{children:`http://id`}),`) — not a full discovery URL. Leave empty to reuse `,_jsx(_components.code,{children:`Authority`}),`. Set this only when the CM cannot reach `,_jsx(_components.code,{children:`Authority`}),` directly; see `,_jsx(_components.a,{href:`#split-horizon-networks-internal-vs-public-issuer`,children:`Split-horizon networks`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Identity.DiscoveryRequireHttps`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`true`})}),_jsxs(_components.td,{children:[`Enforces HTTPS for the discovery endpoint. Only set `,_jsx(_components.code,{children:`false`}),` for local development against a non-TLS Identity host.`]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`sitecore-execution-context`,children:`Sitecore execution context`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`Default`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Sitecore.ServiceUser`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`sitecore\\\\gradial-service`})}),_jsxs(_components.td,{children:[`The Sitecore user every gateway operation runs as. Must exist before the app pool starts. See `,_jsx(_components.a,{href:`#3-service-user-permissions`,children:`Section 3`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Sitecore.DefaultDatabase`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`master`})}),_jsxs(_components.td,{children:[`Database used when a request omits `,_jsx(_components.code,{children:`?db=`}),`.`]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`security`,children:`Security`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`Default`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Security.AllowedDatabases`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`master`})}),_jsxs(_components.td,{children:[`Pipe-separated allowlist of databases the gateway may touch (e.g. `,_jsx(_components.code,{children:`master|web`}),`). `,_jsx(_components.strong,{children:`Fails closed`}),` — empty value denies all requests.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Security.DefaultFields`})}),_jsx(_components.td,{children:_jsx(_components.em,{children:`(empty)`})}),_jsx(_components.td,{children:`Pipe-separated list of fields always returned in item responses. Empty means “all fields except those denied”.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Security.DeniedFields`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`__Security|__Owner|__Workflow state|__Lock|__Created by|__Updated by`})}),_jsx(_components.td,{children:`Pipe-separated list of fields stripped from every response.`})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`feature-settings`,children:`Feature settings`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`Default`}),_jsx(_components.th,{children:`Description`})]})}),_jsx(_components.tbody,{children:_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Features.Preview.Enabled`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`true`})}),_jsxs(_components.td,{children:[`Enables the page preview rendering endpoints. Set `,_jsx(_components.code,{children:`false`}),` to disable preview entirely.`]})]})})]}),`\n`,_jsx(Heading,{level:`3`,id:`preview-rendering-http-loopback`,children:`Preview rendering (HTTP loopback)`}),`\n`,_jsx(_components.p,{children:`The preview endpoint renders a page by issuing an HTTP request back to the CM. These settings control that loopback.`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`Default`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Preview.CmBaseUrl`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`http://localhost`})}),_jsx(_components.td,{children:`Base URL preview requests target. If empty, preview derives the base URL from the incoming gateway request’s scheme + host.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Preview.IgnoreCertificateErrors`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`false`})}),_jsxs(_components.td,{children:[`When `,_jsx(_components.code,{children:`true`}),`, the loopback HTTP client accepts self-signed and invalid TLS certs. `,_jsx(_components.strong,{children:`Only enable in non-production.`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Gradial.Preview.RenderTimeoutSeconds`})}),_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`60`})}),_jsx(_components.td,{children:`Maximum time to wait for a loopback render before giving up.`})]})]})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`5-create-the-integration-in-gradial`,children:`5. Create the integration in Gradial`}),`\n`,_jsx(_components.p,{children:`With the gateway installed, the OIDC client registered, and the service user permissioned, you can now create the integration in Gradial.`}),`\n`,_jsx(Heading,{level:`3`,id:`connection`,children:`Connection`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`Value`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Integration name`})}),_jsxs(_components.td,{children:[`A name for this connection (e.g. `,_jsx(_components.code,{children:`Acme Production CM`}),`).`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`Description`}),` `,_jsx(_components.em,{children:`(optional)`})]}),_jsx(_components.td,{children:`Free-text notes — environment, owner, ticket reference, etc.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Sitecore CM URL`})}),_jsxs(_components.td,{children:[`Base URL of the CM instance, e.g. `,_jsx(_components.code,{children:`https://cm.example.com`}),`. Do `,_jsx(_components.strong,{children:`not`}),` include `,_jsx(_components.code,{children:`/_api/gradial`}),`; Gradial appends that automatically.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Mark as production`})}),_jsx(_components.td,{children:`Tick if this is a production CM. Gradial uses this flag to apply additional confirmation steps and audit emphasis.`})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`credential`,children:`Credential`}),`\n`,_jsxs(_components.p,{children:[`These are the values you produced in `,_jsx(_components.a,{href:`#2-register-gradial-as-an-oidc-client`,children:`Section 2`}),`.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`Value`}),_jsx(_components.th,{children:`Maps to`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Client ID`})}),_jsxs(_components.td,{children:[`The client registered in your OIDC provider (e.g. `,_jsx(_components.code,{children:`gradial`}),`).`]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`\u003cClientId>`}),` and `,_jsx(_components.code,{children:`Gradial.Identity.AllowedClientIds`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Client Secret`})}),_jsx(_components.td,{children:`Plaintext secret you generated (32 bytes, base64). Store securely — Gradial will not display it again after save.`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`\u003cClientSecret1>`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Token URL`})}),_jsxs(_components.td,{children:[`Token endpoint of your OIDC provider, e.g. `,_jsx(_components.code,{children:`https://id.example.com/connect/token`}),`.`]}),_jsxs(_components.td,{children:[`The `,_jsx(_components.code,{children:`token_endpoint`}),` published by the discovery document.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Scope`})}),_jsx(_components.td,{children:`The scope the gateway requires.`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`Gradial.Identity.RequiredScopes`}),` (default `,_jsx(_components.code,{children:`gradial.cm.gateway`}),`).`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Audience`})}),_jsx(_components.td,{children:`The audience the gateway expects.`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`Gradial.Identity.ExpectedAudience`}),` (e.g. `,_jsx(_components.code,{children:`gradial.gateway`}),`).`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`After saving, Gradial will fetch a token via the client-credentials grant and call `,_jsx(_components.code,{children:`/_api/gradial/health`}),` and `,_jsx(_components.code,{children:`/_api/gradial/whoami`}),` to verify the connection end-to-end.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`failure-modes`,children:`Failure modes`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`HTTP status`}),_jsx(_components.th,{children:`Likely cause`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`401 Unauthorized`}),` (every request)`]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`Authority`}),` mismatch, signing key not loadable, or `,_jsx(_components.code,{children:`ExpectedAudience`}),` doesn’t match the token’s `,_jsx(_components.code,{children:`aud`}),` claim.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`403 Forbidden`}),` with `,_jsx(_components.code,{children:`insufficient_scope`})]}),_jsxs(_components.td,{children:[`Token doesn’t include a scope listed in `,_jsx(_components.code,{children:`RequiredScopes`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`403 Forbidden`}),` with `,_jsx(_components.code,{children:`client not allowed`})]}),_jsxs(_components.td,{children:[`Client ID isn’t in `,_jsx(_components.code,{children:`AllowedClientIds`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`403 Forbidden`}),` on item operations`]}),_jsxs(_components.td,{children:[`Service user lacks the required rights on the requested path. Review `,_jsx(_components.a,{href:`#3-service-user-permissions`,children:`Section 3`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`503 Service Unavailable`}),` on authenticated endpoints`]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`Authority`}),` is empty or the gateway can’t reach the discovery document at `,_jsx(_components.code,{children:`MetadataAddress`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`404 Not Found`}),` on `,_jsx(_components.code,{children:`/_api/gradial/*`})]}),_jsxs(_components.td,{children:[`Gateway didn’t initialize. Check the Sitecore log for `,_jsx(_components.code,{children:`[Gradial.Gateway]`}),` errors during app pool startup.`]})]})]})]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`All gateway log entries are tagged `,_jsx(_components.code,{children:`[Gradial.Gateway]`}),` and include a correlation ID. When opening a support case, include the correlation ID from the failed request’s `,_jsx(_components.code,{children:`X-Correlation-Id`}),` response header.`]})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Sitecore XP","description":"Connect Gradial's AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.","href":"/docs/integrations-administration-and-setup/integrations/sitecore-xp"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What you’ll need","slug":"what-you’ll-need","depth":2,"children":[]},{"title":"Steps in this guide","slug":"steps-in-this-guide","depth":2,"children":[]},{"title":"1. Install the Service Gateway module","slug":"1-install-the-service-gateway-module","depth":2,"children":[{"title":"After installing (all methods)","slug":"after-installing-all-methods","depth":3,"children":[]},{"title":"Uninstall","slug":"uninstall","depth":3,"children":[]}]},{"title":"2. Register Gradial as an OIDC client","slug":"2-register-gradial-as-an-oidc-client","depth":2,"children":[{"title":"How the values map across the three sides","slug":"how-the-values-map-across-the-three-sides","depth":3,"children":[]},{"title":"Reference: Sitecore Identity Server","slug":"reference-sitecore-identity-server","depth":3,"children":[]},{"title":"Split-horizon networks (internal vs. public issuer)","slug":"split-horizon-networks-internal-vs-public-issuer","depth":3,"children":[]},{"title":"Generating the client secret","slug":"generating-the-client-secret","depth":3,"children":[]},{"title":"Rotating the secret","slug":"rotating-the-secret","depth":3,"children":[]},{"title":"End-to-end smoke test","slug":"end-to-end-smoke-test","depth":3,"children":[]}]},{"title":"3. Service user permissions","slug":"3-service-user-permissions","depth":2,"children":[{"title":"Recommended rights","slug":"recommended-rights","depth":3,"children":[]},{"title":"Path-level access control","slug":"path-level-access-control","depth":3,"children":[]}]},{"title":"4. Module configuration reference","slug":"4-module-configuration-reference","depth":2,"children":[{"title":"Module","slug":"module","depth":3,"children":[]},{"title":"Identity (OIDC / JWT validation)","slug":"identity-oidc-/-jwt-validation","depth":3,"children":[]},{"title":"Sitecore execution context","slug":"sitecore-execution-context","depth":3,"children":[]},{"title":"Security","slug":"security","depth":3,"children":[]},{"title":"Feature settings","slug":"feature-settings","depth":3,"children":[]},{"title":"Preview rendering (HTTP loopback)","slug":"preview-rendering-http-loopback","depth":3,"children":[]}]},{"title":"5. Create the integration in Gradial","slug":"5-create-the-integration-in-gradial","depth":2,"children":[{"title":"Connection","slug":"connection","depth":3,"children":[]},{"title":"Credential","slug":"credential","depth":3,"children":[]}]},{"title":"Failure modes","slug":"failure-modes","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"gradial","siteName":"Gradial Docs","title":"Sitecore XP - Gradial Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-08-24T17:11:44.335Z","originalFileLocation":"docs/integrations-administration-and-setup/integrations/sitecore-xp.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Connect Gradial\u0026#x27;s AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Gradial Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Sitecore XP - Gradial Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Connect Gradial\u0026#x27;s AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Gradial Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://gradial.mintlify.app/_mintlify/api/og/v2?division=Sitecore\u0026amp;title=Sitecore+XP\u0026amp;description=Connect+Gradial%27s+AI+agents+to+Sitecore+XP+to+automate+content+creation%2C+updates%2C+and+publishing+on+your+on-premises+or+managed+environment.\u0026amp;theme=36c60e18d4f8e3d108d61723\u0026amp;signature=0c83bbe46e9256d6e303731c293b1d89d443065bd49cb102cbb3a85ff52b57cc\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Sitecore XP - Gradial Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Connect Gradial\u0026#x27;s AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://gradial.mintlify.app/_mintlify/api/og/v2?division=Sitecore\u0026amp;title=Sitecore+XP\u0026amp;description=Connect+Gradial%27s+AI+agents+to+Sitecore+XP+to+automate+content+creation%2C+updates%2C+and+publishing+on+your+on-premises+or+managed+environment.\u0026amp;theme=36c60e18d4f8e3d108d61723\u0026amp;signature=0c83bbe46e9256d6e303731c293b1d89d443065bd49cb102cbb3a85ff52b57cc\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/gradial/7-i2K-jVJenc4URQ/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Gradial Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#a855f7\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/integrations-administration-and-setup/integrations/sitecore-xp.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.gradial.com/#organization\",\"name\":\"Gradial Docs\",\"url\":\"https://docs.gradial.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/gradial/RDiUqPSUUpbMwk4U/logo/light.svg?fit=max\u0026auto=format\u0026n=RDiUqPSUUpbMwk4U\u0026q=85\u0026s=3d465cd433ac4e5548cef9e2ca1c64f0\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.gradial.com#website\",\"name\":\"Gradial Docs\",\"url\":\"https://docs.gradial.com\",\"publisher\":{\"@id\":\"https://docs.gradial.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp#webpage\",\"url\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp\",\"name\":\"Sitecore XP\",\"description\":\"Connect Gradial's AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.\",\"dateModified\":\"2026-08-24T17:11:44.335Z\",\"isPartOf\":{\"@id\":\"https://docs.gradial.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Integrations\",\"item\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/get-started-with-integrations\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CMS \u0026 DAM\",\"item\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/aem/aem-overview\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Sitecore\",\"item\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-integration\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Sitecore XP\",\"item\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp#article\",\"headline\":\"Sitecore XP\",\"name\":\"Sitecore XP\",\"description\":\"Connect Gradial's AI agents to Sitecore XP to automate content creation, updates, and publishing on your on-premises or managed environment.\",\"url\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp\",\"mainEntityOfPage\":{\"@id\":\"https://docs.gradial.com/docs/integrations-administration-and-setup/integrations/sitecore-xp#webpage\"},\"dateModified\":\"2026-08-24T17:11:44.335Z\",\"publisher\":{\"@id\":\"https://docs.gradial.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.gradial.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Gradial Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Gradial Docs","nav":{"global":null,"tabs":[{"tab":"Getting Started","pages":[{"title":"Getting Started","href":"/docs/getting-started/what-is-gradial"}]},{"tab":"Gradial in Action","pages":[{"title":"Gradial in Action","href":"/docs/gradial-prompt-library/customer-use-cases"}]},{"tab":"Setup \u0026 Administration","groups":[{"group":"Integrations","pages":[{"title":"Integrations Overview","href":"/docs/integrations-administration-and-setup/integrations/get-started-with-integrations"},{"group":"CMS \u0026 DAM","pages":[{"group":"AEM","pages":[{"title":"AEM Overview","href":"/docs/integrations-administration-and-setup/integrations/aem/aem-overview"},{"title":"AMS/AEM as a Cloud Service","href":"/docs/integrations-administration-and-setup/integrations/aem/aem-cloud"},{"title":"AEM On Prem","href":"/docs/integrations-administration-and-setup/integrations/aem/aem-on-prem"},{"title":"AEM Integration: Advanced Configurations","href":"/docs/integrations-administration-and-setup/integrations/aem/advanced-configurations"},{"title":"Working with AEM Launches","href":"/docs/integrations-administration-and-setup/integrations/aem/aem-launches"},{"title":"AEM OpenAPI","href":"/docs/integrations-administration-and-setup/integrations/aem/aem-openapi"},{"title":"AEM Edge Delivery Services","href":"/docs/integrations-administration-and-setup/integrations/aem/aem-edge-delivery"},{"title":"AEM Guides","href":"/docs/integrations-administration-and-setup/integrations/aem/aem-guides"}]},{"group":"Sitecore","pages":[{"title":"Sitecore","href":"/docs/integrations-administration-and-setup/integrations/sitecore-integration"},{"title":"Sitecore XM Cloud","description":"Connect Gradial's AI agents to Sitecore XM Cloud to automate content creation, updates, and publishing workflows via GraphQL and REST APIs.","href":"/docs/integrations-administration-and-setup/integrations/sitecore-xm-cloud"},{"title":"Sitecore XP","href":"/docs/integrations-administration-and-setup/integrations/sitecore-xp"},{"title":"Sitecore Content Hub","description":"Connect Gradial to Sitecore Content Hub for asset, content, and campaign workflows.","href":"/docs/integrations-administration-and-setup/integrations/sitecore-content-hub-integration"},{"title":"Searching in Content Hub","href":"/docs/integrations-administration-and-setup/integrations/sitecore-content-hub"}]},{"title":"Contentful","href":"/docs/integrations-administration-and-setup/integrations/contentful"},{"title":"Contentstack","href":"/docs/integrations-administration-and-setup/integrations/contentstack"},{"title":"Sanity","href":"/docs/integrations-administration-and-setup/integrations/sanity"},{"title":"Drupal","href":"/docs/integrations-administration-and-setup/integrations/drupal"},{"title":"WordPress","href":"/docs/integrations-administration-and-setup/integrations/wordpress"},{"title":"Bynder","href":"/docs/integrations-administration-and-setup/integrations/bynder"},{"title":"Aprimo","href":"/docs/integrations-administration-and-setup/integrations/aprimo"}]},{"group":"Productivity \u0026 Collaboration","pages":[{"title":"SharePoint","href":"/docs/integrations-administration-and-setup/integrations/sharepoint"},{"title":"Box","href":"/docs/integrations-administration-and-setup/integrations/box"},{"title":"Google Drive","href":"/docs/integrations-administration-and-setup/integrations/google-drive"},{"title":"Slack","href":"/docs/integrations-administration-and-setup/integrations/slack"}]},{"group":"Analytics","pages":[{"title":"Google Analytics","href":"/docs/integrations-administration-and-setup/integrations/analytics/google-analytics"},{"title":"Adobe Analytics","href":"/docs/integrations-administration-and-setup/integrations/analytics/adobe-analytics"},{"title":"Google Search Console","href":"/docs/integrations-administration-and-setup/integrations/analytics/google-search-console"},{"title":"Adobe Customer Journey Analytics","href":"/docs/integrations-administration-and-setup/integrations/customer-journey-analytics"}]},{"group":"Marketing Automation","pages":[{"title":"Marketo","href":"/docs/integrations-administration-and-setup/integrations/marketo"},{"title":"Salesforce Marketing Cloud","href":"/docs/integrations-administration-and-setup/integrations/salesforce-marketing-cloud"},{"title":"HubSpot","href":"/docs/integrations-administration-and-setup/integrations/hubspot"},{"title":"Airship","href":"/docs/integrations-administration-and-setup/integrations/airship"},{"title":"MoEngage","href":"/docs/integrations-administration-and-setup/integrations/moengage"},{"title":"Braze","href":"/docs/integrations-administration-and-setup/integrations/braze"},{"title":"Adobe Target","href":"/docs/integrations-administration-and-setup/integrations/adobe-target"},{"title":"Adobe Experience Platform","href":"/docs/integrations-administration-and-setup/integrations/adobe-experience-platform"},{"title":"Adobe Journey Optimizer","href":"/docs/integrations-administration-and-setup/integrations/adobe-journey-optimizer"},{"title":"DaVinci Commerce","href":"/docs/integrations-administration-and-setup/integrations/davinci-commerce"}]},{"group":"Design","pages":[{"title":"Figma","href":"/docs/integrations-administration-and-setup/integrations/figma"},{"title":"Figma MCP","tag":"Preview","href":"/docs/integrations-administration-and-setup/integrations/figma-mcp"}]},{"group":"Custom Integrations \u0026 APIs","pages":[{"title":"Custom MCP Agent Integration","href":"/docs/integrations-administration-and-setup/integrations/custom-mcp"},{"title":"Agent2Agent (A2A) Server","hidden":true,"href":"/docs/integrations/a2a"}]}]},{"group":"Setup Reference","hidden":true,"pages":[{"title":"IP Allowlisting","href":"/docs/integrations-administration-and-setup/ip-allowlist"}]},{"group":"Ticketing Systems","pages":[{"title":"Connecting to External Ticketing Systems","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/setting-up-ticketing-integrations"},{"group":"Supported Systems","pages":[{"title":"Jira","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/jira"},{"title":"Workfront","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/workfront"},{"title":"Wrike","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/Wrike-Integration"},{"title":"Asana","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/asana"},{"title":"monday.com","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/monday"},{"title":"Airtable","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/airtable"},{"title":"Azure DevOps","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/azure-devops"}]},{"title":"Routing Tickets to Gradial Workspaces","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/routing-tickets"},{"title":"Creating Tickets from Gradial","href":"/docs/integrations-administration-and-setup/how-gradial-works-with-ticketing-systems/creating-tickets-from-gradial"}]},{"group":"Managing Access","pages":[{"title":"Manage Team Members","href":"/docs/integrations-administration-and-setup/managing-access/manage-team-members"},{"group":"Single Sign-On (SSO)","pages":[{"title":"Single Sign-On (SSO)","href":"/docs/integrations-administration-and-setup/managing-access/sso"},{"title":"SCIM User Provisioning","href":"/docs/integrations-administration-and-setup/managing-access/scim"}]},{"title":"Roles \u0026 Permissions","href":"/docs/integrations-administration-and-setup/managing-access/roles"},{"title":"User Groups","href":"/docs/integrations-administration-and-setup/managing-access/groups"}]}]},{"tab":"Release Notes","pages":[{"title":"Release Notes","href":"/release-notes/overview"}]},{"tab":"Gradial ACI","hidden":true,"searchable":true,"pages":[{"title":"Gradial ACI","href":"/aci/getting-started/what-is-gradial-aci"}]}]},"basePath":"","title":"Sitecore XP - Gradial Docs","buildId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","deploymentId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","dynamics":["07c022d89b","a74be98ba7"],"chunks":["Frame-DXXFP6nH.js","DynamicMarkdown-B54_zNBF.js","zoom-image-lightbox-BG6oD64b.js","lightbox-handle-r17bVUz3.js"]}