Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-docs

Deploy with a bootstrap server changedthird-party/claude-desktop/bootstrap

Nearest release: v2.1.302, published 2 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 16 Oct 2026 14:21 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 20 Oct 2026 18:07 UTC.

Upstream edited
Recorded here
Lines+148added
Lines−156removed
From line 2 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits24to this page, all time

The whole hunk

from line 2, old and new numbered
/
lines
from line 2
22 
33> Host an HTTPS endpoint that returns each user's configuration, for organizations without MDM or with role-based configuration too complex for per-group profiles
44 
5<Note>
6 Requires Claude Desktop **1.10628.0** or later. Earlier builds ignore the `bootstrapUrl` keys.
7</Note>
5> [!NOTE]
6>
7> Requires Claude Desktop **1.10628.0** or later. Earlier builds ignore the `bootstrapUrl` keys.
88 
99A **bootstrap server** is an HTTPS endpoint you host that authenticates each user against your identity provider and returns that user's configuration as JSON. Use it when your organization doesn't have MDM, or when configuration varies too widely for per-group profiles: per-user gateway credentials, per-team model allowlists, or per-user OpenTelemetry attribution. When one configuration or a few group-scoped profiles cover your fleet, [deploying with MDM](/docs/third-party/claude-desktop/mdm) is simpler; most MDMs support role-based distribution.
1010 
1111When a bootstrap response is available, it **is** the effective configuration. The MDM profile supplies the trust anchor (`bootstrapUrl`, optional `bootstrapOidc` or `bootstrapHeaders`/`bootstrapHeadersHelper`, and the `bootstrapEnabled` opt-out), and Claude Desktop does not consult MDM for any key the bootstrap server is permitted to set. A bootstrap-settable key that your response **omits** is treated as unset, not inherited from MDM, so return every key you want applied.
1212 
13<Warning>
14 Your bootstrap server is fully trusted. Its response can set inference credentials, the egress allowlist, MCP servers, and every other key in the [published schema](#response-schema). Treat compromise of this endpoint as credential compromise: restrict who can deploy it, log every response, and harden it as you would any secrets-issuing service.
15</Warning>
13> [!WARNING]
14>
15> Your bootstrap server is fully trusted. Its response can set inference credentials, the egress allowlist, MCP servers, and every other key in the [published schema](#response-schema). Treat compromise of this endpoint as credential compromise: restrict who can deploy it, log every response, and harden it as you would any secrets-issuing service.
1616 
1717Before the server can take over, each device needs the bootstrap keys that point at it. There are two ways to get them onto a device:
1818 
from line 145
145145 
146146### Separate identity provider (PKCE)
147147 
148<Steps>
149 <Step title="Register a public client in your identity provider">
150 Register a native or public application with a loopback redirect URI and no client secret. The registration is identical to the one used for [gateway single sign-on](/docs/third-party/claude-desktop/gateway#set-up-single-sign-on); if you already have that, reuse it. See the [provider notes](#provider-notes) below for redirect-URI specifics.
148**1. Register a public client in your identity provider**
151149 
152 For Microsoft Entra ID, also set an **Application ID URI** on the registration (App registration → **Expose an API** → **Set**; accept the default `api://CLIENT_ID`). The `CLIENT_ID/.default` scope in the next step does not resolve without it.
153 </Step>
150Register a native or public application with a loopback redirect URI and no client secret. The registration is identical to the one used for [gateway single sign-on](/docs/third-party/claude-desktop/gateway#set-up-single-sign-on); if you already have that, reuse it. See the [provider notes](#provider-notes) below for redirect-URI specifics.
154151 
155 <Step title="Choose the scope your server will validate">
156 The app sends the OAuth **access token** as the bearer. Your server validates that token's `aud`, so the scope you request must produce a token whose audience your server accepts. This is provider-specific:
152For Microsoft Entra ID, also set an **Application ID URI** on the registration (App registration → **Expose an API** → **Set**; accept the default `api://CLIENT_ID`). The `CLIENT_ID/.default` scope in the next step does not resolve without it.
157153 
158 | Provider | Scope to request | Resulting `aud` |
159 | - | - | - |
160 | Microsoft Entra ID | `openid offline_access CLIENT_ID/.default` | your client ID |
161 | Okta (custom authorization server) | `openid offline_access YOUR_API_SCOPE` | your authorization server's audience |
162 | Generic OIDC | `openid offline_access` plus your API's resource scope | provider-specific |
154**2. Choose the scope your server will validate**
163155 
164 Include `offline_access` so the app receives a refresh token and can renew silently between launches.
156The app sends the OAuth **access token** as the bearer. Your server validates that token's `aud`, so the scope you request must produce a token whose audience your server accepts. This is provider-specific:
165157 
166 <Warning>
167 For Entra, use the bare-GUID form `CLIENT_ID/.default`, **not** `api://CLIENT_ID/.default`. The `api://` form works on the initial authorize but fails on the refresh grant with `AADSTS90009` when the client and resource are the same application.
168 </Warning>
169 </Step>
158| Provider | Scope to request | Resulting `aud` |
159| - | - | - |
160| Microsoft Entra ID | `openid offline_access CLIENT_ID/.default` | your client ID |
161| Okta (custom authorization server) | `openid offline_access YOUR_API_SCOPE` | your authorization server's audience |
162| Generic OIDC | `openid offline_access` plus your API's resource scope | provider-specific |
170163 
171 <Step title="Validate the token in your server">
172 See [Server responsibilities](#server-responsibilities). What the token's `iss` and `aud` look like depends on your provider:
164Include `offline_access` so the app receives a refresh token and can renew silently between launches.
173165 
174 | Provider | `iss` to expect | `aud` to expect | JWKS URL |
175 | - | - | - | - |
176 | Microsoft Entra ID (token version `2`) | `https://login.microsoftonline.com/TENANT/v2.0` | your client ID | `https://login.microsoftonline.com/TENANT/discovery/v2.0/keys` |
177 | Okta (custom authorization server) | `https://YOUR_DOMAIN.okta.com/oauth2/AUTH_SERVER_ID` | the audience configured on that authorization server | `<issuer>/v1/keys` |
166> [!WARNING]
167>
168> For Entra, use the bare-GUID form `CLIENT_ID/.default`, **not** `api://CLIENT_ID/.default`. The `api://` form works on the initial authorize but fails on the refresh grant with `AADSTS90009` when the client and resource are the same application.
178169 
179 **Entra token version.** A new Entra app registration emits v1-format access tokens by default, with `iss` = `https://sts.windows.net/TENANT/` and `aud` = `api://CLIENT_ID`. Set the accepted-token-version field in the registration's **Manifest** to `2` so tokens match the table above. The portal shows this field as either `accessTokenAcceptedVersion` or `api.requestedAccessTokenVersion` depending on the manifest view; set whichever you see. If you cannot change it, your server must accept both the v1 and v2 forms.
170**3. Validate the token in your server**
180171 
181 **Group and role claims.** Entra does not emit `groups` or `roles` in access tokens by default. Enable the groups claim under App registration → **Token configuration**, or define **App roles** and assign users via **Enterprise applications**. The `oid` claim is always present. For Okta, add a `groups` claim on your custom authorization server with a group filter.
182 </Step>
172See [Server responsibilities](#server-responsibilities). What the token's `iss` and `aud` look like depends on your provider:
183173 
184 <Step title="Configure and export from Claude Desktop">
185 Install Claude Desktop on an admin workstation (see [Installation](/docs/third-party/claude-desktop/installation)). From the menu bar, open **Developer → Configure Third-Party Inference…**. In the **Source** section, fill in the **Bootstrap config URL** card:
174| Provider | `iss` to expect | `aud` to expect | JWKS URL |
175| - | - | - | - |
176| Microsoft Entra ID (token version `2`) | `https://login.microsoftonline.com/TENANT/v2.0` | your client ID | `https://login.microsoftonline.com/TENANT/discovery/v2.0/keys` |
177| Okta (custom authorization server) | `https://YOUR_DOMAIN.okta.com/oauth2/AUTH_SERVER_ID` | the audience configured on that authorization server | `<issuer>/v1/keys` |
186178 
187 | Field | Value |
188 | - | - |
189 | Bootstrap config URL | `https://YOUR_BOOTSTRAP_HOST/user/bootstrap` |
190 | Bootstrap OIDC parameters → Client ID | `YOUR_CLIENT_ID` |
191 | Bootstrap OIDC parameters → Issuer URL | `https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0` |
192 | Bootstrap OIDC parameters → Scopes | `openid offline_access YOUR_CLIENT_ID/.default` |
193 | Bootstrap OIDC parameters → Redirect port | leave empty for Entra; set for Okta |
179**Entra token version.** A new Entra app registration emits v1-format access tokens by default, with `iss` = `https://sts.windows.net/TENANT/` and `aud` = `api://CLIENT_ID`. Set the accepted-token-version field in the registration's **Manifest** to `2` so tokens match the table above. The portal shows this field as either `accessTokenAcceptedVersion` or `api.requestedAccessTokenVersion` depending on the manifest view; set whichever you see. If you cannot change it, your server must accept both the v1 and v2 forms.
194180 
195 Click **Sign in** to test against your typed values. Once authenticated, the card shows the keys your server supplied. Click **Export** and choose the template format your MDM expects (such as `.mobileconfig`, ADMX, or `.reg`). See [Deploy the configuration](/docs/third-party/claude-desktop/mdm#4-deploy-the-configuration) for per-platform instructions.
196 </Step>
197</Steps>
181**Group and role claims.** Entra does not emit `groups` or `roles` in access tokens by default. Enable the groups claim under App registration → **Token configuration**, or define **App roles** and assign users via **Enterprise applications**. The `oid` claim is always present. For Okta, add a `groups` claim on your custom authorization server with a group filter.
198182 
183**4. Configure and export from Claude Desktop**
184 
185Install Claude Desktop on an admin workstation (see [Installation](/docs/third-party/claude-desktop/installation)). From the menu bar, open **Developer → Configure Third-Party Inference…**. In the **Source** section, fill in the **Bootstrap config URL** card:
186 
187| Field | Value |
188| - | - |
189| Bootstrap config URL | `https://YOUR_BOOTSTRAP_HOST/user/bootstrap` |
190| Bootstrap OIDC parameters → Client ID | `YOUR_CLIENT_ID` |
191| Bootstrap OIDC parameters → Issuer URL | `https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0` |
192| Bootstrap OIDC parameters → Scopes | `openid offline_access YOUR_CLIENT_ID/.default` |
193| Bootstrap OIDC parameters → Redirect port | leave empty for Entra; set for Okta |
194 
195Click **Sign in** to test against your typed values. Once authenticated, the card shows the keys your server supplied. Click **Export** and choose the template format your MDM expects (such as `.mobileconfig`, ADMX, or `.reg`). See [Deploy the configuration](/docs/third-party/claude-desktop/mdm#4-deploy-the-configuration) for per-platform instructions.
196 
199197#### Provider notes
200198 
201199| Provider | Redirect URI to register | Redirect port field | Additional setup |
from line 210
212210 
213211Set only `bootstrapUrl` in MDM. The app discovers your authorization endpoints via RFC 8414 and runs an RFC 8628 device-code grant. The bearer is reused for inference when `inferenceGatewayBaseUrl` shares the `bootstrapUrl` origin and `inferenceCredentialKind` is `interactive`, so the user signs in once for both.
214212 
215<Steps>
216 <Step title="Publish RFC 8414 discovery metadata">
217 Serve a metadata document under the `bootstrapUrl` path. If `bootstrapUrl` ends in `/bootstrap` or `/user/bootstrap`, that suffix is stripped to form the issuer base.
213**1. Publish RFC 8414 discovery metadata**
218214 
219 ```text theme={null}
220 GET https://YOUR_BOOTSTRAP_HOST/.well-known/oauth-authorization-server
221 ```
215Serve a metadata document under the `bootstrapUrl` path. If `bootstrapUrl` ends in `/bootstrap` or `/user/bootstrap`, that suffix is stripped to form the issuer base.
222216 
223 ```json theme={null}
224 {
225 "issuer": "https://YOUR_BOOTSTRAP_HOST",
226 "token_endpoint": "https://YOUR_BOOTSTRAP_HOST/oauth/token",
227 "device_authorization_endpoint": "https://YOUR_BOOTSTRAP_HOST/oauth/device"
228 }
229 ```
217```text theme={null}
218GET https://YOUR_BOOTSTRAP_HOST/.well-known/oauth-authorization-server
219```
230220 
231 Every endpoint URL must share the `bootstrapUrl` origin. Metadata that points off-origin is rejected.
232 </Step>
221```json theme={null}
222{
223 "issuer": "https://YOUR_BOOTSTRAP_HOST",
224 "token_endpoint": "https://YOUR_BOOTSTRAP_HOST/oauth/token",
225 "device_authorization_endpoint": "https://YOUR_BOOTSTRAP_HOST/oauth/device"
226}
227```
233228 
234 <Step title="Implement the device-code grant">
235 `POST` to `device_authorization_endpoint` returns:
229Every endpoint URL must share the `bootstrapUrl` origin. Metadata that points off-origin is rejected.
236230 
237 ```json theme={null}
238 {
239 "device_code": "EXAMPLE-DEVICE-CODE-OPAQUE-TO-CLIENT",
240 "user_code": "ABCD-EFGH",
241 "verification_uri": "https://YOUR_BOOTSTRAP_HOST/activate",
242 "verification_uri_complete": "https://YOUR_BOOTSTRAP_HOST/activate?user_code=ABCD-EFGH",
243 "interval": 5,
244 "expires_in": 600
245 }
246 ```
231**2. Implement the device-code grant**
247232 
248 `verification_uri` and `verification_uri_complete` must share the `bootstrapUrl` origin; federate behind your own pages rather than returning an upstream provider's URL directly. The app opens the verification URL in the user's browser and shows the user code.
233`POST` to `device_authorization_endpoint` returns:
249234 
250 The app polls `token_endpoint` with `grant_type=urn:ietf:params:oauth:grant-type:device_code` and the `device_code`. Return `{"error":"authorization_pending"}` until the user approves, then:
235```json theme={null}
236{
237 "device_code": "EXAMPLE-DEVICE-CODE-OPAQUE-TO-CLIENT",
238 "user_code": "ABCD-EFGH",
239 "verification_uri": "https://YOUR_BOOTSTRAP_HOST/activate",
240 "verification_uri_complete": "https://YOUR_BOOTSTRAP_HOST/activate?user_code=ABCD-EFGH",
241 "interval": 5,
242 "expires_in": 600
243}
244```
251245 
252 ```json theme={null}
253 { "access_token": "eyJhbGciOiJSUzI1NiIs...", "expires_in": 3600 }
254 ```
246`verification_uri` and `verification_uri_complete` must share the `bootstrapUrl` origin; federate behind your own pages rather than returning an upstream provider's URL directly. The app opens the verification URL in the user's browser and shows the user code.
255247 
256 The polling interval is clamped between 1 and 30 seconds; the grant times out after 5 minutes; the token lifetime you return is clamped between 5 minutes and 30 days (24 hours before 1.17377.1).
248The app polls `token_endpoint` with `grant_type=urn:ietf:params:oauth:grant-type:device_code` and the `device_code`. Return `{"error":"authorization_pending"}` until the user approves, then:
257249 
258 When `inferenceGatewayBaseUrl` shares the `bootstrapUrl` origin, so the same sign-in also serves inference, you may also return a `refresh_token` (optionally with `refresh_token_expires_in` in seconds): as the access token nears expiry during use, Claude Desktop 1.34493.0 and later renews it with an RFC 6749 `grant_type=refresh_token` POST to your `token_endpoint` rather than interrupting the user. The configuration fetch at launch still asks the user to sign in if the access token itself has already expired. Answer `400` with `{"error":"invalid_grant"}` to revoke the refresh token and require a fresh sign-in.
259 </Step>
250```json theme={null}
251{ "access_token": "eyJhbGciOiJSUzI1NiIs...", "expires_in": 3600 }
252```
260253 
261 <Step title="Serve the configuration endpoint">
262 On `GET <bootstrapUrl>` with a valid bearer, look up the user from the token claims and return their configuration (see [the HTTP contract](#the-http-contract)).
263 </Step>
264</Steps>
254The polling interval is clamped between 1 and 30 seconds; the grant times out after 5 minutes; the token lifetime you return is clamped between 5 minutes and 30 days (24 hours before 1.17377.1).
265255 
256When `inferenceGatewayBaseUrl` shares the `bootstrapUrl` origin, so the same sign-in also serves inference, you may also return a `refresh_token` (optionally with `refresh_token_expires_in` in seconds): as the access token nears expiry during use, Claude Desktop 1.34493.0 and later renews it with an RFC 6749 `grant_type=refresh_token` POST to your `token_endpoint` rather than interrupting the user. The configuration fetch at launch still asks the user to sign in if the access token itself has already expired. Answer `400` with `{"error":"invalid_grant"}` to revoke the refresh token and require a fresh sign-in.
257 
258**3. Serve the configuration endpoint**
259 
260On `GET <bootstrapUrl>` with a valid bearer, look up the user from the token claims and return their configuration (see [the HTTP contract](#the-http-contract)).
261 
266262### Request headers (no per-user sign-in)
267263 
268264Requires Claude Desktop 1.32885.1 or later. Set `bootstrapHeaders` to a JSON object of headers to send on every bootstrap fetch, or `bootstrapHeadersHelper` to the absolute path of an executable that prints such an object on stdout (run with no arguments; its output is cached for a few minutes and merged over the static headers, the helper winning on a conflict). When either key is set and `bootstrapOidc` is not, the app treats the headers as sufficient authentication and fetches the configuration without prompting the user to sign in. If your server answers `401` or `403`, the app discards the cached helper output so the next fetch (the next background check, or a relaunch) re-runs the helper. At launch the app also shows a sign-in prompt; that sign-in succeeds only if your server implements the [device-code grant](#bootstrap-server-as-authorization-server-device-code), so a headers-only server should return `401`/`403` only for a genuinely unusable credential. A `401`/`403` on a background check keeps the running configuration and retries at the next check without prompting. A signed-in user's bearer token replaces any `Authorization` header you configured. Both keys are read from device management or the local configuration file only, never from the bootstrap response, and header values are masked in the diagnostic report. [Origin pinning](#origin-pinning) applies in this mode exactly as in device-code mode. Use this instead of embedding `user:password@` in `bootstrapUrl`, which the app refuses.
from line 302
306302| `401`, `403` | Discard the cached token and prompt the user to sign in again. A `401` on a background refresh keeps the running configuration. When the same sign-in also serves inference, the app treats it as an ended session and asks the user to sign in again (1.34493.0 and later); otherwise it retries at the next check without prompting. Return `401` when the token is missing, expired, or the wrong audience; return `403` when the token is valid but the caller is not entitled. |
307303| Other non-2xx, or `3xx` | Fetch error. Falls back to the last good response from this session if one exists; otherwise the app stays in the degraded sign-in state. |
308304 
309<Warning>
310 A `200` that is not a JSON object (an empty body, an HTML page from a captive portal or load balancer, or a JSON array) is a parse error. Make sure intermediate proxies do not rewrite the response.
311</Warning>
305> [!WARNING]
306>
307> A `200` that is not a JSON object (an empty body, an HTML page from a captive portal or load balancer, or a JSON array) is a parse error. Make sure intermediate proxies do not rewrite the response.
312308 
313309### Response schema
314310 
from line 319
323319 
324320The response can supply any key in that schema, including inference credentials, model allowlists, MCP servers, the egress allowlist, telemetry endpoints, and the organization banner.
325321 
326<Note>
327 Organization plugins and skills can be delivered over the network by returning `allowedPluginMarketplaces` in the bootstrap response (see [Plugin marketplaces](/docs/third-party/claude-desktop/extensions#plugin-marketplaces-admin)), or through the filesystem `org-plugins/` directory described in [Connectors and extensions](/docs/third-party/claude-desktop/extensions).
328</Note>
322> [!NOTE]
323>
324> Organization plugins and skills can be delivered over the network by returning `allowedPluginMarketplaces` in the bootstrap response (see [Plugin marketplaces](/docs/third-party/claude-desktop/extensions#plugin-marketplaces-admin)), or through the filesystem `org-plugins/` directory described in [Connectors and extensions](/docs/third-party/claude-desktop/extensions).
329325 
330326A small set of keys are **structurally excluded** and ignored if returned:
331327 
from line 357
361357| `$schemaVersion` | `integer` | Wire-format marker: `2` for the nested format (bootstrap-config-v2, what the app's own JSON export writes), `1` for the flat format (bootstrap-config-v1). Optional: the client infers the format from the document shape; set it to state the format explicitly. |
362358| `expiresAt` | `number` | Unix epoch (seconds or milliseconds) after which the client should re-fetch this document. Optional; when absent the client uses its default refresh interval. |
363359 
364<AccordionGroup>
365 <Accordion title="$schemaVersion details">
366 Omitted → the client infers the version from the document shape (any cluster key present → 2, otherwise 1).
367 </Accordion>
360> **\$schemaVersion details**
361>
362> Omitted → the client infers the version from the document shape (any cluster key present → 2, otherwise 1).
368363 
369 <Accordion title="expiresAt details">
370 Omitted → cache for 1 hour. A number ≥ 10¹² is read as Unix epoch **milliseconds**; below that, **seconds**.
364> **expiresAt details**
365>
366> Omitted → cache for 1 hour. A number ≥ 10¹² is read as Unix epoch **milliseconds**; below that, **seconds**.
367>
368> A failed re-fetch keeps the last good response from the current session and retries; the app only enters the degraded state when there has never been a usable response this session.
371369 
372 A failed re-fetch keeps the last good response from the current session and retries; the app only enters the degraded state when there has never been a usable response this session.
373 </Accordion>
374</AccordionGroup>
375 
376370### Origin pinning
377371 
378372When no `bootstrapOidc` is set (device-code or request-headers mode), the response is fenced: `inferenceGatewayBaseUrl`, `inferenceVertexBaseUrl`, `inferenceBedrockBaseUrl`, and `inferenceFoundryBaseUrl` must share the `bootstrapUrl` origin or the field is dropped. A compromised configuration response cannot redirect inference to an attacker-controlled host because the only host it can name is your bootstrap server's own origin.
from line 377
383377 
384378| Setting | Type | Availability | Default | Description |
385379| - | - | - | - | - |
386| <span id="bootstrapenabled" />Use bootstrap config<br />`bootstrapEnabled` | `boolean` | MDM only<br />Added in 1.10628.0 | `true` | Fetch and apply the URL above at launch. Turn off to keep the URL saved but skip the fetch. Defaults to `true`. |
387| <span id="bootstrapurl" />Bootstrap config URL<br />`bootstrapUrl` | `string` | MDM only<br />Added in 1.10628.0 | — | HTTPS endpoint that returns a per-user JSON config overlay. Values from the response override local settings and become read-only. |
388| <span id="bootstrapoidc" />Bootstrap OIDC parameters<br />`bootstrapOidc` | `object` | MDM only<br />Added in 1.10628.0 | — | When set, the bootstrap request sends a Bearer token from a browser sign-in (authorization-code-with-PKCE). |
389| <span id="bootstrapheaders" />Bootstrap request headers<br />`bootstrapHeaders` | `object` | MDM only<br />Added in 1.32885.1 | — | HTTP headers sent on every bootstrap config fetch. Use this instead of embedding user:pass@ in the URL. |
390| <span id="bootstrapheadershelper" />Bootstrap headers helper script<br />`bootstrapHeadersHelper` | `string` | MDM only<br />Added in 1.32885.1 | — | Absolute path to an executable that prints a JSON object of bootstrap request headers. Merged over the static headers; the helper wins. |
391| <span id="trustbootstrapdelivery" />Trust bootstrap-delivered settings<br />`trustBootstrapDelivery` | `boolean` | MDM only<br />Added in 1.26832.0 | `false` | Skip the per-user consent prompt for sign-in targets, inference endpoints, helper scripts, and connectors the bootstrap server delivers. Defaults to `false`. |
380| Use bootstrap config `bootstrapEnabled` | `boolean` | MDM only Added in 1.10628.0 | `true` | Fetch and apply the URL above at launch. Turn off to keep the URL saved but skip the fetch. Defaults to `true`. |
381| Bootstrap config URL `bootstrapUrl` | `string` | MDM only Added in 1.10628.0 | — | HTTPS endpoint that returns a per-user JSON config overlay. Values from the response override local settings and become read-only. |
382| Bootstrap OIDC parameters `bootstrapOidc` | `object` | MDM only Added in 1.10628.0 | — | When set, the bootstrap request sends a Bearer token from a browser sign-in (authorization-code-with-PKCE). |
383| Bootstrap request headers `bootstrapHeaders` | `object` | MDM only Added in 1.32885.1 | — | HTTP headers sent on every bootstrap config fetch. Use this instead of embedding user:pass@ in the URL. |
384| Bootstrap headers helper script `bootstrapHeadersHelper` | `string` | MDM only Added in 1.32885.1 | — | Absolute path to an executable that prints a JSON object of bootstrap request headers. Merged over the static headers; the helper wins. |
385| Trust bootstrap-delivered settings `trustBootstrapDelivery` | `boolean` | MDM only Added in 1.26832.0 | `false` | Skip the per-user consent prompt for sign-in targets, inference endpoints, helper scripts, and connectors the bootstrap server delivers. Defaults to `false`. |
392386 
393<AccordionGroup>
394 <Accordion title="bootstrapOidc details">
395 Set this to use a separate identity provider (Microsoft Entra ID, Okta, Ping, or any compliant OIDC provider) for the bootstrap sign-in. The app runs an authorization-code-with-PKCE flow in the system browser. Omit to use device-code mode against the bootstrap server's own origin.
387> **bootstrapOidc details**
388>
389> Set this to use a separate identity provider (Microsoft Entra ID, Okta, Ping, or any compliant OIDC provider) for the bootstrap sign-in. The app runs an authorization-code-with-PKCE flow in the system browser. Omit to use device-code mode against the bootstrap server's own origin.
390>
391> This is an **object-typed key** — in an MDM profile it is a single JSON-string value, not separate keys with dotted names like `bootstrapOidc.clientId`. Writing the sub-fields as separate registry values causes the app to silently fall through to device-code mode.
392>
393> | Field | Type | Default | Description |
394> | - | - | - | - |
395> | `clientId` | `string` | — | OAuth client ID of the desktop app registration at your identity provider (public client, PKCE). |
396> | `issuer` | `string` | — | HTTPS issuer with OIDC discovery. Set this, or set the authorization and token URLs instead. |
397> | `authorizationUrl` | `string` | — | HTTPS authorization endpoint. Used with the token URL when no issuer is set. |
398> | `tokenUrl` | `string` | — | HTTPS token endpoint. Used with the authorization URL when no issuer is set. |
399> | `scopes` | `string` | — | Space-separated; the token’s audience must match what your bootstrap server validates. |
400> | `redirectPort` | `integer` | — | Fixed loopback port for the sign-in redirect. Leave unset to use a free port each time. |
401> | `redirectHost` | `enum` | — | Use localhost only if your IdP’s registered redirect URI specifies it. One of: `127.0.0.1`, `localhost`. |
402> | `additionalRedirectReferrerHosts` | `string` | — | Space-separated hostnames also accepted as the referrer of the sign-in callback. Only needed when the IdP completes sign-in from a different host. |
396403 
397 This is an **object-typed key** — in an MDM profile it is a single JSON-string value, not separate keys with dotted names like `bootstrapOidc.clientId`. Writing the sub-fields as separate registry values causes the app to silently fall through to device-code mode.
404> **bootstrapHeaders details**
405>
406> Static headers sent on every request to the bootstrap config URL — for a service-account credential (`Authorization: Basic …`, an API key header) or a routing/tenant header. When either this or the headers helper script is set and no separate `bootstrapOidc` provider is configured, the app treats the headers as sufficient auth and does not require a per-user sign-in for the bootstrap fetch. These headers (and the helper script's below) also accompany requests to a plugin marketplace this server hosts on its own origin (`allowedPluginMarketplaces` with `credentialKind: "inferenceCredential"`). Header values are masked in diagnostics and telemetry. For a rotating token, use the headers helper script instead.
398407 
399 | Field | Type | Default | Description |
400 | - | - | - | - |
401 | `clientId` | `string` | — | OAuth client ID of the desktop app registration at your identity provider (public client, PKCE). |
402 | `issuer` | `string` | — | HTTPS issuer with OIDC discovery. Set this, or set the authorization and token URLs instead. |
403 | `authorizationUrl` | `string` | — | HTTPS authorization endpoint. Used with the token URL when no issuer is set. |
404 | `tokenUrl` | `string` | — | HTTPS token endpoint. Used with the authorization URL when no issuer is set. |
405 | `scopes` | `string` | — | Space-separated; the token’s audience must match what your bootstrap server validates. |
406 | `redirectPort` | `integer` | — | Fixed loopback port for the sign-in redirect. Leave unset to use a free port each time. |
407 | `redirectHost` | `enum` | — | Use localhost only if your IdP’s registered redirect URI specifies it. One of: `127.0.0.1`, `localhost`. |
408 | `additionalRedirectReferrerHosts` | `string` | — | Space-separated hostnames also accepted as the referrer of the sign-in callback. Only needed when the IdP completes sign-in from a different host. |
409 </Accordion>
410 
411 <Accordion title="bootstrapHeaders details">
412 Static headers sent on every request to the bootstrap config URL — for a service-account credential (`Authorization: Basic …`, an API key header) or a routing/tenant header. When either this or the headers helper script is set and no separate `bootstrapOidc` provider is configured, the app treats the headers as sufficient auth and does not require a per-user sign-in for the bootstrap fetch. These headers (and the helper script's below) also accompany requests to a plugin marketplace this server hosts on its own origin (`allowedPluginMarketplaces` with `credentialKind: "inferenceCredential"`). Header values are masked in diagnostics and telemetry. For a rotating token, use the headers helper script instead.
413 </Accordion>
414 
415 <Accordion title="bootstrapHeadersHelper details">
416 Absolute path to an executable that prints a single JSON object of HTTP headers on stdout, e.g. `{"Authorization": "Bearer …"}`. The app runs it (no arguments; output cached for a few minutes) before each bootstrap config fetch and merges the result over **Bootstrap request headers** (the helper wins on conflict). Use this instead of embedding `user:pass@` in the bootstrap URL, or when the bootstrap server needs a rotating token from a secrets manager. When either this or the static headers are set and no separate `bootstrapOidc` provider is configured, the app treats them as sufficient auth and does not require a per-user sign-in for the bootstrap fetch. If a per-user sign-in also runs (`bootstrapOidc` or the server’s own device-code flow), that Bearer token wins on `Authorization`.
417 </Accordion>
418</AccordionGroup>
408> **bootstrapHeadersHelper details**
409>
410> Absolute path to an executable that prints a single JSON object of HTTP headers on stdout, e.g. `{"Authorization": "Bearer …"}`. The app runs it (no arguments; output cached for a few minutes) before each bootstrap config fetch and merges the result over **Bootstrap request headers** (the helper wins on conflict). Use this instead of embedding `user:pass@` in the bootstrap URL, or when the bootstrap server needs a rotating token from a secrets manager. When either this or the static headers are set and no separate `bootstrapOidc` provider is configured, the app treats them as sufficient auth and does not require a per-user sign-in for the bootstrap fetch. If a per-user sign-in also runs (`bootstrapOidc` or the server’s own device-code flow), that Bearer token wins on `Authorization`.
419411 
420412No `inferenceProvider` is needed in the MDM profile when using bootstrap; the response supplies it.
421413 
Feedback