auth0-deploy-cli 9.0.0-beta.2 → 9.0.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 (126) hide show
  1. package/AGENTS.md +2 -357
  2. package/CHANGELOG.md +158 -10
  3. package/CLAUDE.md +138 -2
  4. package/README.md +1 -1
  5. package/lib/context/defaults.d.ts +7 -0
  6. package/lib/context/defaults.js +74 -30
  7. package/lib/context/directory/handlers/actionModules.js +1 -4
  8. package/lib/context/directory/handlers/actions.js +1 -4
  9. package/lib/context/directory/handlers/attackProtection.js +1 -1
  10. package/lib/context/directory/handlers/branding.js +4 -1
  11. package/lib/context/directory/handlers/clientAuthCredentials.d.ts +5 -0
  12. package/lib/context/directory/handlers/clientAuthCredentials.js +13 -0
  13. package/lib/context/directory/handlers/clientGrants.js +78 -24
  14. package/lib/context/directory/handlers/clients.js +20 -3
  15. package/lib/context/directory/handlers/connections.js +19 -5
  16. package/lib/context/directory/handlers/databases.js +1 -4
  17. package/lib/context/directory/handlers/emailTemplates.js +5 -0
  18. package/lib/context/directory/handlers/guardianEmailFactorSettings.d.ts +5 -0
  19. package/lib/context/directory/handlers/guardianEmailFactorSettings.js +38 -0
  20. package/lib/context/directory/handlers/guardianPhoneFactorSettings.d.ts +5 -0
  21. package/lib/context/directory/handlers/guardianPhoneFactorSettings.js +38 -0
  22. package/lib/context/directory/handlers/guardianSettings.d.ts +5 -0
  23. package/lib/context/directory/handlers/guardianSettings.js +38 -0
  24. package/lib/context/directory/handlers/hooks.js +1 -4
  25. package/lib/context/directory/handlers/index.js +12 -0
  26. package/lib/context/directory/handlers/networkACLKeys.d.ts +6 -0
  27. package/lib/context/directory/handlers/networkACLKeys.js +54 -0
  28. package/lib/context/directory/handlers/prompts.js +7 -3
  29. package/lib/context/directory/handlers/rateLimitPolicies.d.ts +6 -0
  30. package/lib/context/directory/handlers/rateLimitPolicies.js +53 -0
  31. package/lib/context/directory/handlers/rules.js +1 -4
  32. package/lib/context/directory/index.js +1 -4
  33. package/lib/context/index.js +31 -31
  34. package/lib/context/yaml/handlers/attackProtection.js +1 -1
  35. package/lib/context/yaml/handlers/branding.js +4 -1
  36. package/lib/context/yaml/handlers/clientAuthCredentials.d.ts +5 -0
  37. package/lib/context/yaml/handlers/clientAuthCredentials.js +13 -0
  38. package/lib/context/yaml/handlers/clients.js +19 -1
  39. package/lib/context/yaml/handlers/connections.js +8 -1
  40. package/lib/context/yaml/handlers/flows.js +3 -0
  41. package/lib/context/yaml/handlers/forms.js +3 -0
  42. package/lib/context/yaml/handlers/guardianEmailFactorSettings.d.ts +5 -0
  43. package/lib/context/yaml/handlers/guardianEmailFactorSettings.js +15 -0
  44. package/lib/context/yaml/handlers/guardianPhoneFactorSettings.d.ts +5 -0
  45. package/lib/context/yaml/handlers/guardianPhoneFactorSettings.js +15 -0
  46. package/lib/context/yaml/handlers/guardianSettings.d.ts +5 -0
  47. package/lib/context/yaml/handlers/guardianSettings.js +15 -0
  48. package/lib/context/yaml/handlers/index.js +12 -0
  49. package/lib/context/yaml/handlers/networkACLKeys.d.ts +6 -0
  50. package/lib/context/yaml/handlers/networkACLKeys.js +42 -0
  51. package/lib/context/yaml/handlers/prompts.js +3 -1
  52. package/lib/context/yaml/handlers/rateLimitPolicies.d.ts +6 -0
  53. package/lib/context/yaml/handlers/rateLimitPolicies.js +27 -0
  54. package/lib/context/yaml/index.js +1 -4
  55. package/lib/keywordPreservation.d.ts +1 -1
  56. package/lib/keywordPreservation.js +2 -1
  57. package/lib/readonly.js +5 -0
  58. package/lib/tools/auth0/handlers/attackProtection.js +19 -6
  59. package/lib/tools/auth0/handlers/clientAuthCredentials.d.ts +27 -0
  60. package/lib/tools/auth0/handlers/clientAuthCredentials.js +234 -0
  61. package/lib/tools/auth0/handlers/clientAuthCredentialsPre.d.ts +38 -0
  62. package/lib/tools/auth0/handlers/clientAuthCredentialsPre.js +123 -0
  63. package/lib/tools/auth0/handlers/clientGrants.d.ts +1 -1
  64. package/lib/tools/auth0/handlers/clients.d.ts +106 -0
  65. package/lib/tools/auth0/handlers/clients.js +206 -2
  66. package/lib/tools/auth0/handlers/connectionProfiles.d.ts +27 -0
  67. package/lib/tools/auth0/handlers/connectionProfiles.js +30 -0
  68. package/lib/tools/auth0/handlers/connections.d.ts +32 -6
  69. package/lib/tools/auth0/handlers/connections.js +49 -7
  70. package/lib/tools/auth0/handlers/databases.d.ts +28 -0
  71. package/lib/tools/auth0/handlers/databases.js +58 -24
  72. package/lib/tools/auth0/handlers/default.d.ts +23 -0
  73. package/lib/tools/auth0/handlers/default.js +47 -29
  74. package/lib/tools/auth0/handlers/eventStreams.js +10 -2
  75. package/lib/tools/auth0/handlers/guardianEmailFactorSettings.d.ts +22 -0
  76. package/lib/tools/auth0/handlers/guardianEmailFactorSettings.js +77 -0
  77. package/lib/tools/auth0/handlers/guardianFactorTemplates.js +13 -4
  78. package/lib/tools/auth0/handlers/guardianPhoneFactorMessageTypes.js +11 -9
  79. package/lib/tools/auth0/handlers/guardianPhoneFactorSelectedProvider.js +11 -9
  80. package/lib/tools/auth0/handlers/guardianPhoneFactorSettings.d.ts +22 -0
  81. package/lib/tools/auth0/handlers/guardianPhoneFactorSettings.js +77 -0
  82. package/lib/tools/auth0/handlers/guardianPolicies.js +11 -1
  83. package/lib/tools/auth0/handlers/guardianSettings.d.ts +30 -0
  84. package/lib/tools/auth0/handlers/guardianSettings.js +85 -0
  85. package/lib/tools/auth0/handlers/hooks.js +1 -1
  86. package/lib/tools/auth0/handlers/index.js +16 -0
  87. package/lib/tools/auth0/handlers/networkACLKeys.d.ts +45 -0
  88. package/lib/tools/auth0/handlers/networkACLKeys.js +177 -0
  89. package/lib/tools/auth0/handlers/networkACLs.d.ts +132 -2
  90. package/lib/tools/auth0/handlers/networkACLs.js +100 -16
  91. package/lib/tools/auth0/handlers/organizations.d.ts +33 -1
  92. package/lib/tools/auth0/handlers/organizations.js +177 -19
  93. package/lib/tools/auth0/handlers/phoneProvider.js +10 -2
  94. package/lib/tools/auth0/handlers/phoneTemplates.d.ts +4 -1
  95. package/lib/tools/auth0/handlers/phoneTemplates.js +67 -10
  96. package/lib/tools/auth0/handlers/prompts.js +1 -1
  97. package/lib/tools/auth0/handlers/rateLimitPolicies.d.ts +81 -0
  98. package/lib/tools/auth0/handlers/rateLimitPolicies.js +203 -0
  99. package/lib/tools/auth0/handlers/resourceServers.d.ts +44 -0
  100. package/lib/tools/auth0/handlers/resourceServers.js +44 -0
  101. package/lib/tools/auth0/handlers/riskAssessment.d.ts +1 -1
  102. package/lib/tools/auth0/handlers/riskAssessment.js +19 -1
  103. package/lib/tools/auth0/handlers/roles.d.ts +4 -0
  104. package/lib/tools/auth0/handlers/roles.js +10 -0
  105. package/lib/tools/auth0/handlers/rules.js +19 -7
  106. package/lib/tools/auth0/handlers/tenant.d.ts +45 -0
  107. package/lib/tools/auth0/handlers/tenant.js +48 -0
  108. package/lib/tools/auth0/handlers/themes.d.ts +37 -1
  109. package/lib/tools/auth0/handlers/themes.js +64 -0
  110. package/lib/tools/auth0/handlers/tokenExchangeProfiles.js +3 -1
  111. package/lib/tools/auth0/index.js +12 -6
  112. package/lib/tools/calculateDryRunChanges.js +12 -8
  113. package/lib/tools/constants.d.ts +2 -0
  114. package/lib/tools/constants.js +3 -0
  115. package/lib/tools/utils.d.ts +3 -0
  116. package/lib/tools/utils.js +41 -2
  117. package/lib/types.d.ts +9 -1
  118. package/lib/utils.d.ts +6 -0
  119. package/lib/utils.js +17 -2
  120. package/package.json +2 -2
  121. package/references/code-style.md +133 -0
  122. package/references/commands.md +98 -0
  123. package/references/docs-update.md +34 -0
  124. package/references/git-workflow.md +135 -0
  125. package/references/pitfalls.md +62 -0
  126. package/references/testing.md +118 -0
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.schema = void 0;
13
+ const default_1 = require("./default");
14
+ const client_1 = require("../client");
15
+ const logger_1 = __importDefault(require("../../../logger"));
16
+ exports.schema = {
17
+ type: 'array',
18
+ items: { type: 'object' },
19
+ };
20
+ /**
21
+ * Handles full credential deletion BEFORE clients.ts (order 50) patches the client.
22
+ *
23
+ * Auth0 rejects a client PATCH containing token_endpoint_auth_method while that client still
24
+ * has active credentials. By running at order 40, this handler clears credentials (and
25
+ * client_authentication_methods) for any client where the field is absent from config, so
26
+ * that clients.ts can safely include token_endpoint_auth_method in its PATCH.
27
+ *
28
+ * Partial deletion (some credentials removed, others kept) is handled by
29
+ * ClientAuthCredentialsHandler at order 70, because those clients still have
30
+ * client_authentication_methods present in config and clients.ts strips token_endpoint_auth_method
31
+ * for them anyway.
32
+ */
33
+ class ClientAuthCredentialsPreHandler {
34
+ constructor({ client, config }) {
35
+ // Same type as ClientAuthCredentialsHandler so AUTH0_EXCLUDED / AUTH0_INCLUDED_ONLY
36
+ // applies to both handlers together without needing a separate AssetTypes entry.
37
+ this.type = 'clientAuthCredentials';
38
+ this.existing = null;
39
+ this.client = client;
40
+ this.config = config;
41
+ }
42
+ async getType() {
43
+ return null;
44
+ }
45
+ async load() {
46
+ return { [this.type]: null };
47
+ }
48
+ async validate() {
49
+ return null;
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
+ }
56
+ async processChanges(assets) {
57
+ const { clients } = assets;
58
+ if (!clients)
59
+ return;
60
+ const allowDelete = this.config('AUTH0_ALLOW_DELETE') === true || this.config('AUTH0_ALLOW_DELETE') === 'true';
61
+ // When allowDelete is false no deletion will happen — skip entirely to avoid
62
+ // unnecessary GET /credentials calls for every client.
63
+ if (!allowDelete)
64
+ return;
65
+ // Only act on clients where client_authentication_methods is absent from config.
66
+ // Absent = intentional full deletion. Clients with the field present (including partial
67
+ // deletion) are fully handled by ClientAuthCredentialsHandler at order 70.
68
+ const deletionCandidates = clients.filter((c) => c.client_authentication_methods === undefined);
69
+ if (deletionCandidates.length === 0)
70
+ return;
71
+ // In directory mode client_id is stripped. Resolve names once for all candidates.
72
+ const needsNameResolution = deletionCandidates.some((c) => !c.client_id);
73
+ let clientIdByName = new Map();
74
+ if (needsNameResolution) {
75
+ const existingClients = await (0, client_1.paginate)(this.client.clients.list, {
76
+ paginate: true,
77
+ is_global: false,
78
+ });
79
+ clientIdByName = new Map(existingClients.map((c) => [c.name, c.client_id]));
80
+ }
81
+ for (const client of deletionCandidates) {
82
+ const clientId = client.client_id || (client.name && clientIdByName.get(client.name));
83
+ if (!clientId)
84
+ continue;
85
+ const clientName = client.name || clientId;
86
+ let existing = [];
87
+ try {
88
+ existing = (await this.client.clients.credentials.list(clientId));
89
+ }
90
+ catch (err) {
91
+ logger_1.default.warn(`clientAuthCredentials: failed to list credentials for client "${clientName}": ${err}`);
92
+ continue;
93
+ }
94
+ if (existing.length === 0)
95
+ continue;
96
+ // De-reference credentials from client_authentication_methods before deleting them —
97
+ // Auth0 rejects deleting a credential that is still referenced.
98
+ try {
99
+ await this.client.clients.update(clientId, {
100
+ client_authentication_methods: null,
101
+ token_endpoint_auth_method: client.token_endpoint_auth_method || 'client_secret_post',
102
+ });
103
+ }
104
+ catch (err) {
105
+ logger_1.default.warn(`clientAuthCredentials: failed to clear client_authentication_methods on client "${clientName}": ${err}`);
106
+ continue;
107
+ }
108
+ for (const cred of existing) {
109
+ try {
110
+ await this.client.clients.credentials.delete(clientId, cred.id);
111
+ logger_1.default.info(`clientAuthCredentials: deleted credential "${cred.name}" on client "${clientName}"`);
112
+ }
113
+ catch (err) {
114
+ logger_1.default.warn(`clientAuthCredentials: failed to delete credential "${cred.name}" on client "${clientName}": ${err}`);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ exports.default = ClientAuthCredentialsPreHandler;
121
+ __decorate([
122
+ (0, default_1.order)('40')
123
+ ], ClientAuthCredentialsPreHandler.prototype, "processChanges", null);
@@ -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,10 +193,53 @@ 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
+ };
208
+ anonymous_sessions: {
209
+ type: string;
210
+ description: string;
211
+ properties: {
212
+ active: {
213
+ type: string;
214
+ description: string;
215
+ };
216
+ };
217
+ required: string[];
218
+ additionalProperties: boolean;
219
+ };
196
220
  app_type: {
197
221
  type: string;
198
222
  description: string;
199
223
  };
224
+ b2b_integration_configuration: {
225
+ type: string[];
226
+ description: string;
227
+ properties: {
228
+ integration_type: {
229
+ type: string;
230
+ enum: string[];
231
+ description: string;
232
+ };
233
+ sso_profiles: {
234
+ type: string;
235
+ description: string;
236
+ items: {
237
+ type: string;
238
+ };
239
+ };
240
+ };
241
+ additionalProperties: boolean;
242
+ };
200
243
  resource_server_identifier: {
201
244
  type: string;
202
245
  description: string;
@@ -242,10 +285,39 @@ export declare const schema: {
242
285
  enum: ("allow" | "allow_if_empty")[];
243
286
  description: string;
244
287
  };
288
+ third_party_client_access: {
289
+ type: string;
290
+ description: string;
291
+ properties: {
292
+ default_value: {
293
+ type: string;
294
+ enum: "block"[];
295
+ description: string;
296
+ };
297
+ allowed_values: {
298
+ type: string;
299
+ items: {
300
+ type: string;
301
+ enum: ("allow" | "block")[];
302
+ };
303
+ uniqueItems: boolean;
304
+ description: string;
305
+ };
306
+ };
307
+ required: string[];
308
+ };
245
309
  invitation_landing_client_id: {
246
310
  type: string;
247
311
  description: string;
248
312
  };
313
+ enforce_permission_ceiling: {
314
+ type: string;
315
+ description: string;
316
+ };
317
+ enforce_self_assignment_restriction: {
318
+ type: string;
319
+ description: string;
320
+ };
249
321
  };
250
322
  required: string[];
251
323
  };
@@ -328,6 +400,40 @@ export declare const schema: {
328
400
  };
329
401
  };
330
402
  };
403
+ token_vault_privileged_access: {
404
+ type: string[];
405
+ description: string;
406
+ properties: {
407
+ ip_allowlist: {
408
+ type: string;
409
+ description: string;
410
+ items: {
411
+ type: string;
412
+ };
413
+ };
414
+ grants: {
415
+ type: string;
416
+ description: string;
417
+ items: {
418
+ type: string;
419
+ properties: {
420
+ connection: {
421
+ type: string;
422
+ description: string;
423
+ };
424
+ scopes: {
425
+ type: string;
426
+ description: string;
427
+ items: {
428
+ type: string;
429
+ };
430
+ };
431
+ };
432
+ required: string[];
433
+ };
434
+ };
435
+ };
436
+ };
331
437
  third_party_security_mode: {
332
438
  type: string;
333
439
  enum: string[];
@@ -59,13 +59,76 @@ const myOrganizationConfigurationSchema = {
59
59
  enum: Object.values(auth0_1.Management.ClientMyOrganizationDeletionBehaviorEnum),
60
60
  description: 'The deletion behavior for My Organization connections created by this client',
61
61
  },
62
+ third_party_client_access: {
63
+ type: 'object',
64
+ description: 'Controls whether third-party clients can access the organization via the My Organization API.',
65
+ properties: {
66
+ default_value: {
67
+ type: 'string',
68
+ enum: Object.values(auth0_1.Management.ClientMyOrganizationConfigurationThirdPartyClientAccessDefaultValueEnum),
69
+ description: 'The default third-party client access value.',
70
+ },
71
+ allowed_values: {
72
+ type: 'array',
73
+ items: {
74
+ type: 'string',
75
+ enum: Object.values(auth0_1.Management.ClientMyOrganizationConfigurationThirdPartyClientAccessAllowedValuesEnum),
76
+ },
77
+ uniqueItems: true,
78
+ description: 'The allowed third-party client access values.',
79
+ },
80
+ },
81
+ required: ['default_value', 'allowed_values'],
82
+ },
62
83
  invitation_landing_client_id: {
63
84
  type: 'string',
64
85
  description: 'The client ID of the invitation landing client for the My Organization configuration',
65
86
  },
87
+ enforce_permission_ceiling: {
88
+ type: 'boolean',
89
+ description: 'When true, limits the permissions that organization admins can assign to members to only those held by the admin themselves. Early Access, gated by the my_org_member_management_ea feature flag.',
90
+ },
91
+ enforce_self_assignment_restriction: {
92
+ type: 'boolean',
93
+ description: 'When true, prevents organization admins from assigning permissions to themselves. Early Access, gated by the my_org_member_management_ea feature flag.',
94
+ },
66
95
  },
67
96
  required: ['allowed_strategies', 'connection_deletion_behavior'],
68
97
  };
98
+ const tokenVaultPrivilegedAccessSchema = {
99
+ type: ['object', 'null'],
100
+ 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.',
101
+ properties: {
102
+ ip_allowlist: {
103
+ type: 'array',
104
+ 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.',
105
+ items: {
106
+ type: 'string',
107
+ },
108
+ },
109
+ grants: {
110
+ type: 'array',
111
+ 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.',
112
+ items: {
113
+ type: 'object',
114
+ properties: {
115
+ connection: {
116
+ type: 'string',
117
+ description: 'The connection name (e.g. google-oauth2). Validated at runtime; the connection need not exist at configuration time.',
118
+ },
119
+ scopes: {
120
+ type: 'array',
121
+ description: 'The OAuth scopes permitted for that connection.',
122
+ items: {
123
+ type: 'string',
124
+ },
125
+ },
126
+ },
127
+ required: ['connection', 'scopes'],
128
+ },
129
+ },
130
+ },
131
+ };
69
132
  exports.schema = {
70
133
  type: 'array',
71
134
  items: {
@@ -221,10 +284,51 @@ exports.schema = {
221
284
  },
222
285
  additionalProperties: true,
223
286
  },
287
+ identity_assertion_authorization_grant: {
288
+ type: 'object',
289
+ description: 'Settings for Cross App Access (ID-JAG) token exchange. Early Access. Enables the client to request identity assertion authorization grants.',
290
+ properties: {
291
+ active: {
292
+ type: 'boolean',
293
+ description: 'Indicates whether the client can request an identity assertion authorization grant (ID-JAG) via token exchange.',
294
+ },
295
+ },
296
+ required: ['active'],
297
+ additionalProperties: false,
298
+ },
299
+ anonymous_sessions: {
300
+ type: 'object',
301
+ description: 'Configuration for anonymous sessions for this client.',
302
+ properties: {
303
+ active: {
304
+ type: 'boolean',
305
+ description: 'Whether anonymous sessions are enabled for this client.',
306
+ },
307
+ },
308
+ required: ['active'],
309
+ additionalProperties: false,
310
+ },
224
311
  app_type: {
225
312
  type: 'string',
226
313
  description: 'The type of application this client represents',
227
314
  },
315
+ b2b_integration_configuration: {
316
+ type: ['object', 'null'],
317
+ description: 'B2B integration configuration. Early Access. Required feature flag: enterprise_connect_entitled.',
318
+ properties: {
319
+ integration_type: {
320
+ type: 'string',
321
+ enum: ['custom_auth_server', 'third_party', 'application'],
322
+ description: 'The type of integration used to connect to this B2B integration client.',
323
+ },
324
+ sso_profiles: {
325
+ type: 'array',
326
+ description: 'List of SSO profile IDs linked to this B2B integration client. Maximum 1 entry.',
327
+ items: { type: 'string' },
328
+ },
329
+ },
330
+ additionalProperties: false,
331
+ },
228
332
  resource_server_identifier: {
229
333
  type: 'string',
230
334
  description: 'The identifier of a resource server in your tenant. This property links a client to a resource server indicating that the client IS that resource server. Can only be set when app_type=resource_server.',
@@ -332,6 +436,7 @@ exports.schema = {
332
436
  },
333
437
  },
334
438
  },
439
+ token_vault_privileged_access: tokenVaultPrivilegedAccessSchema,
335
440
  third_party_security_mode: {
336
441
  type: 'string',
337
442
  enum: ['strict', 'permissive'],
@@ -460,6 +565,40 @@ const createClientSanitizer = (clients) => {
460
565
  },
461
566
  };
462
567
  };
568
+ /**
569
+ * On export, remove `credentials` from `token_vault_privileged_access`.
570
+ *
571
+ * Auth0 returns these as tenant-specific credential references (`{ id }`) — never
572
+ * names or key material — so they are not portable across tenants and must never be
573
+ * written to disk. `ip_allowlist` and `grants` are kept for visibility. Mutates and
574
+ * returns the same client.
575
+ */
576
+ const stripTokenVaultCredentialsOnExport = (client) => {
577
+ const tvpa = client
578
+ .token_vault_privileged_access;
579
+ if (tvpa && 'credentials' in tvpa) {
580
+ delete tvpa.credentials;
581
+ }
582
+ return client;
583
+ };
584
+ /**
585
+ * On write (create/update), remove the entire `token_vault_privileged_access` object.
586
+ *
587
+ * The Management API requires `credentials` whenever `token_vault_privileged_access`
588
+ * is present in the payload, but those credentials are tenant-specific ids that the
589
+ * Deploy CLI intentionally never persists (see stripTokenVaultCredentialsOnExport).
590
+ * Sending the object without `credentials` fails validation ("Missing required
591
+ * property: credentials"); sending it with exported ids would re-send stale ids on a
592
+ * cross-tenant deploy. The Deploy CLI therefore does not manage this field — it is
593
+ * export-only. Manage `token_vault_privileged_access` directly on the tenant.
594
+ * Mutates and returns the same client.
595
+ */
596
+ const stripTokenVaultPrivilegedAccessOnWrite = (client) => {
597
+ if ('token_vault_privileged_access' in client) {
598
+ delete client.token_vault_privileged_access;
599
+ }
600
+ return client;
601
+ };
463
602
  class ClientHandler extends default_1.default {
464
603
  constructor(config) {
465
604
  super({
@@ -482,6 +621,9 @@ class ClientHandler extends default_1.default {
482
621
  'jwks_uri',
483
622
  // third_party_security_mode is immutable after creation; PATCH returns 400
484
623
  'third_party_security_mode',
624
+ // API-generated timestamps; PATCH returns 400 if present
625
+ 'created_at',
626
+ 'updated_at',
485
627
  ],
486
628
  functions: {
487
629
  create: (client) => this.createClient(client),
@@ -566,6 +708,21 @@ class ClientHandler extends default_1.default {
566
708
  delete item.refresh_token;
567
709
  }
568
710
  }
711
+ // Strip client_authentication_methods — the clientAuthCredentials handler (order 70)
712
+ // owns this field entirely. Auth0 rejects credential objects with name/credential_type in PATCH.
713
+ // Strip token_endpoint_auth_method only when client_authentication_methods is present in config:
714
+ // Auth0 rejects it in PATCH while a client has active credentials. For these clients the
715
+ // clientAuthCredentials handler (order 70) owns token_endpoint_auth_method too.
716
+ // For clients without client_authentication_methods, credentials were already cleared by
717
+ // clientAuthCredentialsPre (order 40), so token_endpoint_auth_method passes through safely.
718
+ if (item.client_authentication_methods) {
719
+ delete item.token_endpoint_auth_method;
720
+ }
721
+ delete item.client_authentication_methods;
722
+ // token_vault_privileged_access requires tenant-specific credential ids that
723
+ // the Deploy CLI never persists. Strip the whole object on write so we neither
724
+ // re-send stale ids nor fail validation for the missing credentials property.
725
+ stripTokenVaultPrivilegedAccessOnWrite(item);
569
726
  return item;
570
727
  });
571
728
  };
@@ -587,7 +744,38 @@ class ClientHandler extends default_1.default {
587
744
  is_global: false,
588
745
  ...((0, utils_1.shouldExcludeThirdPartyClients)(this.config) && { is_first_party: true }),
589
746
  });
590
- this.existing = createClientSanitizer(clients).sanitizeCrossOriginAuth(false).get();
747
+ const sanitized = createClientSanitizer(clients)
748
+ .sanitizeCrossOriginAuth(false)
749
+ .get()
750
+ // token_vault_privileged_access.credentials are returned as tenant-specific
751
+ // ids — strip them so they are never exported to disk.
752
+ .map(stripTokenVaultCredentialsOnExport);
753
+ // Enrich credential stubs with name and credential_type for export.
754
+ // Auth0 does not return pem on read — it is never exported.
755
+ await Promise.all(sanitized.map(async (client) => {
756
+ if (!client.client_authentication_methods)
757
+ return;
758
+ try {
759
+ const creds = await this.client.clients.credentials.list(client.client_id);
760
+ const credMap = new Map(creds.map((c) => [c.id, c]));
761
+ Object.values(client.client_authentication_methods).forEach((method) => {
762
+ if (method?.credentials) {
763
+ method.credentials = method.credentials
764
+ .map((stub) => {
765
+ const full = credMap.get(stub.id);
766
+ if (!full?.name)
767
+ return null;
768
+ return { name: full.name, credential_type: full.credential_type };
769
+ })
770
+ .filter(Boolean);
771
+ }
772
+ });
773
+ }
774
+ catch (_) {
775
+ // leave stubs as-is if the credentials API call fails
776
+ }
777
+ }));
778
+ this.existing = sanitized;
591
779
  return this.existing;
592
780
  }
593
781
  isCimdClient(client) {
@@ -625,7 +813,23 @@ class ClientHandler extends default_1.default {
625
813
  async updateClient(clientId, client) {
626
814
  // For non-CIMD clients
627
815
  if (!this.isCimdClient(client)) {
628
- return this.client.clients.update(clientId, client);
816
+ const payload = { ...client };
817
+ // b2b_integration_configuration: PATCH only allowed if client already has the object.
818
+ // Sending it to a client that lacks it returns 400 invalid_body.
819
+ // null clears the object — but only for clients that already have it; stripping
820
+ // null for a client without the field is a safe no-op.
821
+ if ('b2b_integration_configuration' in payload) {
822
+ const existing = (this.existing || []).find((c) => c.client_id === (client.client_id || clientId));
823
+ if (!existing?.b2b_integration_configuration) {
824
+ if (payload.b2b_integration_configuration !== null) {
825
+ logger_1.default.warn(`b2b_integration_configuration cannot be added to an existing client via PATCH ` +
826
+ `(client: ${client.name || clientId}). Skipping field. ` +
827
+ `Re-create the client to set this field.`);
828
+ }
829
+ delete payload.b2b_integration_configuration;
830
+ }
831
+ }
832
+ return this.client.clients.update(clientId, payload);
629
833
  }
630
834
  const updatePayload = this.getCIMDEditableFields(client);
631
835
  const registrationClientId = client.client_id || clientId;
@@ -36,6 +36,33 @@ export declare const schema: {
36
36
  connection_config: {
37
37
  type: string[];
38
38
  };
39
+ cross_app_access_resource_app: {
40
+ type: string;
41
+ description: string;
42
+ properties: {
43
+ status: {
44
+ type: string;
45
+ properties: {
46
+ default_value: {
47
+ type: string;
48
+ enum: ("enabled" | "disabled")[];
49
+ description: string;
50
+ };
51
+ allowed_values: {
52
+ type: string;
53
+ items: {
54
+ type: string;
55
+ enum: ("enabled" | "disabled")[];
56
+ };
57
+ uniqueItems: boolean;
58
+ description: string;
59
+ };
60
+ };
61
+ required: string[];
62
+ };
63
+ };
64
+ required: string[];
65
+ };
39
66
  strategy_overrides: {
40
67
  type: string[];
41
68
  properties: {
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getConnectionProfile = exports.schema = void 0;
7
+ const auth0_1 = require("auth0");
7
8
  const default_1 = __importDefault(require("./default"));
8
9
  const client_1 = require("../client");
9
10
  const logger_1 = __importDefault(require("../../../logger"));
@@ -42,6 +43,35 @@ exports.schema = {
42
43
  connection_config: {
43
44
  type: ['object', 'null'],
44
45
  },
46
+ cross_app_access_resource_app: {
47
+ type: 'object',
48
+ description: 'Controls whether organization admins may enable Cross App Access (XAA) on their Identity Providers.',
49
+ properties: {
50
+ status: {
51
+ type: 'object',
52
+ properties: {
53
+ default_value: {
54
+ type: 'string',
55
+ enum: Object.values(auth0_1.Management.ConnectionProfileCrossAppAccessResourceAppStatusDefaultValueEnum),
56
+ description: 'The default Cross App Access resource app status.',
57
+ },
58
+ allowed_values: {
59
+ type: 'array',
60
+ items: {
61
+ type: 'string',
62
+ enum: Object.values(auth0_1.Management.ConnectionProfileCrossAppAccessResourceAppStatusValueEnum),
63
+ },
64
+ uniqueItems: true,
65
+ description: 'The allowed Cross App Access resource app status values.',
66
+ },
67
+ },
68
+ // allowed_values is optional per the SDK type (unlike the client's
69
+ // third_party_client_access, which requires both fields).
70
+ required: ['default_value'],
71
+ },
72
+ },
73
+ required: ['status'],
74
+ },
45
75
  strategy_overrides: {
46
76
  type: ['object', 'null'],
47
77
  properties: {