auth0-deploy-cli 8.41.0 → 8.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +53 -1
  2. package/lib/context/directory/handlers/actionModules.js +11 -12
  3. package/lib/context/directory/handlers/actions.js +11 -13
  4. package/lib/context/directory/handlers/databases.js +4 -4
  5. package/lib/context/directory/handlers/hooks.js +12 -1
  6. package/lib/context/directory/handlers/rules.js +12 -1
  7. package/lib/context/directory/index.js +7 -8
  8. package/lib/context/yaml/index.js +7 -8
  9. package/lib/tools/auth0/handlers/attackProtection.js +16 -5
  10. package/lib/tools/auth0/handlers/clientAuthCredentials.d.ts +2 -1
  11. package/lib/tools/auth0/handlers/clientAuthCredentials.js +7 -0
  12. package/lib/tools/auth0/handlers/clientAuthCredentialsPre.d.ts +2 -1
  13. package/lib/tools/auth0/handlers/clientAuthCredentialsPre.js +5 -0
  14. package/lib/tools/auth0/handlers/clientGrants.d.ts +1 -1
  15. package/lib/tools/auth0/handlers/clients.d.ts +46 -0
  16. package/lib/tools/auth0/handlers/clients.js +91 -1
  17. package/lib/tools/auth0/handlers/connections.d.ts +32 -6
  18. package/lib/tools/auth0/handlers/connections.js +39 -4
  19. package/lib/tools/auth0/handlers/databases.js +11 -2
  20. package/lib/tools/auth0/handlers/default.js +6 -6
  21. package/lib/tools/auth0/handlers/guardianFactorTemplates.js +13 -4
  22. package/lib/tools/auth0/handlers/guardianPhoneFactorMessageTypes.js +11 -9
  23. package/lib/tools/auth0/handlers/guardianPhoneFactorSelectedProvider.js +11 -9
  24. package/lib/tools/auth0/handlers/hooks.js +1 -1
  25. package/lib/tools/auth0/handlers/networkACLs.d.ts +18 -0
  26. package/lib/tools/auth0/handlers/networkACLs.js +9 -0
  27. package/lib/tools/auth0/handlers/organizations.d.ts +28 -0
  28. package/lib/tools/auth0/handlers/organizations.js +127 -2
  29. package/lib/tools/auth0/handlers/phoneTemplates.d.ts +4 -1
  30. package/lib/tools/auth0/handlers/phoneTemplates.js +67 -10
  31. package/lib/tools/auth0/handlers/roles.d.ts +4 -0
  32. package/lib/tools/auth0/handlers/roles.js +10 -0
  33. package/lib/tools/auth0/handlers/rules.js +19 -7
  34. package/lib/tools/auth0/handlers/tenant.d.ts +23 -0
  35. package/lib/tools/auth0/handlers/tenant.js +24 -0
  36. package/lib/tools/auth0/handlers/themes.d.ts +37 -1
  37. package/lib/tools/auth0/handlers/themes.js +64 -0
  38. package/lib/tools/auth0/index.js +9 -0
  39. package/lib/tools/utils.d.ts +1 -0
  40. package/lib/tools/utils.js +25 -2
  41. package/lib/types.d.ts +1 -0
  42. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [8.43.0] - 2026-08-12
11
+
12
+ ### Added
13
+
14
+ - Add org-to-app entitlement (EA) support for organizations. [#1454]
15
+ - Support full group metadata for Google Workspace directory sync (GA). [#1456]
16
+
17
+ ### Fixed
18
+
19
+ - Create phone templates on import instead of skipping when they have no ID. [#1457]
20
+ - Address path traversal vulnerability and false warnings in config file handlers. [#1449]
21
+ - Exclude org-scoped roles from tenant export by filtering `type='tenant'`. [#1453]
22
+ - Strip read-only field from roles to fix export/import round-trip. [#1445]
23
+
24
+ ## [8.42.0] - 2026-07-30
25
+
26
+ ### Added
27
+
28
+ - Add UL identifier input support for themes and tenant settings. [#1433]
29
+ - Add `token_vault_privileged_access` support for clients. [#1430]
30
+ - Add `auth0_managed` field support for network ACLs (Curated Blocklists - EA). [#1435]
31
+ - Add Cross App Access (XAA) resource app support for connections and clients. [#1431]
32
+ - Add `cross_app_access_requesting_app` support for connections (EA). [#1422]
33
+
34
+ ### Fixed
35
+
36
+ - Prevent dry-run crash on `clientAuthCredentials` handler. [#1438]
37
+ - Resolve spurious dry-run diffs for rules, themes, and hooks. [#1437]
38
+ - Strip unresolved placeholders on deploy instead of throwing. [#1436]
39
+ - Handle 403 entitlement errors for bot detection and captcha on export. [#1434]
40
+ - Warn and skip deprecated guardian phone provider on 403 during import. [#1429]
41
+ - Add `use_scope_descriptions_for_consent` to allowed tenant flags. [#1428]
42
+
10
43
  ## [8.41.0] - 2026-07-16
11
44
 
12
45
  ### Added
@@ -1876,8 +1909,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1876
1909
  [#1416]: https://github.com/auth0/auth0-deploy-cli/issues/1416
1877
1910
  [#1417]: https://github.com/auth0/auth0-deploy-cli/issues/1417
1878
1911
  [#1421]: https://github.com/auth0/auth0-deploy-cli/issues/1421
1912
+ [#1422]: https://github.com/auth0/auth0-deploy-cli/issues/1422
1879
1913
  [#1425]: https://github.com/auth0/auth0-deploy-cli/issues/1425
1880
- [Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.41.0...HEAD
1914
+ [#1428]: https://github.com/auth0/auth0-deploy-cli/issues/1428
1915
+ [#1429]: https://github.com/auth0/auth0-deploy-cli/issues/1429
1916
+ [#1430]: https://github.com/auth0/auth0-deploy-cli/issues/1430
1917
+ [#1431]: https://github.com/auth0/auth0-deploy-cli/issues/1431
1918
+ [#1433]: https://github.com/auth0/auth0-deploy-cli/issues/1433
1919
+ [#1434]: https://github.com/auth0/auth0-deploy-cli/issues/1434
1920
+ [#1435]: https://github.com/auth0/auth0-deploy-cli/issues/1435
1921
+ [#1436]: https://github.com/auth0/auth0-deploy-cli/issues/1436
1922
+ [#1437]: https://github.com/auth0/auth0-deploy-cli/issues/1437
1923
+ [#1438]: https://github.com/auth0/auth0-deploy-cli/issues/1438
1924
+ [#1445]: https://github.com/auth0/auth0-deploy-cli/issues/1445
1925
+ [#1449]: https://github.com/auth0/auth0-deploy-cli/issues/1449
1926
+ [#1453]: https://github.com/auth0/auth0-deploy-cli/issues/1453
1927
+ [#1454]: https://github.com/auth0/auth0-deploy-cli/issues/1454
1928
+ [#1456]: https://github.com/auth0/auth0-deploy-cli/issues/1456
1929
+ [#1457]: https://github.com/auth0/auth0-deploy-cli/issues/1457
1930
+ [Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.43.0...HEAD
1931
+ [8.43.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.42.0...v8.43.0
1932
+ [8.42.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.41.0...v8.42.0
1881
1933
  [8.41.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.40.0...v8.41.0
1882
1934
  [8.40.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.39.0...v8.40.0
1883
1935
  [8.39.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.38.0...v8.39.0
@@ -20,20 +20,19 @@ function parse(context) {
20
20
  disableKeywordReplacement: context.disableKeywordReplacement,
21
21
  }),
22
22
  };
23
- const moduleFolder = path_1.default.join(tools_1.constants.ACTION_MODULES_DIRECTORY, `${module.name}`);
24
23
  if (module.code) {
25
- // The `module.code` can be a file path. It needs to be loaded.
26
- // It can be a relative path, so we need to handle both cases.
27
- const unixPath = module.code.replace(/[\\/]+/g, '/').replace(/^([a-zA-Z]+:|\.\/)/, '');
28
- if (fs_extra_1.default.existsSync(unixPath)) {
29
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
30
- `Please update your configuration to use paths relative to the config directory. ` +
31
- `Current absolute path used: ["${module.code}"]`);
32
- module.code = context.loadFile(unixPath, moduleFolder);
33
- }
34
- else {
35
- module.code = context.loadFile(path_1.default.join(context.filePath, module.code), moduleFolder);
24
+ const normalizedCode = module.code.replace(/\\/g, '/');
25
+ const configRoot = path_1.default.resolve(context.filePath);
26
+ const resolvedPath = path_1.default.resolve(context.filePath, normalizedCode);
27
+ if (!resolvedPath.startsWith(configRoot + path_1.default.sep)) {
28
+ logger_1.default.warn(`Path "${module.code}" resolves to "${resolvedPath}" which is outside the config directory "${configRoot}". ` +
29
+ `This will be blocked as an error in the next major release. ` +
30
+ `Move the file inside your config directory.`);
36
31
  }
32
+ module.code = (0, tools_1.loadFileAndReplaceKeywords)(resolvedPath, {
33
+ mappings: context.mappings,
34
+ disableKeywordReplacement: context.disableKeywordReplacement,
35
+ });
37
36
  }
38
37
  return module;
39
38
  });
@@ -22,21 +22,19 @@ function parse(context) {
22
22
  disableKeywordReplacement: context.disableKeywordReplacement,
23
23
  }),
24
24
  };
25
- const actionFolder = path_1.default.join(tools_1.constants.ACTIONS_DIRECTORY, `${action.name}`);
26
25
  if (action.code) {
27
- // Convert `action.code` path to Unix-style path by replacing backslashes and multiple slashes with a single forward slash, and remove leading drive letters or './'.
28
- const unixPath = action.code.replace(/[\\/]+/g, '/').replace(/^([a-zA-Z]+:|\.\/)/, '');
29
- if (fs_extra_1.default.existsSync(unixPath)) {
30
- // If the Unix-style path exists, load the file from that path
31
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
32
- `Please update your configuration to use paths relative to the config directory. ` +
33
- `Current absolute path used: ["${action.code}"]`);
34
- action.code = context.loadFile(unixPath, actionFolder);
35
- }
36
- else {
37
- // Otherwise, load the file from the context's file path
38
- action.code = context.loadFile(path_1.default.join(context.filePath, action.code), actionFolder);
26
+ const normalizedCode = action.code.replace(/\\/g, '/');
27
+ const configRoot = path_1.default.resolve(context.filePath);
28
+ const resolvedPath = path_1.default.resolve(context.filePath, normalizedCode);
29
+ if (!resolvedPath.startsWith(configRoot + path_1.default.sep)) {
30
+ logger_1.default.warn(`Path "${action.code}" resolves to "${resolvedPath}" which is outside the config directory "${configRoot}". ` +
31
+ `This will be blocked as an error in the next major release. ` +
32
+ `Move the file inside your config directory.`);
39
33
  }
34
+ action.code = (0, tools_1.loadFileAndReplaceKeywords)(resolvedPath, {
35
+ mappings: context.mappings,
36
+ disableKeywordReplacement: context.disableKeywordReplacement,
37
+ });
40
38
  }
41
39
  return action;
42
40
  });
@@ -41,11 +41,11 @@ function getDatabase(folder, configRoot, mappingOpts) {
41
41
  }
42
42
  else {
43
43
  const resolvedBase = path_1.default.resolve(configRoot);
44
- const toLoad = path_1.default.resolve(folder, script);
44
+ const toLoad = path_1.default.resolve(folder, script.replace(/\\/g, '/'));
45
45
  if (!toLoad.startsWith(resolvedBase + path_1.default.sep)) {
46
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
47
- `Please update your configuration to use paths relative to the config directory. ` +
48
- `Current absolute path used: ["${script}"]`);
46
+ logger_1.default.warn(`Path "${script}" resolves to "${toLoad}" which is outside the config directory "${resolvedBase}". ` +
47
+ `This will be blocked as an error in the next major release. ` +
48
+ `Move the file inside your config directory.`);
49
49
  }
50
50
  database.options.customScripts[name] = (0, tools_1.loadFileAndReplaceKeywords)(toLoad, mappingOpts);
51
51
  }
@@ -21,7 +21,18 @@ function parse(context) {
21
21
  }),
22
22
  };
23
23
  if (hook.script) {
24
- hook.script = context.loadFile(hook.script, tools_1.constants.HOOKS_DIRECTORY);
24
+ const normalizedScript = hook.script.replace(/\\/g, '/');
25
+ const configRoot = path_1.default.resolve(context.filePath);
26
+ const resolvedPath = path_1.default.resolve(context.filePath, tools_1.constants.HOOKS_DIRECTORY, normalizedScript);
27
+ if (!resolvedPath.startsWith(configRoot + path_1.default.sep)) {
28
+ logger_1.default.warn(`Path "${hook.script}" resolves to "${resolvedPath}" which is outside the config directory "${configRoot}". ` +
29
+ `This will be blocked as an error in the next major release. ` +
30
+ `Move the file inside your config directory.`);
31
+ }
32
+ hook.script = (0, tools_1.loadFileAndReplaceKeywords)(resolvedPath, {
33
+ mappings: context.mappings,
34
+ disableKeywordReplacement: context.disableKeywordReplacement,
35
+ });
25
36
  }
26
37
  hook.name = hook.name.toLowerCase().replace(/\s/g, '-');
27
38
  return hook;
@@ -21,7 +21,18 @@ function parse(context) {
21
21
  }),
22
22
  };
23
23
  if (rule.script) {
24
- rule.script = context.loadFile(rule.script, tools_1.constants.RULES_DIRECTORY);
24
+ const normalizedScript = rule.script.replace(/\\/g, '/');
25
+ const configRoot = path_1.default.resolve(context.filePath);
26
+ const resolvedPath = path_1.default.resolve(context.filePath, tools_1.constants.RULES_DIRECTORY, normalizedScript);
27
+ if (!resolvedPath.startsWith(configRoot + path_1.default.sep)) {
28
+ logger_1.default.warn(`Path "${rule.script}" resolves to "${resolvedPath}" which is outside the config directory "${configRoot}". ` +
29
+ `This will be blocked as an error in the next major release. ` +
30
+ `Move the file inside your config directory.`);
31
+ }
32
+ rule.script = (0, tools_1.loadFileAndReplaceKeywords)(resolvedPath, {
33
+ mappings: context.mappings,
34
+ disableKeywordReplacement: context.disableKeywordReplacement,
35
+ });
25
36
  }
26
37
  return rule;
27
38
  });
@@ -68,14 +68,13 @@ class DirectoryContext {
68
68
  };
69
69
  }
70
70
  loadFile(f, folder) {
71
- const basePath = path.join(this.filePath, folder);
72
- let toLoad = path.join(basePath, f);
73
- if (!(0, utils_1.isFile)(toLoad)) {
74
- // try load not relative to yaml file
75
- toLoad = f;
76
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
77
- `Please update your configuration to use paths relative to the config directory. ` +
78
- `Current absolute path used: ["${f}"]`);
71
+ const configRoot = path.resolve(this.filePath);
72
+ const basePath = path.resolve(this.filePath, folder);
73
+ const toLoad = path.resolve(basePath, f.replace(/\\/g, '/'));
74
+ if (!toLoad.startsWith(configRoot + path.sep)) {
75
+ logger_1.default.warn(`Path "${f}" resolves to "${toLoad}" which is outside the config directory "${configRoot}". ` +
76
+ `This will be blocked as an error in the next major release. ` +
77
+ `Move the file inside your config directory.`);
79
78
  }
80
79
  return (0, tools_1.loadFileAndReplaceKeywords)(toLoad, {
81
80
  mappings: this.mappings,
@@ -43,15 +43,14 @@ class YAMLContext {
43
43
  })();
44
44
  }
45
45
  loadFile(f) {
46
- let toLoad = path_1.default.join(this.basePath, f);
47
- if (!(0, utils_1.isFile)(toLoad)) {
48
- // try load not relative to yaml file
49
- toLoad = f;
50
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
51
- `Please update your configuration to use paths relative to the config directory. ` +
52
- `Current absolute path used: ["${f}"]`);
46
+ const configRoot = path_1.default.resolve(this.basePath);
47
+ const toLoad = path_1.default.resolve(this.basePath, f.replace(/\\/g, '/'));
48
+ if (!toLoad.startsWith(configRoot + path_1.default.sep)) {
49
+ logger_1.default.warn(`Path "${f}" resolves to "${toLoad}" which is outside the config directory "${configRoot}". ` +
50
+ `This will be blocked as an error in the next major release. ` +
51
+ `Move the file inside your config directory.`);
53
52
  }
54
- return (0, tools_1.loadFileAndReplaceKeywords)(path_1.default.resolve(toLoad), {
53
+ return (0, tools_1.loadFileAndReplaceKeywords)(toLoad, {
55
54
  mappings: this.mappings,
56
55
  disableKeywordReplacement: this.disableKeywordReplacement,
57
56
  });
@@ -243,14 +243,25 @@ class AttackProtectionHandler extends default_1.default {
243
243
  let botDetection = null;
244
244
  let captcha = null;
245
245
  try {
246
- [botDetection, captcha] = await Promise.all([
247
- this.client.attackProtection.botDetection.get(),
248
- this.client.attackProtection.captcha.get(),
249
- ]);
246
+ botDetection = await this.client.attackProtection.botDetection.get();
250
247
  }
251
248
  catch (err) {
252
249
  if (err.statusCode === 403) {
253
- logger_1.default.warn('Bot Detection API are not enabled for this tenant. Please verify `scope` or contact Auth0 support to enable this feature.');
250
+ logger_1.default.warn("Bot detection is not available on this tenant's current plan. Skipping bot detection settings.");
251
+ }
252
+ else {
253
+ throw err;
254
+ }
255
+ }
256
+ try {
257
+ captcha = await this.client.attackProtection.captcha.get();
258
+ }
259
+ catch (err) {
260
+ if (err.statusCode === 403) {
261
+ logger_1.default.warn("Captcha is not available on this tenant's current plan. Skipping captcha settings.");
262
+ }
263
+ else {
264
+ throw err;
254
265
  }
255
266
  }
256
267
  const attackProtection = {
@@ -1,4 +1,4 @@
1
- import { Assets, Auth0APIClient } from '../../../types';
1
+ import { Assets, Auth0APIClient, CalculatedChanges } from '../../../types';
2
2
  import { ConfigFunction } from '../../../configFactory';
3
3
  export declare const schema: {
4
4
  type: string;
@@ -20,6 +20,7 @@ export default class ClientAuthCredentialsHandler {
20
20
  [x: string]: null;
21
21
  }>;
22
22
  validate(): Promise<null>;
23
+ dryRunChanges(_assets: Assets): Promise<CalculatedChanges>;
23
24
  processChanges(assets: Assets): Promise<void>;
24
25
  private inferCredentialType;
25
26
  private inferMethodFromType;
@@ -39,6 +39,13 @@ class ClientAuthCredentialsHandler {
39
39
  async validate() {
40
40
  return null;
41
41
  }
42
+ // Credentials are per-client sub-resources with no top-level asset list, so they are not
43
+ // modeled in the dry-run diff. Return empty changes so the dry-run loop (which calls
44
+ // dryRunChanges on every handler) does not crash. Credential changes are still applied
45
+ // during a real import via processChanges.
46
+ async dryRunChanges(_assets) {
47
+ return { del: [], create: [], conflicts: [], update: [] };
48
+ }
42
49
  async processChanges(assets) {
43
50
  const { clients } = assets;
44
51
  if (!clients)
@@ -1,4 +1,4 @@
1
- import { Assets, Auth0APIClient } from '../../../types';
1
+ import { Assets, Auth0APIClient, CalculatedChanges } from '../../../types';
2
2
  import { ConfigFunction } from '../../../configFactory';
3
3
  export declare const schema: {
4
4
  type: string;
@@ -33,5 +33,6 @@ export default class ClientAuthCredentialsPreHandler {
33
33
  [x: string]: null;
34
34
  }>;
35
35
  validate(): Promise<null>;
36
+ dryRunChanges(_assets: Assets): Promise<CalculatedChanges>;
36
37
  processChanges(assets: Assets): Promise<void>;
37
38
  }
@@ -48,6 +48,11 @@ class ClientAuthCredentialsPreHandler {
48
48
  async validate() {
49
49
  return null;
50
50
  }
51
+ // Deploy-only pre-pass handler with no dry-run representation. Return empty changes so the
52
+ // dry-run loop (which calls dryRunChanges on every registered handler) does not crash.
53
+ async dryRunChanges(_assets) {
54
+ return { del: [], create: [], conflicts: [], update: [] };
55
+ }
51
56
  async processChanges(assets) {
52
57
  const { clients } = assets;
53
58
  if (!clients)
@@ -22,7 +22,7 @@ export declare const schema: {
22
22
  };
23
23
  subject_type: {
24
24
  type: string;
25
- enum: ("client" | "user")[];
25
+ enum: ("client" | "user" | "anonymous_user")[];
26
26
  description: string;
27
27
  };
28
28
  authorization_details_types: {
@@ -193,6 +193,18 @@ export declare const schema: {
193
193
  };
194
194
  additionalProperties: boolean;
195
195
  };
196
+ identity_assertion_authorization_grant: {
197
+ type: string;
198
+ description: string;
199
+ properties: {
200
+ active: {
201
+ type: string;
202
+ description: string;
203
+ };
204
+ };
205
+ required: string[];
206
+ additionalProperties: boolean;
207
+ };
196
208
  app_type: {
197
209
  type: string;
198
210
  description: string;
@@ -328,6 +340,40 @@ export declare const schema: {
328
340
  };
329
341
  };
330
342
  };
343
+ token_vault_privileged_access: {
344
+ type: string[];
345
+ description: string;
346
+ properties: {
347
+ ip_allowlist: {
348
+ type: string;
349
+ description: string;
350
+ items: {
351
+ type: string;
352
+ };
353
+ };
354
+ grants: {
355
+ type: string;
356
+ description: string;
357
+ items: {
358
+ type: string;
359
+ properties: {
360
+ connection: {
361
+ type: string;
362
+ description: string;
363
+ };
364
+ scopes: {
365
+ type: string;
366
+ description: string;
367
+ items: {
368
+ type: string;
369
+ };
370
+ };
371
+ };
372
+ required: string[];
373
+ };
374
+ };
375
+ };
376
+ };
331
377
  third_party_security_mode: {
332
378
  type: string;
333
379
  enum: string[];
@@ -66,6 +66,40 @@ const myOrganizationConfigurationSchema = {
66
66
  },
67
67
  required: ['allowed_strategies', 'connection_deletion_behavior'],
68
68
  };
69
+ const tokenVaultPrivilegedAccessSchema = {
70
+ type: ['object', 'null'],
71
+ description: 'Settings for Token Vault Privileged Access, hardening a privileged client by restricting the caller IPs, connections, and scopes it may use at runtime. Early Access, gated by the token_vault_subject_type_jwt_ea_rollout feature flag. Export-only: this object is exported for visibility but is not deployed by the Deploy CLI (it is stripped from create/update payloads because the required credentials are tenant-specific ids). Manage it directly on the tenant.',
72
+ properties: {
73
+ ip_allowlist: {
74
+ type: 'array',
75
+ description: 'IPv4/IPv6 addresses or CIDR ranges permitted to call token exchange on behalf of this privileged client. When the EA flag is on, this is required (non-empty) on create if token_vault_privileged_access is being set.',
76
+ items: {
77
+ type: 'string',
78
+ },
79
+ },
80
+ grants: {
81
+ type: 'array',
82
+ description: 'Connection/scope pin objects restricting which federated connections and OAuth scopes the privileged client may use at runtime. Maximum 5 connections; maximum 20 scopes in total across all connections.',
83
+ items: {
84
+ type: 'object',
85
+ properties: {
86
+ connection: {
87
+ type: 'string',
88
+ description: 'The connection name (e.g. google-oauth2). Validated at runtime; the connection need not exist at configuration time.',
89
+ },
90
+ scopes: {
91
+ type: 'array',
92
+ description: 'The OAuth scopes permitted for that connection.',
93
+ items: {
94
+ type: 'string',
95
+ },
96
+ },
97
+ },
98
+ required: ['connection', 'scopes'],
99
+ },
100
+ },
101
+ },
102
+ };
69
103
  exports.schema = {
70
104
  type: 'array',
71
105
  items: {
@@ -221,6 +255,18 @@ exports.schema = {
221
255
  },
222
256
  additionalProperties: true,
223
257
  },
258
+ identity_assertion_authorization_grant: {
259
+ type: 'object',
260
+ description: 'Settings for Cross App Access (ID-JAG) token exchange. Early Access. Enables the client to request identity assertion authorization grants.',
261
+ properties: {
262
+ active: {
263
+ type: 'boolean',
264
+ description: 'Indicates whether the client can request an identity assertion authorization grant (ID-JAG) via token exchange.',
265
+ },
266
+ },
267
+ required: ['active'],
268
+ additionalProperties: false,
269
+ },
224
270
  app_type: {
225
271
  type: 'string',
226
272
  description: 'The type of application this client represents',
@@ -332,6 +378,7 @@ exports.schema = {
332
378
  },
333
379
  },
334
380
  },
381
+ token_vault_privileged_access: tokenVaultPrivilegedAccessSchema,
335
382
  third_party_security_mode: {
336
383
  type: 'string',
337
384
  enum: ['strict', 'permissive'],
@@ -460,6 +507,40 @@ const createClientSanitizer = (clients) => {
460
507
  },
461
508
  };
462
509
  };
510
+ /**
511
+ * On export, remove `credentials` from `token_vault_privileged_access`.
512
+ *
513
+ * Auth0 returns these as tenant-specific credential references (`{ id }`) — never
514
+ * names or key material — so they are not portable across tenants and must never be
515
+ * written to disk. `ip_allowlist` and `grants` are kept for visibility. Mutates and
516
+ * returns the same client.
517
+ */
518
+ const stripTokenVaultCredentialsOnExport = (client) => {
519
+ const tvpa = client
520
+ .token_vault_privileged_access;
521
+ if (tvpa && 'credentials' in tvpa) {
522
+ delete tvpa.credentials;
523
+ }
524
+ return client;
525
+ };
526
+ /**
527
+ * On write (create/update), remove the entire `token_vault_privileged_access` object.
528
+ *
529
+ * The Management API requires `credentials` whenever `token_vault_privileged_access`
530
+ * is present in the payload, but those credentials are tenant-specific ids that the
531
+ * Deploy CLI intentionally never persists (see stripTokenVaultCredentialsOnExport).
532
+ * Sending the object without `credentials` fails validation ("Missing required
533
+ * property: credentials"); sending it with exported ids would re-send stale ids on a
534
+ * cross-tenant deploy. The Deploy CLI therefore does not manage this field — it is
535
+ * export-only. Manage `token_vault_privileged_access` directly on the tenant.
536
+ * Mutates and returns the same client.
537
+ */
538
+ const stripTokenVaultPrivilegedAccessOnWrite = (client) => {
539
+ if ('token_vault_privileged_access' in client) {
540
+ delete client.token_vault_privileged_access;
541
+ }
542
+ return client;
543
+ };
463
544
  class ClientHandler extends default_1.default {
464
545
  constructor(config) {
465
546
  super({
@@ -577,6 +658,10 @@ class ClientHandler extends default_1.default {
577
658
  delete item.token_endpoint_auth_method;
578
659
  }
579
660
  delete item.client_authentication_methods;
661
+ // token_vault_privileged_access requires tenant-specific credential ids that
662
+ // the Deploy CLI never persists. Strip the whole object on write so we neither
663
+ // re-send stale ids nor fail validation for the missing credentials property.
664
+ stripTokenVaultPrivilegedAccessOnWrite(item);
580
665
  return item;
581
666
  });
582
667
  };
@@ -598,7 +683,12 @@ class ClientHandler extends default_1.default {
598
683
  is_global: false,
599
684
  ...((0, utils_1.shouldExcludeThirdPartyClients)(this.config) && { is_first_party: true }),
600
685
  });
601
- const sanitized = createClientSanitizer(clients).sanitizeCrossOriginAuth(false).get();
686
+ const sanitized = createClientSanitizer(clients)
687
+ .sanitizeCrossOriginAuth(false)
688
+ .get()
689
+ // token_vault_privileged_access.credentials are returned as tenant-specific
690
+ // ids — strip them so they are never exported to disk.
691
+ .map(stripTokenVaultCredentialsOnExport);
602
692
  // Enrich credential stubs with name and credential_type for export.
603
693
  // Auth0 does not return pem on read — it is never exported.
604
694
  await Promise.all(sanitized.map(async (client) => {
@@ -103,6 +103,27 @@ export declare const schema: {
103
103
  required: string[];
104
104
  additionalProperties: boolean;
105
105
  };
106
+ cross_app_access_requesting_app: {
107
+ type: string;
108
+ properties: {
109
+ active: {
110
+ type: string;
111
+ };
112
+ };
113
+ required: string[];
114
+ additionalProperties: boolean;
115
+ };
116
+ cross_app_access_resource_app: {
117
+ type: string;
118
+ properties: {
119
+ status: {
120
+ type: string;
121
+ enum: string[];
122
+ };
123
+ };
124
+ required: string[];
125
+ additionalProperties: boolean;
126
+ };
106
127
  directory_provisioning_configuration: {
107
128
  type: string;
108
129
  properties: {
@@ -138,6 +159,15 @@ export declare const schema: {
138
159
  id: {
139
160
  type: string;
140
161
  };
162
+ name: {
163
+ type: string;
164
+ };
165
+ email: {
166
+ type: string;
167
+ };
168
+ direct_members_count: {
169
+ type: string;
170
+ };
141
171
  };
142
172
  required: string[];
143
173
  };
@@ -152,9 +182,7 @@ type DirectoryProvisioningConfig = Management.DirectoryProvisioning;
152
182
  export type Connection = Management.ConnectionForList & {
153
183
  enabled_clients?: string[];
154
184
  directory_provisioning_configuration?: Pick<DirectoryProvisioningConfig, 'mapping' | 'synchronize_automatically' | 'synchronize_groups'> & {
155
- synchronized_groups?: Array<{
156
- id: string;
157
- }>;
185
+ synchronized_groups?: Management.SynchronizedGroupPayload[];
158
186
  };
159
187
  };
160
188
  export declare const addExcludedConnectionPropertiesToChanges: ({ proposedChanges, existingConnections, config, }: {
@@ -230,9 +258,7 @@ export default class ConnectionsHandler extends DefaultAPIHandler {
230
258
  /**
231
259
  * Retrieves all synchronized groups for a connection using checkpoint pagination.
232
260
  */
233
- getConnectionSynchronizedGroups(connectionId: string): Promise<Array<{
234
- id: string;
235
- }> | null>;
261
+ getConnectionSynchronizedGroups(connectionId: string): Promise<Management.SynchronizedGroupPayload[] | null>;
236
262
  /**
237
263
  * Replaces the synchronized groups for a connection (PUT replace-all semantics).
238
264
  */