@canopy-io/node 0.10.0 → 0.12.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.
- package/CHANGELOG.md +25 -0
- package/README.md +61 -4
- package/dist/index.cjs +288 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1819 -277
- package/dist/index.d.ts +1819 -277
- package/dist/index.js +288 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -748,7 +748,7 @@ interface paths {
|
|
|
748
748
|
};
|
|
749
749
|
/**
|
|
750
750
|
* Get identity's effective permissions
|
|
751
|
-
* @description Returns the identity's effective
|
|
751
|
+
* @description Returns the identity's effective permission keys for the current Environment as a flat `items` array of strings. Without `node_id`, the Application-wide answer: every permission its role assignments grant anywhere. With `node_id`, the answer at that node: the permissions granted by assignments on the node's lineage, the list a screen renders its controls from. Returns `404` when the identity has no membership in this Environment, or when `node_id` names no node in it.
|
|
752
752
|
*/
|
|
753
753
|
get: operations["ApiIdentitiesController_getIdentityPermissions"];
|
|
754
754
|
put?: never;
|
|
@@ -759,6 +759,26 @@ interface paths {
|
|
|
759
759
|
patch?: never;
|
|
760
760
|
trace?: never;
|
|
761
761
|
};
|
|
762
|
+
"/api/v1/identities/{id}/accessible-nodes": {
|
|
763
|
+
parameters: {
|
|
764
|
+
query?: never;
|
|
765
|
+
header?: never;
|
|
766
|
+
path?: never;
|
|
767
|
+
cookie?: never;
|
|
768
|
+
};
|
|
769
|
+
/**
|
|
770
|
+
* Get where an identity may act with one permission
|
|
771
|
+
* @description Returns where the identity may act with `permission`, for a list query: `roots`, the nodes it holds the permission at that no other such node already covers, and `nodes`, every node beneath those roots, the roots included, when there are at most `max_nodes` of them (default 10,000; at most 50,000). Past the cap `nodes` is null and `complete` false, and the caller filters by `roots` against its own closure table or materialised path. `env_wide` is true when a root is the Environment's own root, so every node qualifies and no filter is needed; `nodes` is null then too. The same rules as `evaluate` decide the roots, so a list filtered by this answer agrees with the check a write makes. Returns `404` when the identity has no membership in this Environment.
|
|
772
|
+
*/
|
|
773
|
+
get: operations["ApiIdentitiesController_getIdentityAccessibleNodes"];
|
|
774
|
+
put?: never;
|
|
775
|
+
post?: never;
|
|
776
|
+
delete?: never;
|
|
777
|
+
options?: never;
|
|
778
|
+
head?: never;
|
|
779
|
+
patch?: never;
|
|
780
|
+
trace?: never;
|
|
781
|
+
};
|
|
762
782
|
"/api/v1/identities/{id}/grants": {
|
|
763
783
|
parameters: {
|
|
764
784
|
query?: never;
|
|
@@ -768,7 +788,7 @@ interface paths {
|
|
|
768
788
|
};
|
|
769
789
|
/**
|
|
770
790
|
* Get where an identity holds each permission
|
|
771
|
-
* @description Returns, for the current Environment, one page of `(permission, node_id)` rows: every permission the identity holds, paired with each hierarchy node its grants were made at — the nodes themselves, **not** expanded through their descendants. Rows are ordered by permission, then node; a caller building the whole map walks every page. A grant already means "this node and everything beneath it", so a caller answers a node-scoped question by walking up from the node in question and looking for one of these roots, using a copy of the parent edges fetched once from `GET /api/v1/nodes/parents` and shared across identities. Answers both scopes without a further call: the permission appearing at all is the Application-wide answer, and the walk is the node-scoped one.
|
|
791
|
+
* @description Returns, for the current Environment, one page of `(permission, node_id)` rows: every permission the identity holds, paired with each hierarchy node its grants were made at — the nodes themselves, **not** expanded through their descendants. Rows are ordered by permission, then node; a caller building the whole map walks every page. A grant already means "this node and everything beneath it", so a caller answers a node-scoped question by walking up from the node in question and looking for one of these roots, using a copy of the parent edges fetched once from `GET /api/v1/nodes/parents` and shared across identities. Answers both scopes without a further call: the permission appearing at all is the Application-wide answer, and the walk is the node-scoped one. By default, assignments outside their effective window are excluded. With `include=windows`, every assignment is a row carrying `effective_from` and `effective_to` (null for an unbounded side), in effect or not, so a caller applies the window itself: it can say why a check fails (the grant has ended, or has not begun) and drop a grant at its boundary without reading again. Returns `404` when the identity has no membership in this Environment.
|
|
772
792
|
*/
|
|
773
793
|
get: operations["ApiIdentitiesController_getIdentityGrants"];
|
|
774
794
|
put?: never;
|
|
@@ -1075,6 +1095,170 @@ interface paths {
|
|
|
1075
1095
|
patch?: never;
|
|
1076
1096
|
trace?: never;
|
|
1077
1097
|
};
|
|
1098
|
+
"/api/v1/organizations/{id}/me": {
|
|
1099
|
+
parameters: {
|
|
1100
|
+
query?: never;
|
|
1101
|
+
header?: never;
|
|
1102
|
+
path?: never;
|
|
1103
|
+
cookie?: never;
|
|
1104
|
+
};
|
|
1105
|
+
/**
|
|
1106
|
+
* What the caller administers in an organization
|
|
1107
|
+
* @description The authority read a customer's admin screen renders from: whether the caller holds `canopy:organization.manage` at the organization node (`administers_organization`), the topmost nodes where they hold `canopy:access.manage` inside it (`access_roots`, each with its name, type and the path of names from the organization down to it; the organization node itself when they administer the organization), the same for the structure and roles keys (empty until those ship), and whether the Environment's schema allows nodes beneath an organization (`has_hierarchy`). Computed from assignments at or beneath the organization node only, so a role held above every organization does not count. The developer's key answers as administering the whole organization. Refused with `403` for a caller holding nothing inside the organization.
|
|
1108
|
+
*/
|
|
1109
|
+
get: operations["ApiOrganizationAccessController_me"];
|
|
1110
|
+
put?: never;
|
|
1111
|
+
post?: never;
|
|
1112
|
+
delete?: never;
|
|
1113
|
+
options?: never;
|
|
1114
|
+
head?: never;
|
|
1115
|
+
patch?: never;
|
|
1116
|
+
trace?: never;
|
|
1117
|
+
};
|
|
1118
|
+
"/api/v1/organizations/{id}/tree": {
|
|
1119
|
+
parameters: {
|
|
1120
|
+
query?: never;
|
|
1121
|
+
header?: never;
|
|
1122
|
+
path?: never;
|
|
1123
|
+
cookie?: never;
|
|
1124
|
+
};
|
|
1125
|
+
/**
|
|
1126
|
+
* List the organization's tree as the caller sees it
|
|
1127
|
+
* @description The organization's subtree pruned to the caller: every node beneath a node they administer is `accessible`, the ancestors between the organization node and such a node are `context_only`, and nothing else is returned. A paged flat list, each row carrying its parent, in the shape of the developer's node listing. Admitted to whoever the authority read admits.
|
|
1128
|
+
*/
|
|
1129
|
+
get: operations["ApiOrganizationAccessController_tree"];
|
|
1130
|
+
put?: never;
|
|
1131
|
+
post?: never;
|
|
1132
|
+
delete?: never;
|
|
1133
|
+
options?: never;
|
|
1134
|
+
head?: never;
|
|
1135
|
+
patch?: never;
|
|
1136
|
+
trace?: never;
|
|
1137
|
+
};
|
|
1138
|
+
"/api/v1/organizations/{id}/nodes/{nodeId}/access": {
|
|
1139
|
+
parameters: {
|
|
1140
|
+
query?: never;
|
|
1141
|
+
header?: never;
|
|
1142
|
+
path?: never;
|
|
1143
|
+
cookie?: never;
|
|
1144
|
+
};
|
|
1145
|
+
/**
|
|
1146
|
+
* List who holds a role at a node in the organization
|
|
1147
|
+
* @description Who holds a role at the node, directly or inherited from a node above it inside the organization: one row per assignment with the identity, the role, where it was granted and its window. Paginated; filtered and sorted as the developer's node identities listing is. Requires `hierarchy.view` at the node, or `canopy:organization.manage` at the organization, or `canopy:access.manage` at the node or above it.
|
|
1148
|
+
*/
|
|
1149
|
+
get: operations["ApiOrganizationAccessController_listAccess"];
|
|
1150
|
+
put?: never;
|
|
1151
|
+
post?: never;
|
|
1152
|
+
delete?: never;
|
|
1153
|
+
options?: never;
|
|
1154
|
+
head?: never;
|
|
1155
|
+
patch?: never;
|
|
1156
|
+
trace?: never;
|
|
1157
|
+
};
|
|
1158
|
+
"/api/v1/organizations/{id}/nodes/{nodeId}/access/summary": {
|
|
1159
|
+
parameters: {
|
|
1160
|
+
query?: never;
|
|
1161
|
+
header?: never;
|
|
1162
|
+
path?: never;
|
|
1163
|
+
cookie?: never;
|
|
1164
|
+
};
|
|
1165
|
+
/**
|
|
1166
|
+
* Summarize who holds a role at a node in the organization
|
|
1167
|
+
* @description The counts over the node's assignments: direct and inherited people, by status, roles in use and the most recent arrivals, with `can_manage_assignments` saying whether the caller may change them. Requires the same as the node access listing.
|
|
1168
|
+
*/
|
|
1169
|
+
get: operations["ApiOrganizationAccessController_accessSummary"];
|
|
1170
|
+
put?: never;
|
|
1171
|
+
post?: never;
|
|
1172
|
+
delete?: never;
|
|
1173
|
+
options?: never;
|
|
1174
|
+
head?: never;
|
|
1175
|
+
patch?: never;
|
|
1176
|
+
trace?: never;
|
|
1177
|
+
};
|
|
1178
|
+
"/api/v1/organizations/{id}/nodes/{nodeId}/grantable-roles": {
|
|
1179
|
+
parameters: {
|
|
1180
|
+
query?: never;
|
|
1181
|
+
header?: never;
|
|
1182
|
+
path?: never;
|
|
1183
|
+
cookie?: never;
|
|
1184
|
+
};
|
|
1185
|
+
/**
|
|
1186
|
+
* List the roles the caller may grant at a node
|
|
1187
|
+
* @description The active, assignable roles of the Environment kept to the ones the caller may grant at the node under the grant ceiling: for an identity, those whose every permission it holds at the node or above; every assignable role for the developer's key and Console users. The list a picker offers, so nothing it shows is refused on write. Requires `canopy:access.manage` at the node or above it, `canopy:organization.manage` at the organization, or `hierarchy.manage` at the node. The response is an unpaginated `{ items }` array.
|
|
1188
|
+
*/
|
|
1189
|
+
get: operations["ApiOrganizationAccessController_grantableRoles"];
|
|
1190
|
+
put?: never;
|
|
1191
|
+
post?: never;
|
|
1192
|
+
delete?: never;
|
|
1193
|
+
options?: never;
|
|
1194
|
+
head?: never;
|
|
1195
|
+
patch?: never;
|
|
1196
|
+
trace?: never;
|
|
1197
|
+
};
|
|
1198
|
+
"/api/v1/organizations/{id}/nodes/{nodeId}/members": {
|
|
1199
|
+
parameters: {
|
|
1200
|
+
query?: never;
|
|
1201
|
+
header?: never;
|
|
1202
|
+
path?: never;
|
|
1203
|
+
cookie?: never;
|
|
1204
|
+
};
|
|
1205
|
+
/**
|
|
1206
|
+
* List the organization's members, for granting a role at a node
|
|
1207
|
+
* @description The organization's members as candidates for a role at the node: each row names the identity only. Paginated; `q` searches name and email. Requires the same as the grantable-roles read at the node, so an administrator of one office may choose from the whole organization's roster without reading what anyone else holds.
|
|
1208
|
+
*/
|
|
1209
|
+
get: operations["ApiOrganizationAccessController_listMembersAt"];
|
|
1210
|
+
put?: never;
|
|
1211
|
+
post?: never;
|
|
1212
|
+
delete?: never;
|
|
1213
|
+
options?: never;
|
|
1214
|
+
head?: never;
|
|
1215
|
+
patch?: never;
|
|
1216
|
+
trace?: never;
|
|
1217
|
+
};
|
|
1218
|
+
"/api/v1/organizations/{id}/assignments": {
|
|
1219
|
+
parameters: {
|
|
1220
|
+
query?: never;
|
|
1221
|
+
header?: never;
|
|
1222
|
+
path?: never;
|
|
1223
|
+
cookie?: never;
|
|
1224
|
+
};
|
|
1225
|
+
get?: never;
|
|
1226
|
+
put?: never;
|
|
1227
|
+
/**
|
|
1228
|
+
* Grant a role at a node beneath the organization
|
|
1229
|
+
* @description Grants `role_id` to `identity_id` at `node_id`, the organization node or one beneath it. The identity must be a member of the organization (`409 organization.membership_required` otherwise). Requires `rbac.manage_assignments` at the node, `canopy:organization.manage` at the organization, or `canopy:access.manage` at the node or above it, within the grant ceiling. Emits `assignment.created`.
|
|
1230
|
+
*/
|
|
1231
|
+
post: operations["ApiOrganizationAccessController_createAssignment"];
|
|
1232
|
+
delete?: never;
|
|
1233
|
+
options?: never;
|
|
1234
|
+
head?: never;
|
|
1235
|
+
patch?: never;
|
|
1236
|
+
trace?: never;
|
|
1237
|
+
};
|
|
1238
|
+
"/api/v1/organizations/{id}/assignments/{assignmentId}": {
|
|
1239
|
+
parameters: {
|
|
1240
|
+
query?: never;
|
|
1241
|
+
header?: never;
|
|
1242
|
+
path?: never;
|
|
1243
|
+
cookie?: never;
|
|
1244
|
+
};
|
|
1245
|
+
get?: never;
|
|
1246
|
+
put?: never;
|
|
1247
|
+
post?: never;
|
|
1248
|
+
/**
|
|
1249
|
+
* Take a grant in the organization away
|
|
1250
|
+
* @description Removes an assignment at the organization node or beneath it; the membership stays. Never bounded by the grant ceiling, but the last administrator's role at the organization node cannot be removed (`409 organization.last_admin`). Requires the same as creating one.
|
|
1251
|
+
*/
|
|
1252
|
+
delete: operations["ApiOrganizationAccessController_removeAssignment"];
|
|
1253
|
+
options?: never;
|
|
1254
|
+
head?: never;
|
|
1255
|
+
/**
|
|
1256
|
+
* Change a grant in the organization
|
|
1257
|
+
* @description Changes the role or the window of an assignment at the organization node or beneath it. A new role meets the grant ceiling; dates alone do not. The last administrator's role at the organization node cannot be changed away (`409 organization.last_admin`). Requires the same as creating one.
|
|
1258
|
+
*/
|
|
1259
|
+
patch: operations["ApiOrganizationAccessController_updateAssignment"];
|
|
1260
|
+
trace?: never;
|
|
1261
|
+
};
|
|
1078
1262
|
"/api/v1/organizations": {
|
|
1079
1263
|
parameters: {
|
|
1080
1264
|
query?: never;
|
|
@@ -1332,13 +1516,13 @@ interface paths {
|
|
|
1332
1516
|
};
|
|
1333
1517
|
/**
|
|
1334
1518
|
* List an organization's members
|
|
1335
|
-
* @description Lists the organization's members: each row is the member's identity,
|
|
1519
|
+
* @description Lists the organization's members: each row is the membership (its `status`, `source` and `joined_at`), the member's identity, and `roles`, every role assignment the member holds in the organization, at its node and beneath, with the node and the effective window. Active members by default; `status=deactivated` lists those who left and `status=all` both. Paginated; `q` searches name and email, `role_id` keeps members holding that role anywhere in the organization. Requires the `rbac.view_assignments` permission at the organization.
|
|
1336
1520
|
*/
|
|
1337
1521
|
get: operations["ApiOrganizationsController_listMembers"];
|
|
1338
1522
|
put?: never;
|
|
1339
1523
|
/**
|
|
1340
1524
|
* Add a member to an organization
|
|
1341
|
-
* @description Adds a member:
|
|
1525
|
+
* @description Adds a member. Membership is admission, not authority: with `role_id` the member also holds that role at the organization node from the start; without it they belong and hold nothing until a role is assigned. The identity must already hold an active membership in this Environment (invite by email instead for someone who does not). An identity that is already a member returns `409`; roles are added through the assignment routes. Requires the `rbac.manage_assignments` permission at the organization and emits `organization.member.added`. An organization's own administrator, signed in with an identity token and admitted by `canopy:organization.manage` alone, is refused with `403` (`organization.member_add_requires_invite`): the person never agreed to join, so the administrator invites them instead.
|
|
1342
1526
|
*/
|
|
1343
1527
|
post: operations["ApiOrganizationsController_addMember"];
|
|
1344
1528
|
delete?: never;
|
|
@@ -1359,16 +1543,12 @@ interface paths {
|
|
|
1359
1543
|
post?: never;
|
|
1360
1544
|
/**
|
|
1361
1545
|
* Remove a member from an organization
|
|
1362
|
-
* @description Removes the member from this organization
|
|
1546
|
+
* @description Removes the member from this organization: the membership is deactivated and every role assignment they hold at the organization's nodes goes with it, and nothing else; the identity and its memberships in other organizations are untouched. Returns `404` when the identity is not an active member and `409` when they are the last administrator. Responds `204 No Content`, requires the `rbac.manage_assignments` permission at the organization, and emits `organization.member.removed`.
|
|
1363
1547
|
*/
|
|
1364
1548
|
delete: operations["ApiOrganizationsController_removeMember"];
|
|
1365
1549
|
options?: never;
|
|
1366
1550
|
head?: never;
|
|
1367
|
-
|
|
1368
|
-
* Change a member's role
|
|
1369
|
-
* @description Replaces the member's role in this organization with `role_id`. A member holds exactly one role per organization, so this updates the existing membership in place; changing to the role already held is a no-op. Returns `404` when the identity is not a member. Requires the `rbac.manage_assignments` permission at the organization and emits `organization.member.role_changed`.
|
|
1370
|
-
*/
|
|
1371
|
-
patch: operations["ApiOrganizationsController_changeMemberRole"];
|
|
1551
|
+
patch?: never;
|
|
1372
1552
|
trace?: never;
|
|
1373
1553
|
};
|
|
1374
1554
|
"/api/v1/organizations/{id}/members/{identityId}/mfa/reset": {
|
|
@@ -1424,7 +1604,7 @@ interface paths {
|
|
|
1424
1604
|
};
|
|
1425
1605
|
/**
|
|
1426
1606
|
* List the roles an organization may assign
|
|
1427
|
-
* @description The active, assignable roles of the organization's Environment, for choosing a member's role or an invitation's. System roles are left out, since they cannot be assigned. Requires `hierarchy.view` or `canopy:
|
|
1607
|
+
* @description The active, assignable roles of the organization's Environment, for choosing a member's role or an invitation's, each with `grantable`: whether the caller may grant it at the organization node under the grant ceiling (always true for the developer's key). System roles are left out, since they cannot be assigned. Requires `hierarchy.view`, `canopy:organization.manage` at the organization, or `canopy:access.manage` at the organization node. The response is an unpaginated `{ items }` array.
|
|
1428
1608
|
*/
|
|
1429
1609
|
get: operations["ApiOrganizationsController_listRoles"];
|
|
1430
1610
|
put?: never;
|
|
@@ -2484,6 +2664,7 @@ interface components {
|
|
|
2484
2664
|
effective_node_id?: string | null;
|
|
2485
2665
|
/** @description Ids of the roles whose assignments produced a node-scoped allow. Always empty for `scope_evaluated: "app_wide"`, whose answer is not tied to a node, and for a deny. */
|
|
2486
2666
|
granting_roles: string[];
|
|
2667
|
+
/** @description Why the check was refused: `NO_ROLE_ASSIGNMENT`, `PERMISSION_NOT_GRANTED`, `NODE_SCOPE_VIOLATION`, `ROLE_EXPIRED`, `IDENTITY_INACTIVE`, `IDENTITY_NOT_ENV_MEMBER`, or `ORGANIZATION_MEMBERSHIP_INACTIVE` (assignments sit on the lineage inside an organization the identity's membership in is deactivated, so none count). Null on an allow. */
|
|
2487
2668
|
denial_reason?: string | null;
|
|
2488
2669
|
};
|
|
2489
2670
|
EvaluatePermissionDto: {
|
|
@@ -2518,7 +2699,7 @@ interface components {
|
|
|
2518
2699
|
assignment_id: string;
|
|
2519
2700
|
role_id: string;
|
|
2520
2701
|
role_name: string;
|
|
2521
|
-
/** @description Whether the assignment counts right now: within its effective_from/effective_to window,
|
|
2702
|
+
/** @description Whether the assignment counts right now: within its effective_from/effective_to window, its role active, and, inside an organization, the holder's membership there active. An assignment that fails any of these is listed but grants nothing. */
|
|
2522
2703
|
active: boolean;
|
|
2523
2704
|
effective_from?: string | null;
|
|
2524
2705
|
effective_to?: string | null;
|
|
@@ -2592,6 +2773,8 @@ interface components {
|
|
|
2592
2773
|
effective_from: string | null;
|
|
2593
2774
|
/** @description When this assignment expires; null means it never does */
|
|
2594
2775
|
effective_to: string | null;
|
|
2776
|
+
/** @description Optimistic-lock version; send it back as `If-Match` */
|
|
2777
|
+
version: number;
|
|
2595
2778
|
};
|
|
2596
2779
|
IdentityRowDto: {
|
|
2597
2780
|
id: string;
|
|
@@ -2738,6 +2921,20 @@ interface components {
|
|
|
2738
2921
|
created_at: string;
|
|
2739
2922
|
/** Format: date-time */
|
|
2740
2923
|
updated_at: string;
|
|
2924
|
+
/** @description Optimistic-lock version; send it back as `If-Match` */
|
|
2925
|
+
version: number;
|
|
2926
|
+
};
|
|
2927
|
+
IdentityAccessibleNodesResponseDto: {
|
|
2928
|
+
/** @example reports.view */
|
|
2929
|
+
permission: string;
|
|
2930
|
+
/** @description True when a root is the Environment's own root, so every node qualifies and a list needs no filter. `nodes` is null then. */
|
|
2931
|
+
env_wide: boolean;
|
|
2932
|
+
/** @description The nodes the permission is granted at, in effect now, that no other such node already covers. Each reaches everything beneath it. */
|
|
2933
|
+
roots: string[];
|
|
2934
|
+
/** @description Every node beneath the roots, the roots included, for an `IN (...)` filter. Null when `env_wide`, or when there are more than `max_nodes` (then `complete` is false and the caller filters by `roots` instead). */
|
|
2935
|
+
nodes: string[] | null;
|
|
2936
|
+
/** @description False when the set beneath the roots was larger than `max_nodes` and was not sent. */
|
|
2937
|
+
complete: boolean;
|
|
2741
2938
|
};
|
|
2742
2939
|
IdentityGrantResponseDto: {
|
|
2743
2940
|
/** @example reports.view */
|
|
@@ -2747,6 +2944,16 @@ interface components {
|
|
|
2747
2944
|
* @description The hierarchy node the permission was granted at. Not expanded through descendants.
|
|
2748
2945
|
*/
|
|
2749
2946
|
node_id: string;
|
|
2947
|
+
/**
|
|
2948
|
+
* Format: date-time
|
|
2949
|
+
* @description When the assignment behind this root begins, or null for no start. Present only with `include=windows`.
|
|
2950
|
+
*/
|
|
2951
|
+
effective_from?: string | null;
|
|
2952
|
+
/**
|
|
2953
|
+
* Format: date-time
|
|
2954
|
+
* @description When the assignment behind this root ends, or null for no end. Present only with `include=windows`.
|
|
2955
|
+
*/
|
|
2956
|
+
effective_to?: string | null;
|
|
2750
2957
|
};
|
|
2751
2958
|
IdentityInviteResponseDto: {
|
|
2752
2959
|
id: string;
|
|
@@ -2957,6 +3164,8 @@ interface components {
|
|
|
2957
3164
|
status: "active" | "scheduled" | "expired";
|
|
2958
3165
|
/** Format: date-time */
|
|
2959
3166
|
created_at: string;
|
|
3167
|
+
/** @description Optimistic-lock version; send it back as `If-Match` */
|
|
3168
|
+
version: number;
|
|
2960
3169
|
};
|
|
2961
3170
|
IdentityAssignmentRowDto: {
|
|
2962
3171
|
identity: components["schemas"]["AssignmentIdentityDto"];
|
|
@@ -2981,6 +3190,65 @@ interface components {
|
|
|
2981
3190
|
distinct_role_count: number;
|
|
2982
3191
|
recent_identities: components["schemas"]["RecentIdentityDto"][];
|
|
2983
3192
|
};
|
|
3193
|
+
OrganizationAuthorityRootDto: {
|
|
3194
|
+
node_id: string;
|
|
3195
|
+
name: string;
|
|
3196
|
+
/** @description The node's type, as the schema names it */
|
|
3197
|
+
node_type: string;
|
|
3198
|
+
/** @description The names from the organization node down to this node's parent, so the node can be named in context; empty for the organization node itself */
|
|
3199
|
+
path: string[];
|
|
3200
|
+
};
|
|
3201
|
+
OrganizationMeResponseDto: {
|
|
3202
|
+
/** @description Holds `canopy:organization.manage` at the organization node, or is the developer's key */
|
|
3203
|
+
administers_organization: boolean;
|
|
3204
|
+
/** @description The topmost nodes where `canopy:access.manage` is held inside the organization; the organization node when `administers_organization` */
|
|
3205
|
+
access_roots: components["schemas"]["OrganizationAuthorityRootDto"][];
|
|
3206
|
+
/** @description The same for `canopy:structure.manage`, a key no role carries yet; always empty */
|
|
3207
|
+
structure_roots: components["schemas"]["OrganizationAuthorityRootDto"][];
|
|
3208
|
+
/** @description The same for `canopy:roles.manage`, a key no role carries yet; always empty */
|
|
3209
|
+
roles_roots: components["schemas"]["OrganizationAuthorityRootDto"][];
|
|
3210
|
+
/** @description Whether the Environment's schema allows nodes beneath an organization; false in a flat Environment, where the organization is its only node */
|
|
3211
|
+
has_hierarchy: boolean;
|
|
3212
|
+
};
|
|
3213
|
+
RoleResponseDto: {
|
|
3214
|
+
id: string;
|
|
3215
|
+
application_id: string;
|
|
3216
|
+
name: string;
|
|
3217
|
+
description?: string | null;
|
|
3218
|
+
is_system_role: boolean;
|
|
3219
|
+
system_key?: string | null;
|
|
3220
|
+
is_active: boolean;
|
|
3221
|
+
/** Format: date-time */
|
|
3222
|
+
created_at: string;
|
|
3223
|
+
/** Format: date-time */
|
|
3224
|
+
updated_at: string;
|
|
3225
|
+
/** @description Optimistic-lock version. Send back as the `If-Match` header when updating to detect concurrent edits. */
|
|
3226
|
+
version: number;
|
|
3227
|
+
/** @description Number of permissions currently assigned to this role. Populated on list responses; omitted on single-role responses where the join isn't computed. */
|
|
3228
|
+
permission_count?: number;
|
|
3229
|
+
/** @description Number of distinct identities assigned this role. Populated on list responses; omitted on single-role responses where the join isn't computed. */
|
|
3230
|
+
member_count?: number;
|
|
3231
|
+
};
|
|
3232
|
+
OrganizationMemberCandidateResponseDto: {
|
|
3233
|
+
identity: components["schemas"]["AssignmentIdentityDto"];
|
|
3234
|
+
};
|
|
3235
|
+
CreateOrganizationAssignmentDto: {
|
|
3236
|
+
/** @description A member of the organization */
|
|
3237
|
+
identity_id: string;
|
|
3238
|
+
/** @description The organization node, or a node beneath it; the identity must be an active member of the organization */
|
|
3239
|
+
node_id: string;
|
|
3240
|
+
/** @description An active, assignable role of the Environment */
|
|
3241
|
+
role_id: string;
|
|
3242
|
+
/** @description When the grant starts (ISO 8601); now when omitted */
|
|
3243
|
+
effective_from?: Record<string, unknown>;
|
|
3244
|
+
/** @description When the grant ends (ISO 8601); never when omitted */
|
|
3245
|
+
effective_to?: Record<string, unknown>;
|
|
3246
|
+
};
|
|
3247
|
+
UpdateAssignmentDto: {
|
|
3248
|
+
role_id: string;
|
|
3249
|
+
effective_from?: string | null;
|
|
3250
|
+
effective_to?: string | null;
|
|
3251
|
+
};
|
|
2984
3252
|
OrganizationResponseDto: {
|
|
2985
3253
|
id: string;
|
|
2986
3254
|
name: string;
|
|
@@ -2990,7 +3258,7 @@ interface components {
|
|
|
2990
3258
|
metadata: Record<string, unknown>;
|
|
2991
3259
|
/** @description Your own id for this organization, unique per Environment. */
|
|
2992
3260
|
external_id?: string | null;
|
|
2993
|
-
/** @description
|
|
3261
|
+
/** @description Active members of this organization, whatever roles they hold. */
|
|
2994
3262
|
member_count: number;
|
|
2995
3263
|
/** @description Unexpired, unaccepted, unrevoked invitations. */
|
|
2996
3264
|
pending_invite_count: number;
|
|
@@ -3181,38 +3449,52 @@ interface components {
|
|
|
3181
3449
|
name: string;
|
|
3182
3450
|
node_type: string;
|
|
3183
3451
|
};
|
|
3184
|
-
|
|
3452
|
+
OrganizationMemberAssignmentDto: {
|
|
3185
3453
|
/** @description The assignment id. */
|
|
3186
3454
|
id: string;
|
|
3187
|
-
application_node: components["schemas"]["OrganizationMemberNodeDto"];
|
|
3188
|
-
role: components["schemas"]["OrganizationMemberRoleDto"];
|
|
3189
|
-
};
|
|
3190
|
-
OrganizationMemberResponseDto: {
|
|
3191
|
-
/** @description The membership (role assignment) id. */
|
|
3192
|
-
id: string;
|
|
3193
|
-
identity: components["schemas"]["OrganizationMemberIdentityDto"];
|
|
3194
3455
|
role: components["schemas"]["OrganizationMemberRoleDto"];
|
|
3456
|
+
node: components["schemas"]["OrganizationMemberNodeDto"];
|
|
3195
3457
|
/** Format: date-time */
|
|
3196
3458
|
effective_from?: string | null;
|
|
3197
3459
|
/** Format: date-time */
|
|
3198
3460
|
effective_to?: string | null;
|
|
3461
|
+
/** @description The assignment's version, for `If-Match` on a change. */
|
|
3462
|
+
version: number;
|
|
3463
|
+
};
|
|
3464
|
+
OrganizationMemberResponseDto: {
|
|
3465
|
+
/** @description The membership id. */
|
|
3466
|
+
id: string;
|
|
3467
|
+
identity: components["schemas"]["OrganizationMemberIdentityDto"];
|
|
3468
|
+
/**
|
|
3469
|
+
* @description `active` while the identity belongs; `deactivated` once removed, kept for the organization's history.
|
|
3470
|
+
* @enum {string}
|
|
3471
|
+
*/
|
|
3472
|
+
status: "active" | "deactivated";
|
|
3473
|
+
/**
|
|
3474
|
+
* @description How the membership began: added by an administrator, an accepted invitation, single sign-on, directory sync, or the organization's own creation on sign-up.
|
|
3475
|
+
* @enum {string}
|
|
3476
|
+
*/
|
|
3477
|
+
source: "added" | "invitation" | "sso" | "directory_sync" | "signup";
|
|
3199
3478
|
/**
|
|
3200
3479
|
* Format: date-time
|
|
3201
|
-
* @description When the membership
|
|
3480
|
+
* @description When the current membership began.
|
|
3202
3481
|
*/
|
|
3203
|
-
|
|
3204
|
-
/**
|
|
3205
|
-
|
|
3482
|
+
joined_at: string;
|
|
3483
|
+
/**
|
|
3484
|
+
* Format: date-time
|
|
3485
|
+
* @description When the member was removed; null while active.
|
|
3486
|
+
*/
|
|
3487
|
+
deactivated_at?: string | null;
|
|
3488
|
+
/** @description Every role assignment the member holds in the organization, the organization node first, then beneath it. Empty for a member who holds none. */
|
|
3489
|
+
roles: components["schemas"]["OrganizationMemberAssignmentDto"][];
|
|
3490
|
+
/** @description The membership's version. */
|
|
3491
|
+
version: number;
|
|
3206
3492
|
};
|
|
3207
3493
|
AddOrganizationMemberDto: {
|
|
3208
3494
|
/** @description Identity to add. Must already hold an active membership in this Environment; invite by email instead for someone who does not. */
|
|
3209
3495
|
identity_id: string;
|
|
3210
|
-
/** @description
|
|
3211
|
-
role_id
|
|
3212
|
-
};
|
|
3213
|
-
ChangeOrganizationMemberRoleDto: {
|
|
3214
|
-
/** @description The replacement role. A member holds exactly one role per organization, so this updates the existing membership in place. */
|
|
3215
|
-
role_id: string;
|
|
3496
|
+
/** @description A role to hold at the organization node from the start, from the Environment's roles. Left out, the member belongs and holds nothing until a role is assigned. */
|
|
3497
|
+
role_id?: string;
|
|
3216
3498
|
};
|
|
3217
3499
|
CreateOrganizationInviteDto: {
|
|
3218
3500
|
/** @description Email to invite. Works for people with no identity in this Environment — one is created when they accept. */
|
|
@@ -3227,7 +3509,7 @@ interface components {
|
|
|
3227
3509
|
*/
|
|
3228
3510
|
send_email: boolean;
|
|
3229
3511
|
};
|
|
3230
|
-
|
|
3512
|
+
OrganizationRoleResponseDto: {
|
|
3231
3513
|
id: string;
|
|
3232
3514
|
application_id: string;
|
|
3233
3515
|
name: string;
|
|
@@ -3245,6 +3527,8 @@ interface components {
|
|
|
3245
3527
|
permission_count?: number;
|
|
3246
3528
|
/** @description Number of distinct identities assigned this role. Populated on list responses; omitted on single-role responses where the join isn't computed. */
|
|
3247
3529
|
member_count?: number;
|
|
3530
|
+
/** @description Whether the caller may grant this role at the organization node under the grant ceiling: for an identity, it holds every permission the role carries there; always true for the developer's key and Console users */
|
|
3531
|
+
grantable: boolean;
|
|
3248
3532
|
};
|
|
3249
3533
|
SsoConnectionTestSummaryDto: {
|
|
3250
3534
|
test_id: string;
|
|
@@ -3554,11 +3838,6 @@ interface components {
|
|
|
3554
3838
|
effective_from?: string;
|
|
3555
3839
|
effective_to?: string;
|
|
3556
3840
|
};
|
|
3557
|
-
UpdateAssignmentDto: {
|
|
3558
|
-
role_id: string;
|
|
3559
|
-
effective_from?: string | null;
|
|
3560
|
-
effective_to?: string | null;
|
|
3561
|
-
};
|
|
3562
3841
|
BulkRemoveAssignmentsDto: {
|
|
3563
3842
|
assignment_ids: string[];
|
|
3564
3843
|
};
|
|
@@ -4999,16 +5278,21 @@ interface components {
|
|
|
4999
5278
|
* @description The identity that joined.
|
|
5000
5279
|
*/
|
|
5001
5280
|
identity_id: string;
|
|
5281
|
+
/** @description Your own identifier for the organization, when you set one. */
|
|
5282
|
+
external_id?: string | null;
|
|
5002
5283
|
/**
|
|
5003
5284
|
* Format: uuid
|
|
5004
|
-
* @description The
|
|
5285
|
+
* @description The membership record.
|
|
5005
5286
|
*/
|
|
5006
|
-
|
|
5007
|
-
/**
|
|
5008
|
-
|
|
5287
|
+
membership_id?: string;
|
|
5288
|
+
/**
|
|
5289
|
+
* Format: uuid
|
|
5290
|
+
* @description The role given at the organization node on joining, when one was.
|
|
5291
|
+
*/
|
|
5292
|
+
role_id?: string;
|
|
5009
5293
|
/**
|
|
5010
5294
|
* Format: uuid
|
|
5011
|
-
* @description
|
|
5295
|
+
* @description That role's assignment, when a role was given.
|
|
5012
5296
|
*/
|
|
5013
5297
|
assignment_id?: string;
|
|
5014
5298
|
/**
|
|
@@ -5030,7 +5314,7 @@ interface components {
|
|
|
5030
5314
|
* @description How the member joined, when it was not added directly.
|
|
5031
5315
|
* @enum {string}
|
|
5032
5316
|
*/
|
|
5033
|
-
source?: "sso_jit" | "invite" | "scim";
|
|
5317
|
+
source?: "sso_jit" | "invite" | "scim" | "self_signup";
|
|
5034
5318
|
};
|
|
5035
5319
|
};
|
|
5036
5320
|
};
|
|
@@ -5087,13 +5371,13 @@ interface components {
|
|
|
5087
5371
|
* @description The identity removed.
|
|
5088
5372
|
*/
|
|
5089
5373
|
identity_id: string;
|
|
5374
|
+
/** @description Role assignments it held at the organization's nodes, removed with the membership. */
|
|
5375
|
+
assignments_removed: number;
|
|
5090
5376
|
/**
|
|
5091
5377
|
* Format: uuid
|
|
5092
|
-
* @description The
|
|
5378
|
+
* @description The membership record, now deactivated.
|
|
5093
5379
|
*/
|
|
5094
|
-
|
|
5095
|
-
/** @description Grants it held beneath the organization, removed with the membership. */
|
|
5096
|
-
scoped_assignments_removed: number;
|
|
5380
|
+
membership_id?: string;
|
|
5097
5381
|
/**
|
|
5098
5382
|
* @description Set when directory sync made the change rather than somebody directly.
|
|
5099
5383
|
* @enum {string}
|
|
@@ -5541,8 +5825,7 @@ interface operations {
|
|
|
5541
5825
|
ApiPermissionsController_deletePermission: {
|
|
5542
5826
|
parameters: {
|
|
5543
5827
|
query?: never;
|
|
5544
|
-
header
|
|
5545
|
-
"if-match": string;
|
|
5828
|
+
header?: {
|
|
5546
5829
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
5547
5830
|
"If-Match"?: string;
|
|
5548
5831
|
};
|
|
@@ -5670,8 +5953,7 @@ interface operations {
|
|
|
5670
5953
|
ApiPermissionsController_updatePermission: {
|
|
5671
5954
|
parameters: {
|
|
5672
5955
|
query?: never;
|
|
5673
|
-
header
|
|
5674
|
-
"if-match": string;
|
|
5956
|
+
header?: {
|
|
5675
5957
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
5676
5958
|
"If-Match"?: string;
|
|
5677
5959
|
};
|
|
@@ -8358,7 +8640,10 @@ interface operations {
|
|
|
8358
8640
|
};
|
|
8359
8641
|
ApiIdentitiesController_getIdentityPermissions: {
|
|
8360
8642
|
parameters: {
|
|
8361
|
-
query?:
|
|
8643
|
+
query?: {
|
|
8644
|
+
/** @description Answer at this node: the permissions granted by assignments on its lineage. Omit for the Application-wide answer. */
|
|
8645
|
+
node_id?: string;
|
|
8646
|
+
};
|
|
8362
8647
|
header?: never;
|
|
8363
8648
|
path: {
|
|
8364
8649
|
id: string;
|
|
@@ -8464,13 +8749,13 @@ interface operations {
|
|
|
8464
8749
|
};
|
|
8465
8750
|
};
|
|
8466
8751
|
};
|
|
8467
|
-
|
|
8752
|
+
ApiIdentitiesController_getIdentityAccessibleNodes: {
|
|
8468
8753
|
parameters: {
|
|
8469
|
-
query
|
|
8470
|
-
/** @description
|
|
8471
|
-
|
|
8472
|
-
/** @description
|
|
8473
|
-
|
|
8754
|
+
query: {
|
|
8755
|
+
/** @description The permission to answer for, by key. */
|
|
8756
|
+
permission: string;
|
|
8757
|
+
/** @description The largest `nodes` set to return. Past it, `nodes` is null and `complete` false. */
|
|
8758
|
+
max_nodes?: number;
|
|
8474
8759
|
};
|
|
8475
8760
|
header?: never;
|
|
8476
8761
|
path: {
|
|
@@ -8480,15 +8765,130 @@ interface operations {
|
|
|
8480
8765
|
};
|
|
8481
8766
|
requestBody?: never;
|
|
8482
8767
|
responses: {
|
|
8483
|
-
/** @description
|
|
8768
|
+
/** @description The minimal grant roots for the permission, and the nodes beneath them up to the cap */
|
|
8484
8769
|
200: {
|
|
8485
8770
|
headers: {
|
|
8486
8771
|
[name: string]: unknown;
|
|
8487
8772
|
};
|
|
8488
8773
|
content: {
|
|
8489
8774
|
"application/json": {
|
|
8490
|
-
|
|
8491
|
-
|
|
8775
|
+
data: components["schemas"]["IdentityAccessibleNodesResponseDto"];
|
|
8776
|
+
};
|
|
8777
|
+
};
|
|
8778
|
+
};
|
|
8779
|
+
/** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
|
|
8780
|
+
400: {
|
|
8781
|
+
headers: {
|
|
8782
|
+
[name: string]: unknown;
|
|
8783
|
+
};
|
|
8784
|
+
content: {
|
|
8785
|
+
/**
|
|
8786
|
+
* @example {
|
|
8787
|
+
* "error": {
|
|
8788
|
+
* "statusCode": 400,
|
|
8789
|
+
* "code": null,
|
|
8790
|
+
* "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
|
|
8791
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
8792
|
+
* "path": "/api/v1/identities/{id}/accessible-nodes",
|
|
8793
|
+
* "method": "GET"
|
|
8794
|
+
* }
|
|
8795
|
+
* }
|
|
8796
|
+
*/
|
|
8797
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
8798
|
+
};
|
|
8799
|
+
};
|
|
8800
|
+
/** @description Invalid or expired token */
|
|
8801
|
+
401: {
|
|
8802
|
+
headers: {
|
|
8803
|
+
[name: string]: unknown;
|
|
8804
|
+
};
|
|
8805
|
+
content: {
|
|
8806
|
+
/**
|
|
8807
|
+
* @example {
|
|
8808
|
+
* "error": {
|
|
8809
|
+
* "statusCode": 401,
|
|
8810
|
+
* "code": null,
|
|
8811
|
+
* "message": "Invalid or expired token",
|
|
8812
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
8813
|
+
* "path": "/api/v1/identities",
|
|
8814
|
+
* "method": "GET"
|
|
8815
|
+
* }
|
|
8816
|
+
* }
|
|
8817
|
+
*/
|
|
8818
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
8819
|
+
};
|
|
8820
|
+
};
|
|
8821
|
+
/** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
|
|
8822
|
+
403: {
|
|
8823
|
+
headers: {
|
|
8824
|
+
[name: string]: unknown;
|
|
8825
|
+
};
|
|
8826
|
+
content: {
|
|
8827
|
+
/**
|
|
8828
|
+
* @example {
|
|
8829
|
+
* "error": {
|
|
8830
|
+
* "statusCode": 403,
|
|
8831
|
+
* "code": null,
|
|
8832
|
+
* "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
|
|
8833
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
8834
|
+
* "path": "/api/v1/identities",
|
|
8835
|
+
* "method": "GET"
|
|
8836
|
+
* }
|
|
8837
|
+
* }
|
|
8838
|
+
*/
|
|
8839
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
8840
|
+
};
|
|
8841
|
+
};
|
|
8842
|
+
/** @description No identity with that id has a membership in this Environment */
|
|
8843
|
+
404: {
|
|
8844
|
+
headers: {
|
|
8845
|
+
[name: string]: unknown;
|
|
8846
|
+
};
|
|
8847
|
+
content: {
|
|
8848
|
+
/**
|
|
8849
|
+
* @example {
|
|
8850
|
+
* "error": {
|
|
8851
|
+
* "statusCode": 404,
|
|
8852
|
+
* "code": null,
|
|
8853
|
+
* "message": "No identity with that id has a membership in this Environment",
|
|
8854
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
8855
|
+
* "path": "/api/v1/identities/{id}/accessible-nodes",
|
|
8856
|
+
* "method": "GET"
|
|
8857
|
+
* }
|
|
8858
|
+
* }
|
|
8859
|
+
*/
|
|
8860
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
8861
|
+
};
|
|
8862
|
+
};
|
|
8863
|
+
};
|
|
8864
|
+
};
|
|
8865
|
+
ApiIdentitiesController_getIdentityGrants: {
|
|
8866
|
+
parameters: {
|
|
8867
|
+
query?: {
|
|
8868
|
+
/** @description Page number (1-based) */
|
|
8869
|
+
page?: number;
|
|
8870
|
+
/** @description Items per page (1-100, default 20) */
|
|
8871
|
+
take?: number;
|
|
8872
|
+
/** @description `windows` adds `effective_from` and `effective_to` to every row and includes assignments outside their window, so the caller applies the window itself. */
|
|
8873
|
+
include?: "windows";
|
|
8874
|
+
};
|
|
8875
|
+
header?: never;
|
|
8876
|
+
path: {
|
|
8877
|
+
id: string;
|
|
8878
|
+
};
|
|
8879
|
+
cookie?: never;
|
|
8880
|
+
};
|
|
8881
|
+
requestBody?: never;
|
|
8882
|
+
responses: {
|
|
8883
|
+
/** @description One page of grant roots, one row per permission and node, ordered by permission then node */
|
|
8884
|
+
200: {
|
|
8885
|
+
headers: {
|
|
8886
|
+
[name: string]: unknown;
|
|
8887
|
+
};
|
|
8888
|
+
content: {
|
|
8889
|
+
"application/json": {
|
|
8890
|
+
/** @description The version of the authorization model these rows describe. A client that evaluates from them refuses a version it does not know rather than guessing. */
|
|
8891
|
+
model_version: number;
|
|
8492
8892
|
items: components["schemas"]["IdentityGrantResponseDto"][];
|
|
8493
8893
|
pagination: components["schemas"]["PageMetaDto"];
|
|
8494
8894
|
};
|
|
@@ -9683,8 +10083,7 @@ interface operations {
|
|
|
9683
10083
|
ApiNodesController_deleteNode: {
|
|
9684
10084
|
parameters: {
|
|
9685
10085
|
query?: never;
|
|
9686
|
-
header
|
|
9687
|
-
"if-match": string;
|
|
10086
|
+
header?: {
|
|
9688
10087
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
9689
10088
|
"If-Match"?: string;
|
|
9690
10089
|
};
|
|
@@ -9812,8 +10211,7 @@ interface operations {
|
|
|
9812
10211
|
ApiNodesController_updateNode: {
|
|
9813
10212
|
parameters: {
|
|
9814
10213
|
query?: never;
|
|
9815
|
-
header
|
|
9816
|
-
"if-match": string;
|
|
10214
|
+
header?: {
|
|
9817
10215
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
9818
10216
|
"If-Match"?: string;
|
|
9819
10217
|
};
|
|
@@ -10234,8 +10632,7 @@ interface operations {
|
|
|
10234
10632
|
ApiNodesController_moveNode: {
|
|
10235
10633
|
parameters: {
|
|
10236
10634
|
query?: never;
|
|
10237
|
-
header
|
|
10238
|
-
"if-match": string;
|
|
10635
|
+
header?: {
|
|
10239
10636
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
10240
10637
|
"If-Match"?: string;
|
|
10241
10638
|
};
|
|
@@ -10539,8 +10936,1100 @@ interface operations {
|
|
|
10539
10936
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
10540
10937
|
};
|
|
10541
10938
|
};
|
|
10542
|
-
/** @description Invalid or expired token */
|
|
10543
|
-
401: {
|
|
10939
|
+
/** @description Invalid or expired token */
|
|
10940
|
+
401: {
|
|
10941
|
+
headers: {
|
|
10942
|
+
[name: string]: unknown;
|
|
10943
|
+
};
|
|
10944
|
+
content: {
|
|
10945
|
+
/**
|
|
10946
|
+
* @example {
|
|
10947
|
+
* "error": {
|
|
10948
|
+
* "statusCode": 401,
|
|
10949
|
+
* "code": null,
|
|
10950
|
+
* "message": "Invalid or expired token",
|
|
10951
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
10952
|
+
* "path": "/api/v1/nodes",
|
|
10953
|
+
* "method": "GET"
|
|
10954
|
+
* }
|
|
10955
|
+
* }
|
|
10956
|
+
*/
|
|
10957
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
10958
|
+
};
|
|
10959
|
+
};
|
|
10960
|
+
/** @description The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment */
|
|
10961
|
+
403: {
|
|
10962
|
+
headers: {
|
|
10963
|
+
[name: string]: unknown;
|
|
10964
|
+
};
|
|
10965
|
+
content: {
|
|
10966
|
+
/**
|
|
10967
|
+
* @example {
|
|
10968
|
+
* "error": {
|
|
10969
|
+
* "statusCode": 403,
|
|
10970
|
+
* "code": null,
|
|
10971
|
+
* "message": "The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment",
|
|
10972
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
10973
|
+
* "path": "/api/v1/nodes",
|
|
10974
|
+
* "method": "GET"
|
|
10975
|
+
* }
|
|
10976
|
+
* }
|
|
10977
|
+
*/
|
|
10978
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
10979
|
+
};
|
|
10980
|
+
};
|
|
10981
|
+
/** @description Node not found */
|
|
10982
|
+
404: {
|
|
10983
|
+
headers: {
|
|
10984
|
+
[name: string]: unknown;
|
|
10985
|
+
};
|
|
10986
|
+
content: {
|
|
10987
|
+
/**
|
|
10988
|
+
* @example {
|
|
10989
|
+
* "error": {
|
|
10990
|
+
* "statusCode": 404,
|
|
10991
|
+
* "code": null,
|
|
10992
|
+
* "message": "Node not found",
|
|
10993
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
10994
|
+
* "path": "/api/v1/nodes/{id}/identities/summary",
|
|
10995
|
+
* "method": "GET"
|
|
10996
|
+
* }
|
|
10997
|
+
* }
|
|
10998
|
+
*/
|
|
10999
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11000
|
+
};
|
|
11001
|
+
};
|
|
11002
|
+
};
|
|
11003
|
+
};
|
|
11004
|
+
ApiOrganizationAccessController_me: {
|
|
11005
|
+
parameters: {
|
|
11006
|
+
query?: never;
|
|
11007
|
+
header?: never;
|
|
11008
|
+
path: {
|
|
11009
|
+
id: string;
|
|
11010
|
+
};
|
|
11011
|
+
cookie?: never;
|
|
11012
|
+
};
|
|
11013
|
+
requestBody?: never;
|
|
11014
|
+
responses: {
|
|
11015
|
+
/** @description The caller's authority in the organization */
|
|
11016
|
+
200: {
|
|
11017
|
+
headers: {
|
|
11018
|
+
[name: string]: unknown;
|
|
11019
|
+
};
|
|
11020
|
+
content: {
|
|
11021
|
+
"application/json": {
|
|
11022
|
+
data: components["schemas"]["OrganizationMeResponseDto"];
|
|
11023
|
+
};
|
|
11024
|
+
};
|
|
11025
|
+
};
|
|
11026
|
+
/** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
|
|
11027
|
+
400: {
|
|
11028
|
+
headers: {
|
|
11029
|
+
[name: string]: unknown;
|
|
11030
|
+
};
|
|
11031
|
+
content: {
|
|
11032
|
+
/**
|
|
11033
|
+
* @example {
|
|
11034
|
+
* "error": {
|
|
11035
|
+
* "statusCode": 400,
|
|
11036
|
+
* "code": null,
|
|
11037
|
+
* "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
|
|
11038
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11039
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11040
|
+
* "method": "GET"
|
|
11041
|
+
* }
|
|
11042
|
+
* }
|
|
11043
|
+
*/
|
|
11044
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11045
|
+
};
|
|
11046
|
+
};
|
|
11047
|
+
/** @description Invalid or expired token */
|
|
11048
|
+
401: {
|
|
11049
|
+
headers: {
|
|
11050
|
+
[name: string]: unknown;
|
|
11051
|
+
};
|
|
11052
|
+
content: {
|
|
11053
|
+
/**
|
|
11054
|
+
* @example {
|
|
11055
|
+
* "error": {
|
|
11056
|
+
* "statusCode": 401,
|
|
11057
|
+
* "code": null,
|
|
11058
|
+
* "message": "Invalid or expired token",
|
|
11059
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11060
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11061
|
+
* "method": "GET"
|
|
11062
|
+
* }
|
|
11063
|
+
* }
|
|
11064
|
+
*/
|
|
11065
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11066
|
+
};
|
|
11067
|
+
};
|
|
11068
|
+
/** @description The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token */
|
|
11069
|
+
403: {
|
|
11070
|
+
headers: {
|
|
11071
|
+
[name: string]: unknown;
|
|
11072
|
+
};
|
|
11073
|
+
content: {
|
|
11074
|
+
/**
|
|
11075
|
+
* @example {
|
|
11076
|
+
* "error": {
|
|
11077
|
+
* "statusCode": 403,
|
|
11078
|
+
* "code": null,
|
|
11079
|
+
* "message": "The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token",
|
|
11080
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11081
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11082
|
+
* "method": "GET"
|
|
11083
|
+
* }
|
|
11084
|
+
* }
|
|
11085
|
+
*/
|
|
11086
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11087
|
+
};
|
|
11088
|
+
};
|
|
11089
|
+
/** @description Organization not found */
|
|
11090
|
+
404: {
|
|
11091
|
+
headers: {
|
|
11092
|
+
[name: string]: unknown;
|
|
11093
|
+
};
|
|
11094
|
+
content: {
|
|
11095
|
+
/**
|
|
11096
|
+
* @example {
|
|
11097
|
+
* "error": {
|
|
11098
|
+
* "statusCode": 404,
|
|
11099
|
+
* "code": null,
|
|
11100
|
+
* "message": "Organization not found",
|
|
11101
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11102
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11103
|
+
* "method": "GET"
|
|
11104
|
+
* }
|
|
11105
|
+
* }
|
|
11106
|
+
*/
|
|
11107
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11108
|
+
};
|
|
11109
|
+
};
|
|
11110
|
+
};
|
|
11111
|
+
};
|
|
11112
|
+
ApiOrganizationAccessController_tree: {
|
|
11113
|
+
parameters: {
|
|
11114
|
+
query?: {
|
|
11115
|
+
/** @description Page number (1-based) */
|
|
11116
|
+
page?: number;
|
|
11117
|
+
/** @description Items per page (1-100, default 20) */
|
|
11118
|
+
take?: number;
|
|
11119
|
+
/** @description Search node names and slugs */
|
|
11120
|
+
q?: string;
|
|
11121
|
+
/** @description Sort column. Defaults to `created`, oldest first. */
|
|
11122
|
+
sort_by?: "name" | "created";
|
|
11123
|
+
/** @description Sort direction */
|
|
11124
|
+
order?: "asc" | "desc";
|
|
11125
|
+
};
|
|
11126
|
+
header?: never;
|
|
11127
|
+
path: {
|
|
11128
|
+
id: string;
|
|
11129
|
+
};
|
|
11130
|
+
cookie?: never;
|
|
11131
|
+
};
|
|
11132
|
+
requestBody?: never;
|
|
11133
|
+
responses: {
|
|
11134
|
+
/** @description Nodes returned */
|
|
11135
|
+
200: {
|
|
11136
|
+
headers: {
|
|
11137
|
+
[name: string]: unknown;
|
|
11138
|
+
};
|
|
11139
|
+
content: {
|
|
11140
|
+
"application/json": {
|
|
11141
|
+
items: components["schemas"]["ScopedNodeResponseDto"][];
|
|
11142
|
+
pagination: components["schemas"]["PageMetaDto"];
|
|
11143
|
+
};
|
|
11144
|
+
};
|
|
11145
|
+
};
|
|
11146
|
+
/** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
|
|
11147
|
+
400: {
|
|
11148
|
+
headers: {
|
|
11149
|
+
[name: string]: unknown;
|
|
11150
|
+
};
|
|
11151
|
+
content: {
|
|
11152
|
+
/**
|
|
11153
|
+
* @example {
|
|
11154
|
+
* "error": {
|
|
11155
|
+
* "statusCode": 400,
|
|
11156
|
+
* "code": null,
|
|
11157
|
+
* "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
|
|
11158
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11159
|
+
* "path": "/api/v1/organizations/{id}/tree",
|
|
11160
|
+
* "method": "GET"
|
|
11161
|
+
* }
|
|
11162
|
+
* }
|
|
11163
|
+
*/
|
|
11164
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11165
|
+
};
|
|
11166
|
+
};
|
|
11167
|
+
/** @description Invalid or expired token */
|
|
11168
|
+
401: {
|
|
11169
|
+
headers: {
|
|
11170
|
+
[name: string]: unknown;
|
|
11171
|
+
};
|
|
11172
|
+
content: {
|
|
11173
|
+
/**
|
|
11174
|
+
* @example {
|
|
11175
|
+
* "error": {
|
|
11176
|
+
* "statusCode": 401,
|
|
11177
|
+
* "code": null,
|
|
11178
|
+
* "message": "Invalid or expired token",
|
|
11179
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11180
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11181
|
+
* "method": "GET"
|
|
11182
|
+
* }
|
|
11183
|
+
* }
|
|
11184
|
+
*/
|
|
11185
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11186
|
+
};
|
|
11187
|
+
};
|
|
11188
|
+
/** @description The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token */
|
|
11189
|
+
403: {
|
|
11190
|
+
headers: {
|
|
11191
|
+
[name: string]: unknown;
|
|
11192
|
+
};
|
|
11193
|
+
content: {
|
|
11194
|
+
/**
|
|
11195
|
+
* @example {
|
|
11196
|
+
* "error": {
|
|
11197
|
+
* "statusCode": 403,
|
|
11198
|
+
* "code": null,
|
|
11199
|
+
* "message": "The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token",
|
|
11200
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11201
|
+
* "path": "/api/v1/organizations/{id}/tree",
|
|
11202
|
+
* "method": "GET"
|
|
11203
|
+
* }
|
|
11204
|
+
* }
|
|
11205
|
+
*/
|
|
11206
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11207
|
+
};
|
|
11208
|
+
};
|
|
11209
|
+
/** @description Organization not found */
|
|
11210
|
+
404: {
|
|
11211
|
+
headers: {
|
|
11212
|
+
[name: string]: unknown;
|
|
11213
|
+
};
|
|
11214
|
+
content: {
|
|
11215
|
+
/**
|
|
11216
|
+
* @example {
|
|
11217
|
+
* "error": {
|
|
11218
|
+
* "statusCode": 404,
|
|
11219
|
+
* "code": null,
|
|
11220
|
+
* "message": "Organization not found",
|
|
11221
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11222
|
+
* "path": "/api/v1/organizations/{id}/tree",
|
|
11223
|
+
* "method": "GET"
|
|
11224
|
+
* }
|
|
11225
|
+
* }
|
|
11226
|
+
*/
|
|
11227
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11228
|
+
};
|
|
11229
|
+
};
|
|
11230
|
+
};
|
|
11231
|
+
};
|
|
11232
|
+
ApiOrganizationAccessController_listAccess: {
|
|
11233
|
+
parameters: {
|
|
11234
|
+
query?: {
|
|
11235
|
+
/** @description Page number (1-based) */
|
|
11236
|
+
page?: number;
|
|
11237
|
+
/** @description Items per page (1-100, default 20) */
|
|
11238
|
+
take?: number;
|
|
11239
|
+
/** @description Search term */
|
|
11240
|
+
q?: string;
|
|
11241
|
+
/** @description Sort field */
|
|
11242
|
+
sort_by?: "name" | "role" | "access_type" | "created_at";
|
|
11243
|
+
/** @description Sort order */
|
|
11244
|
+
order?: "asc" | "desc";
|
|
11245
|
+
/** @description Filter by role ID */
|
|
11246
|
+
role_id?: string;
|
|
11247
|
+
/** @description Filter by access type */
|
|
11248
|
+
access_type?: "direct" | "inherited";
|
|
11249
|
+
/** @description Filter by assignment status */
|
|
11250
|
+
status?: "active" | "scheduled" | "expired";
|
|
11251
|
+
/** @description Filter by source node ID */
|
|
11252
|
+
source_node_id?: string;
|
|
11253
|
+
};
|
|
11254
|
+
header?: never;
|
|
11255
|
+
path: {
|
|
11256
|
+
id: string;
|
|
11257
|
+
nodeId: string;
|
|
11258
|
+
};
|
|
11259
|
+
cookie?: never;
|
|
11260
|
+
};
|
|
11261
|
+
requestBody?: never;
|
|
11262
|
+
responses: {
|
|
11263
|
+
/** @description Assignments returned */
|
|
11264
|
+
200: {
|
|
11265
|
+
headers: {
|
|
11266
|
+
[name: string]: unknown;
|
|
11267
|
+
};
|
|
11268
|
+
content: {
|
|
11269
|
+
"application/json": {
|
|
11270
|
+
items: components["schemas"]["IdentityAssignmentRowDto"][];
|
|
11271
|
+
pagination: components["schemas"]["PageMetaDto"];
|
|
11272
|
+
};
|
|
11273
|
+
};
|
|
11274
|
+
};
|
|
11275
|
+
/** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
|
|
11276
|
+
400: {
|
|
11277
|
+
headers: {
|
|
11278
|
+
[name: string]: unknown;
|
|
11279
|
+
};
|
|
11280
|
+
content: {
|
|
11281
|
+
/**
|
|
11282
|
+
* @example {
|
|
11283
|
+
* "error": {
|
|
11284
|
+
* "statusCode": 400,
|
|
11285
|
+
* "code": null,
|
|
11286
|
+
* "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
|
|
11287
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11288
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
|
|
11289
|
+
* "method": "GET"
|
|
11290
|
+
* }
|
|
11291
|
+
* }
|
|
11292
|
+
*/
|
|
11293
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11294
|
+
};
|
|
11295
|
+
};
|
|
11296
|
+
/** @description Invalid or expired token */
|
|
11297
|
+
401: {
|
|
11298
|
+
headers: {
|
|
11299
|
+
[name: string]: unknown;
|
|
11300
|
+
};
|
|
11301
|
+
content: {
|
|
11302
|
+
/**
|
|
11303
|
+
* @example {
|
|
11304
|
+
* "error": {
|
|
11305
|
+
* "statusCode": 401,
|
|
11306
|
+
* "code": null,
|
|
11307
|
+
* "message": "Invalid or expired token",
|
|
11308
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11309
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11310
|
+
* "method": "GET"
|
|
11311
|
+
* }
|
|
11312
|
+
* }
|
|
11313
|
+
*/
|
|
11314
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11315
|
+
};
|
|
11316
|
+
};
|
|
11317
|
+
/** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
|
|
11318
|
+
403: {
|
|
11319
|
+
headers: {
|
|
11320
|
+
[name: string]: unknown;
|
|
11321
|
+
};
|
|
11322
|
+
content: {
|
|
11323
|
+
/**
|
|
11324
|
+
* @example {
|
|
11325
|
+
* "error": {
|
|
11326
|
+
* "statusCode": 403,
|
|
11327
|
+
* "code": null,
|
|
11328
|
+
* "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
|
|
11329
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11330
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
|
|
11331
|
+
* "method": "GET"
|
|
11332
|
+
* }
|
|
11333
|
+
* }
|
|
11334
|
+
*/
|
|
11335
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11336
|
+
};
|
|
11337
|
+
};
|
|
11338
|
+
/** @description The organization is not in this Environment, or the node is not inside it */
|
|
11339
|
+
404: {
|
|
11340
|
+
headers: {
|
|
11341
|
+
[name: string]: unknown;
|
|
11342
|
+
};
|
|
11343
|
+
content: {
|
|
11344
|
+
/**
|
|
11345
|
+
* @example {
|
|
11346
|
+
* "error": {
|
|
11347
|
+
* "statusCode": 404,
|
|
11348
|
+
* "code": null,
|
|
11349
|
+
* "message": "The organization is not in this Environment, or the node is not inside it",
|
|
11350
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11351
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
|
|
11352
|
+
* "method": "GET"
|
|
11353
|
+
* }
|
|
11354
|
+
* }
|
|
11355
|
+
*/
|
|
11356
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11357
|
+
};
|
|
11358
|
+
};
|
|
11359
|
+
};
|
|
11360
|
+
};
|
|
11361
|
+
ApiOrganizationAccessController_accessSummary: {
|
|
11362
|
+
parameters: {
|
|
11363
|
+
query?: never;
|
|
11364
|
+
header?: never;
|
|
11365
|
+
path: {
|
|
11366
|
+
id: string;
|
|
11367
|
+
nodeId: string;
|
|
11368
|
+
};
|
|
11369
|
+
cookie?: never;
|
|
11370
|
+
};
|
|
11371
|
+
requestBody?: never;
|
|
11372
|
+
responses: {
|
|
11373
|
+
/** @description Summary returned */
|
|
11374
|
+
200: {
|
|
11375
|
+
headers: {
|
|
11376
|
+
[name: string]: unknown;
|
|
11377
|
+
};
|
|
11378
|
+
content: {
|
|
11379
|
+
"application/json": {
|
|
11380
|
+
data: components["schemas"]["NodeIdentitiesSummaryDto"];
|
|
11381
|
+
};
|
|
11382
|
+
};
|
|
11383
|
+
};
|
|
11384
|
+
/** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
|
|
11385
|
+
400: {
|
|
11386
|
+
headers: {
|
|
11387
|
+
[name: string]: unknown;
|
|
11388
|
+
};
|
|
11389
|
+
content: {
|
|
11390
|
+
/**
|
|
11391
|
+
* @example {
|
|
11392
|
+
* "error": {
|
|
11393
|
+
* "statusCode": 400,
|
|
11394
|
+
* "code": null,
|
|
11395
|
+
* "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
|
|
11396
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11397
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11398
|
+
* "method": "GET"
|
|
11399
|
+
* }
|
|
11400
|
+
* }
|
|
11401
|
+
*/
|
|
11402
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11403
|
+
};
|
|
11404
|
+
};
|
|
11405
|
+
/** @description Invalid or expired token */
|
|
11406
|
+
401: {
|
|
11407
|
+
headers: {
|
|
11408
|
+
[name: string]: unknown;
|
|
11409
|
+
};
|
|
11410
|
+
content: {
|
|
11411
|
+
/**
|
|
11412
|
+
* @example {
|
|
11413
|
+
* "error": {
|
|
11414
|
+
* "statusCode": 401,
|
|
11415
|
+
* "code": null,
|
|
11416
|
+
* "message": "Invalid or expired token",
|
|
11417
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11418
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11419
|
+
* "method": "GET"
|
|
11420
|
+
* }
|
|
11421
|
+
* }
|
|
11422
|
+
*/
|
|
11423
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11424
|
+
};
|
|
11425
|
+
};
|
|
11426
|
+
/** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
|
|
11427
|
+
403: {
|
|
11428
|
+
headers: {
|
|
11429
|
+
[name: string]: unknown;
|
|
11430
|
+
};
|
|
11431
|
+
content: {
|
|
11432
|
+
/**
|
|
11433
|
+
* @example {
|
|
11434
|
+
* "error": {
|
|
11435
|
+
* "statusCode": 403,
|
|
11436
|
+
* "code": null,
|
|
11437
|
+
* "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
|
|
11438
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11439
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
|
|
11440
|
+
* "method": "GET"
|
|
11441
|
+
* }
|
|
11442
|
+
* }
|
|
11443
|
+
*/
|
|
11444
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11445
|
+
};
|
|
11446
|
+
};
|
|
11447
|
+
/** @description The organization is not in this Environment, or the node is not inside it */
|
|
11448
|
+
404: {
|
|
11449
|
+
headers: {
|
|
11450
|
+
[name: string]: unknown;
|
|
11451
|
+
};
|
|
11452
|
+
content: {
|
|
11453
|
+
/**
|
|
11454
|
+
* @example {
|
|
11455
|
+
* "error": {
|
|
11456
|
+
* "statusCode": 404,
|
|
11457
|
+
* "code": null,
|
|
11458
|
+
* "message": "The organization is not in this Environment, or the node is not inside it",
|
|
11459
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11460
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access/summary",
|
|
11461
|
+
* "method": "GET"
|
|
11462
|
+
* }
|
|
11463
|
+
* }
|
|
11464
|
+
*/
|
|
11465
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11466
|
+
};
|
|
11467
|
+
};
|
|
11468
|
+
};
|
|
11469
|
+
};
|
|
11470
|
+
ApiOrganizationAccessController_grantableRoles: {
|
|
11471
|
+
parameters: {
|
|
11472
|
+
query?: never;
|
|
11473
|
+
header?: never;
|
|
11474
|
+
path: {
|
|
11475
|
+
id: string;
|
|
11476
|
+
nodeId: string;
|
|
11477
|
+
};
|
|
11478
|
+
cookie?: never;
|
|
11479
|
+
};
|
|
11480
|
+
requestBody?: never;
|
|
11481
|
+
responses: {
|
|
11482
|
+
/** @description Roles returned */
|
|
11483
|
+
200: {
|
|
11484
|
+
headers: {
|
|
11485
|
+
[name: string]: unknown;
|
|
11486
|
+
};
|
|
11487
|
+
content: {
|
|
11488
|
+
"application/json": {
|
|
11489
|
+
items: components["schemas"]["RoleResponseDto"][];
|
|
11490
|
+
};
|
|
11491
|
+
};
|
|
11492
|
+
};
|
|
11493
|
+
/** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
|
|
11494
|
+
400: {
|
|
11495
|
+
headers: {
|
|
11496
|
+
[name: string]: unknown;
|
|
11497
|
+
};
|
|
11498
|
+
content: {
|
|
11499
|
+
/**
|
|
11500
|
+
* @example {
|
|
11501
|
+
* "error": {
|
|
11502
|
+
* "statusCode": 400,
|
|
11503
|
+
* "code": null,
|
|
11504
|
+
* "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
|
|
11505
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11506
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11507
|
+
* "method": "GET"
|
|
11508
|
+
* }
|
|
11509
|
+
* }
|
|
11510
|
+
*/
|
|
11511
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11512
|
+
};
|
|
11513
|
+
};
|
|
11514
|
+
/** @description Invalid or expired token */
|
|
11515
|
+
401: {
|
|
11516
|
+
headers: {
|
|
11517
|
+
[name: string]: unknown;
|
|
11518
|
+
};
|
|
11519
|
+
content: {
|
|
11520
|
+
/**
|
|
11521
|
+
* @example {
|
|
11522
|
+
* "error": {
|
|
11523
|
+
* "statusCode": 401,
|
|
11524
|
+
* "code": null,
|
|
11525
|
+
* "message": "Invalid or expired token",
|
|
11526
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11527
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11528
|
+
* "method": "GET"
|
|
11529
|
+
* }
|
|
11530
|
+
* }
|
|
11531
|
+
*/
|
|
11532
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11533
|
+
};
|
|
11534
|
+
};
|
|
11535
|
+
/** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
|
|
11536
|
+
403: {
|
|
11537
|
+
headers: {
|
|
11538
|
+
[name: string]: unknown;
|
|
11539
|
+
};
|
|
11540
|
+
content: {
|
|
11541
|
+
/**
|
|
11542
|
+
* @example {
|
|
11543
|
+
* "error": {
|
|
11544
|
+
* "statusCode": 403,
|
|
11545
|
+
* "code": null,
|
|
11546
|
+
* "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
|
|
11547
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11548
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
|
|
11549
|
+
* "method": "GET"
|
|
11550
|
+
* }
|
|
11551
|
+
* }
|
|
11552
|
+
*/
|
|
11553
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11554
|
+
};
|
|
11555
|
+
};
|
|
11556
|
+
/** @description The organization is not in this Environment, or the node is not inside it */
|
|
11557
|
+
404: {
|
|
11558
|
+
headers: {
|
|
11559
|
+
[name: string]: unknown;
|
|
11560
|
+
};
|
|
11561
|
+
content: {
|
|
11562
|
+
/**
|
|
11563
|
+
* @example {
|
|
11564
|
+
* "error": {
|
|
11565
|
+
* "statusCode": 404,
|
|
11566
|
+
* "code": null,
|
|
11567
|
+
* "message": "The organization is not in this Environment, or the node is not inside it",
|
|
11568
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11569
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/grantable-roles",
|
|
11570
|
+
* "method": "GET"
|
|
11571
|
+
* }
|
|
11572
|
+
* }
|
|
11573
|
+
*/
|
|
11574
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11575
|
+
};
|
|
11576
|
+
};
|
|
11577
|
+
};
|
|
11578
|
+
};
|
|
11579
|
+
ApiOrganizationAccessController_listMembersAt: {
|
|
11580
|
+
parameters: {
|
|
11581
|
+
query?: {
|
|
11582
|
+
/** @description Page number (1-based) */
|
|
11583
|
+
page?: number;
|
|
11584
|
+
/** @description Items per page (1-100, default 20) */
|
|
11585
|
+
take?: number;
|
|
11586
|
+
/** @description Search member names and emails */
|
|
11587
|
+
q?: string;
|
|
11588
|
+
/** @description Sort column. Defaults to `joined`, longest-standing member first. */
|
|
11589
|
+
sort_by?: "name" | "email" | "joined";
|
|
11590
|
+
/** @description Sort direction */
|
|
11591
|
+
order?: "asc" | "desc";
|
|
11592
|
+
};
|
|
11593
|
+
header?: never;
|
|
11594
|
+
path: {
|
|
11595
|
+
id: string;
|
|
11596
|
+
nodeId: string;
|
|
11597
|
+
};
|
|
11598
|
+
cookie?: never;
|
|
11599
|
+
};
|
|
11600
|
+
requestBody?: never;
|
|
11601
|
+
responses: {
|
|
11602
|
+
/** @description Members returned */
|
|
11603
|
+
200: {
|
|
11604
|
+
headers: {
|
|
11605
|
+
[name: string]: unknown;
|
|
11606
|
+
};
|
|
11607
|
+
content: {
|
|
11608
|
+
"application/json": {
|
|
11609
|
+
items: components["schemas"]["OrganizationMemberCandidateResponseDto"][];
|
|
11610
|
+
pagination: components["schemas"]["PageMetaDto"];
|
|
11611
|
+
};
|
|
11612
|
+
};
|
|
11613
|
+
};
|
|
11614
|
+
/** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
|
|
11615
|
+
400: {
|
|
11616
|
+
headers: {
|
|
11617
|
+
[name: string]: unknown;
|
|
11618
|
+
};
|
|
11619
|
+
content: {
|
|
11620
|
+
/**
|
|
11621
|
+
* @example {
|
|
11622
|
+
* "error": {
|
|
11623
|
+
* "statusCode": 400,
|
|
11624
|
+
* "code": null,
|
|
11625
|
+
* "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
|
|
11626
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11627
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/members",
|
|
11628
|
+
* "method": "GET"
|
|
11629
|
+
* }
|
|
11630
|
+
* }
|
|
11631
|
+
*/
|
|
11632
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11633
|
+
};
|
|
11634
|
+
};
|
|
11635
|
+
/** @description Invalid or expired token */
|
|
11636
|
+
401: {
|
|
11637
|
+
headers: {
|
|
11638
|
+
[name: string]: unknown;
|
|
11639
|
+
};
|
|
11640
|
+
content: {
|
|
11641
|
+
/**
|
|
11642
|
+
* @example {
|
|
11643
|
+
* "error": {
|
|
11644
|
+
* "statusCode": 401,
|
|
11645
|
+
* "code": null,
|
|
11646
|
+
* "message": "Invalid or expired token",
|
|
11647
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11648
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11649
|
+
* "method": "GET"
|
|
11650
|
+
* }
|
|
11651
|
+
* }
|
|
11652
|
+
*/
|
|
11653
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11654
|
+
};
|
|
11655
|
+
};
|
|
11656
|
+
/** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
|
|
11657
|
+
403: {
|
|
11658
|
+
headers: {
|
|
11659
|
+
[name: string]: unknown;
|
|
11660
|
+
};
|
|
11661
|
+
content: {
|
|
11662
|
+
/**
|
|
11663
|
+
* @example {
|
|
11664
|
+
* "error": {
|
|
11665
|
+
* "statusCode": 403,
|
|
11666
|
+
* "code": null,
|
|
11667
|
+
* "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
|
|
11668
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11669
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
|
|
11670
|
+
* "method": "GET"
|
|
11671
|
+
* }
|
|
11672
|
+
* }
|
|
11673
|
+
*/
|
|
11674
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11675
|
+
};
|
|
11676
|
+
};
|
|
11677
|
+
/** @description The organization is not in this Environment, or the node is not inside it */
|
|
11678
|
+
404: {
|
|
11679
|
+
headers: {
|
|
11680
|
+
[name: string]: unknown;
|
|
11681
|
+
};
|
|
11682
|
+
content: {
|
|
11683
|
+
/**
|
|
11684
|
+
* @example {
|
|
11685
|
+
* "error": {
|
|
11686
|
+
* "statusCode": 404,
|
|
11687
|
+
* "code": null,
|
|
11688
|
+
* "message": "The organization is not in this Environment, or the node is not inside it",
|
|
11689
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11690
|
+
* "path": "/api/v1/organizations/{id}/nodes/{nodeId}/members",
|
|
11691
|
+
* "method": "GET"
|
|
11692
|
+
* }
|
|
11693
|
+
* }
|
|
11694
|
+
*/
|
|
11695
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11696
|
+
};
|
|
11697
|
+
};
|
|
11698
|
+
};
|
|
11699
|
+
};
|
|
11700
|
+
ApiOrganizationAccessController_createAssignment: {
|
|
11701
|
+
parameters: {
|
|
11702
|
+
query?: never;
|
|
11703
|
+
header?: never;
|
|
11704
|
+
path: {
|
|
11705
|
+
id: string;
|
|
11706
|
+
};
|
|
11707
|
+
cookie?: never;
|
|
11708
|
+
};
|
|
11709
|
+
requestBody: {
|
|
11710
|
+
content: {
|
|
11711
|
+
"application/json": components["schemas"]["CreateOrganizationAssignmentDto"];
|
|
11712
|
+
};
|
|
11713
|
+
};
|
|
11714
|
+
responses: {
|
|
11715
|
+
/** @description Assignment created */
|
|
11716
|
+
201: {
|
|
11717
|
+
headers: {
|
|
11718
|
+
[name: string]: unknown;
|
|
11719
|
+
};
|
|
11720
|
+
content: {
|
|
11721
|
+
"application/json": {
|
|
11722
|
+
data: components["schemas"]["AssignmentResponseDto"];
|
|
11723
|
+
};
|
|
11724
|
+
};
|
|
11725
|
+
};
|
|
11726
|
+
/** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
|
|
11727
|
+
400: {
|
|
11728
|
+
headers: {
|
|
11729
|
+
[name: string]: unknown;
|
|
11730
|
+
};
|
|
11731
|
+
content: {
|
|
11732
|
+
/**
|
|
11733
|
+
* @example {
|
|
11734
|
+
* "error": {
|
|
11735
|
+
* "statusCode": 400,
|
|
11736
|
+
* "code": null,
|
|
11737
|
+
* "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
|
|
11738
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11739
|
+
* "path": "/api/v1/organizations/{id}/assignments",
|
|
11740
|
+
* "method": "POST"
|
|
11741
|
+
* }
|
|
11742
|
+
* }
|
|
11743
|
+
*/
|
|
11744
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11745
|
+
};
|
|
11746
|
+
};
|
|
11747
|
+
/** @description Invalid or expired token */
|
|
11748
|
+
401: {
|
|
11749
|
+
headers: {
|
|
11750
|
+
[name: string]: unknown;
|
|
11751
|
+
};
|
|
11752
|
+
content: {
|
|
11753
|
+
/**
|
|
11754
|
+
* @example {
|
|
11755
|
+
* "error": {
|
|
11756
|
+
* "statusCode": 401,
|
|
11757
|
+
* "code": null,
|
|
11758
|
+
* "message": "Invalid or expired token",
|
|
11759
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11760
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11761
|
+
* "method": "GET"
|
|
11762
|
+
* }
|
|
11763
|
+
* }
|
|
11764
|
+
*/
|
|
11765
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11766
|
+
};
|
|
11767
|
+
};
|
|
11768
|
+
/** @description The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`) */
|
|
11769
|
+
403: {
|
|
11770
|
+
headers: {
|
|
11771
|
+
[name: string]: unknown;
|
|
11772
|
+
};
|
|
11773
|
+
content: {
|
|
11774
|
+
/**
|
|
11775
|
+
* @example {
|
|
11776
|
+
* "error": {
|
|
11777
|
+
* "statusCode": 403,
|
|
11778
|
+
* "code": null,
|
|
11779
|
+
* "message": "The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`)",
|
|
11780
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11781
|
+
* "path": "/api/v1/organizations/{id}/assignments",
|
|
11782
|
+
* "method": "POST"
|
|
11783
|
+
* }
|
|
11784
|
+
* }
|
|
11785
|
+
*/
|
|
11786
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11787
|
+
};
|
|
11788
|
+
};
|
|
11789
|
+
/** @description The organization is not in this Environment, or the node is not inside it */
|
|
11790
|
+
404: {
|
|
11791
|
+
headers: {
|
|
11792
|
+
[name: string]: unknown;
|
|
11793
|
+
};
|
|
11794
|
+
content: {
|
|
11795
|
+
/**
|
|
11796
|
+
* @example {
|
|
11797
|
+
* "error": {
|
|
11798
|
+
* "statusCode": 404,
|
|
11799
|
+
* "code": null,
|
|
11800
|
+
* "message": "The organization is not in this Environment, or the node is not inside it",
|
|
11801
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11802
|
+
* "path": "/api/v1/organizations/{id}/assignments",
|
|
11803
|
+
* "method": "POST"
|
|
11804
|
+
* }
|
|
11805
|
+
* }
|
|
11806
|
+
*/
|
|
11807
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11808
|
+
};
|
|
11809
|
+
};
|
|
11810
|
+
/** @description The identity already holds this role at this node, or is not a member of the organization (`organization.membership_required`) */
|
|
11811
|
+
409: {
|
|
11812
|
+
headers: {
|
|
11813
|
+
[name: string]: unknown;
|
|
11814
|
+
};
|
|
11815
|
+
content: {
|
|
11816
|
+
/**
|
|
11817
|
+
* @example {
|
|
11818
|
+
* "error": {
|
|
11819
|
+
* "statusCode": 409,
|
|
11820
|
+
* "code": null,
|
|
11821
|
+
* "message": "The identity already holds this role at this node, or is not a member of the organization (`organization.membership_required`)",
|
|
11822
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11823
|
+
* "path": "/api/v1/organizations/{id}/assignments",
|
|
11824
|
+
* "method": "POST"
|
|
11825
|
+
* }
|
|
11826
|
+
* }
|
|
11827
|
+
*/
|
|
11828
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11829
|
+
};
|
|
11830
|
+
};
|
|
11831
|
+
};
|
|
11832
|
+
};
|
|
11833
|
+
ApiOrganizationAccessController_removeAssignment: {
|
|
11834
|
+
parameters: {
|
|
11835
|
+
query?: never;
|
|
11836
|
+
header?: never;
|
|
11837
|
+
path: {
|
|
11838
|
+
id: string;
|
|
11839
|
+
assignmentId: string;
|
|
11840
|
+
};
|
|
11841
|
+
cookie?: never;
|
|
11842
|
+
};
|
|
11843
|
+
requestBody?: never;
|
|
11844
|
+
responses: {
|
|
11845
|
+
/** @description Assignment removed */
|
|
11846
|
+
204: {
|
|
11847
|
+
headers: {
|
|
11848
|
+
[name: string]: unknown;
|
|
11849
|
+
};
|
|
11850
|
+
content?: never;
|
|
11851
|
+
};
|
|
11852
|
+
/** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
|
|
11853
|
+
400: {
|
|
11854
|
+
headers: {
|
|
11855
|
+
[name: string]: unknown;
|
|
11856
|
+
};
|
|
11857
|
+
content: {
|
|
11858
|
+
/**
|
|
11859
|
+
* @example {
|
|
11860
|
+
* "error": {
|
|
11861
|
+
* "statusCode": 400,
|
|
11862
|
+
* "code": null,
|
|
11863
|
+
* "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
|
|
11864
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11865
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11866
|
+
* "method": "GET"
|
|
11867
|
+
* }
|
|
11868
|
+
* }
|
|
11869
|
+
*/
|
|
11870
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11871
|
+
};
|
|
11872
|
+
};
|
|
11873
|
+
/** @description Invalid or expired token */
|
|
11874
|
+
401: {
|
|
11875
|
+
headers: {
|
|
11876
|
+
[name: string]: unknown;
|
|
11877
|
+
};
|
|
11878
|
+
content: {
|
|
11879
|
+
/**
|
|
11880
|
+
* @example {
|
|
11881
|
+
* "error": {
|
|
11882
|
+
* "statusCode": 401,
|
|
11883
|
+
* "code": null,
|
|
11884
|
+
* "message": "Invalid or expired token",
|
|
11885
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11886
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
11887
|
+
* "method": "GET"
|
|
11888
|
+
* }
|
|
11889
|
+
* }
|
|
11890
|
+
*/
|
|
11891
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11892
|
+
};
|
|
11893
|
+
};
|
|
11894
|
+
/** @description The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node */
|
|
11895
|
+
403: {
|
|
11896
|
+
headers: {
|
|
11897
|
+
[name: string]: unknown;
|
|
11898
|
+
};
|
|
11899
|
+
content: {
|
|
11900
|
+
/**
|
|
11901
|
+
* @example {
|
|
11902
|
+
* "error": {
|
|
11903
|
+
* "statusCode": 403,
|
|
11904
|
+
* "code": null,
|
|
11905
|
+
* "message": "The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node",
|
|
11906
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11907
|
+
* "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
|
|
11908
|
+
* "method": "DELETE"
|
|
11909
|
+
* }
|
|
11910
|
+
* }
|
|
11911
|
+
*/
|
|
11912
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11913
|
+
};
|
|
11914
|
+
};
|
|
11915
|
+
/** @description The organization is not in this Environment, or the assignment is not at one of its nodes */
|
|
11916
|
+
404: {
|
|
11917
|
+
headers: {
|
|
11918
|
+
[name: string]: unknown;
|
|
11919
|
+
};
|
|
11920
|
+
content: {
|
|
11921
|
+
/**
|
|
11922
|
+
* @example {
|
|
11923
|
+
* "error": {
|
|
11924
|
+
* "statusCode": 404,
|
|
11925
|
+
* "code": null,
|
|
11926
|
+
* "message": "The organization is not in this Environment, or the assignment is not at one of its nodes",
|
|
11927
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11928
|
+
* "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
|
|
11929
|
+
* "method": "DELETE"
|
|
11930
|
+
* }
|
|
11931
|
+
* }
|
|
11932
|
+
*/
|
|
11933
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11934
|
+
};
|
|
11935
|
+
};
|
|
11936
|
+
/** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
|
|
11937
|
+
409: {
|
|
11938
|
+
headers: {
|
|
11939
|
+
[name: string]: unknown;
|
|
11940
|
+
};
|
|
11941
|
+
content: {
|
|
11942
|
+
/**
|
|
11943
|
+
* @example {
|
|
11944
|
+
* "error": {
|
|
11945
|
+
* "statusCode": 409,
|
|
11946
|
+
* "code": null,
|
|
11947
|
+
* "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
|
|
11948
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
11949
|
+
* "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
|
|
11950
|
+
* "method": "DELETE"
|
|
11951
|
+
* }
|
|
11952
|
+
* }
|
|
11953
|
+
*/
|
|
11954
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
11955
|
+
};
|
|
11956
|
+
};
|
|
11957
|
+
};
|
|
11958
|
+
};
|
|
11959
|
+
ApiOrganizationAccessController_updateAssignment: {
|
|
11960
|
+
parameters: {
|
|
11961
|
+
query?: never;
|
|
11962
|
+
header?: {
|
|
11963
|
+
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
11964
|
+
"If-Match"?: string;
|
|
11965
|
+
};
|
|
11966
|
+
path: {
|
|
11967
|
+
id: string;
|
|
11968
|
+
assignmentId: string;
|
|
11969
|
+
};
|
|
11970
|
+
cookie?: never;
|
|
11971
|
+
};
|
|
11972
|
+
requestBody: {
|
|
11973
|
+
content: {
|
|
11974
|
+
"application/json": components["schemas"]["UpdateAssignmentDto"];
|
|
11975
|
+
};
|
|
11976
|
+
};
|
|
11977
|
+
responses: {
|
|
11978
|
+
/** @description Assignment updated */
|
|
11979
|
+
200: {
|
|
11980
|
+
headers: {
|
|
11981
|
+
[name: string]: unknown;
|
|
11982
|
+
};
|
|
11983
|
+
content: {
|
|
11984
|
+
"application/json": {
|
|
11985
|
+
data: components["schemas"]["AssignmentResponseDto"];
|
|
11986
|
+
};
|
|
11987
|
+
};
|
|
11988
|
+
};
|
|
11989
|
+
/** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
|
|
11990
|
+
400: {
|
|
11991
|
+
headers: {
|
|
11992
|
+
[name: string]: unknown;
|
|
11993
|
+
};
|
|
11994
|
+
content: {
|
|
11995
|
+
/**
|
|
11996
|
+
* @example {
|
|
11997
|
+
* "error": {
|
|
11998
|
+
* "statusCode": 400,
|
|
11999
|
+
* "code": null,
|
|
12000
|
+
* "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
|
|
12001
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
12002
|
+
* "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
|
|
12003
|
+
* "method": "PATCH"
|
|
12004
|
+
* }
|
|
12005
|
+
* }
|
|
12006
|
+
*/
|
|
12007
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
12008
|
+
};
|
|
12009
|
+
};
|
|
12010
|
+
/** @description Invalid or expired token */
|
|
12011
|
+
401: {
|
|
12012
|
+
headers: {
|
|
12013
|
+
[name: string]: unknown;
|
|
12014
|
+
};
|
|
12015
|
+
content: {
|
|
12016
|
+
/**
|
|
12017
|
+
* @example {
|
|
12018
|
+
* "error": {
|
|
12019
|
+
* "statusCode": 401,
|
|
12020
|
+
* "code": null,
|
|
12021
|
+
* "message": "Invalid or expired token",
|
|
12022
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
12023
|
+
* "path": "/api/v1/organizations/{id}/me",
|
|
12024
|
+
* "method": "GET"
|
|
12025
|
+
* }
|
|
12026
|
+
* }
|
|
12027
|
+
*/
|
|
12028
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
12029
|
+
};
|
|
12030
|
+
};
|
|
12031
|
+
/** @description The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`) */
|
|
12032
|
+
403: {
|
|
10544
12033
|
headers: {
|
|
10545
12034
|
[name: string]: unknown;
|
|
10546
12035
|
};
|
|
@@ -10548,20 +12037,20 @@ interface operations {
|
|
|
10548
12037
|
/**
|
|
10549
12038
|
* @example {
|
|
10550
12039
|
* "error": {
|
|
10551
|
-
* "statusCode":
|
|
12040
|
+
* "statusCode": 403,
|
|
10552
12041
|
* "code": null,
|
|
10553
|
-
* "message": "
|
|
12042
|
+
* "message": "The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`)",
|
|
10554
12043
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
10555
|
-
* "path": "/api/v1/
|
|
10556
|
-
* "method": "
|
|
12044
|
+
* "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
|
|
12045
|
+
* "method": "PATCH"
|
|
10557
12046
|
* }
|
|
10558
12047
|
* }
|
|
10559
12048
|
*/
|
|
10560
12049
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
10561
12050
|
};
|
|
10562
12051
|
};
|
|
10563
|
-
/** @description The
|
|
10564
|
-
|
|
12052
|
+
/** @description The organization is not in this Environment, or the assignment is not at one of its nodes */
|
|
12053
|
+
404: {
|
|
10565
12054
|
headers: {
|
|
10566
12055
|
[name: string]: unknown;
|
|
10567
12056
|
};
|
|
@@ -10569,20 +12058,20 @@ interface operations {
|
|
|
10569
12058
|
/**
|
|
10570
12059
|
* @example {
|
|
10571
12060
|
* "error": {
|
|
10572
|
-
* "statusCode":
|
|
12061
|
+
* "statusCode": 404,
|
|
10573
12062
|
* "code": null,
|
|
10574
|
-
* "message": "The
|
|
12063
|
+
* "message": "The organization is not in this Environment, or the assignment is not at one of its nodes",
|
|
10575
12064
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
10576
|
-
* "path": "/api/v1/
|
|
10577
|
-
* "method": "
|
|
12065
|
+
* "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
|
|
12066
|
+
* "method": "PATCH"
|
|
10578
12067
|
* }
|
|
10579
12068
|
* }
|
|
10580
12069
|
*/
|
|
10581
12070
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
10582
12071
|
};
|
|
10583
12072
|
};
|
|
10584
|
-
/** @description
|
|
10585
|
-
|
|
12073
|
+
/** @description The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or it is the last administrator's role at the organization node (`organization.last_admin`) */
|
|
12074
|
+
409: {
|
|
10586
12075
|
headers: {
|
|
10587
12076
|
[name: string]: unknown;
|
|
10588
12077
|
};
|
|
@@ -10590,12 +12079,12 @@ interface operations {
|
|
|
10590
12079
|
/**
|
|
10591
12080
|
* @example {
|
|
10592
12081
|
* "error": {
|
|
10593
|
-
* "statusCode":
|
|
12082
|
+
* "statusCode": 409,
|
|
10594
12083
|
* "code": null,
|
|
10595
|
-
* "message": "
|
|
12084
|
+
* "message": "The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or it is the last administrator's role at the organization node (`organization.last_admin`)",
|
|
10596
12085
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
10597
|
-
* "path": "/api/v1/
|
|
10598
|
-
* "method": "
|
|
12086
|
+
* "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
|
|
12087
|
+
* "method": "PATCH"
|
|
10599
12088
|
* }
|
|
10600
12089
|
* }
|
|
10601
12090
|
*/
|
|
@@ -11005,8 +12494,7 @@ interface operations {
|
|
|
11005
12494
|
ApiOrganizationsController_deleteOrganization: {
|
|
11006
12495
|
parameters: {
|
|
11007
12496
|
query?: never;
|
|
11008
|
-
header
|
|
11009
|
-
"if-match": string;
|
|
12497
|
+
header?: {
|
|
11010
12498
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
11011
12499
|
"If-Match"?: string;
|
|
11012
12500
|
};
|
|
@@ -11134,8 +12622,7 @@ interface operations {
|
|
|
11134
12622
|
ApiOrganizationsController_updateOrganization: {
|
|
11135
12623
|
parameters: {
|
|
11136
12624
|
query?: never;
|
|
11137
|
-
header
|
|
11138
|
-
"if-match": string;
|
|
12625
|
+
header?: {
|
|
11139
12626
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
11140
12627
|
"If-Match"?: string;
|
|
11141
12628
|
};
|
|
@@ -11379,8 +12866,7 @@ interface operations {
|
|
|
11379
12866
|
ApiOrganizationsController_updatePolicy: {
|
|
11380
12867
|
parameters: {
|
|
11381
12868
|
query?: never;
|
|
11382
|
-
header
|
|
11383
|
-
"if-match": string;
|
|
12869
|
+
header?: {
|
|
11384
12870
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
11385
12871
|
"If-Match"?: string;
|
|
11386
12872
|
};
|
|
@@ -12690,14 +14176,14 @@ interface operations {
|
|
|
12690
14176
|
take?: number;
|
|
12691
14177
|
/** @description Search member names and emails */
|
|
12692
14178
|
q?: string;
|
|
12693
|
-
/** @description Sort column. Defaults to `
|
|
12694
|
-
sort_by?: "name" | "email" | "
|
|
14179
|
+
/** @description Sort column. Defaults to `joined`, longest-standing member first. */
|
|
14180
|
+
sort_by?: "name" | "email" | "joined";
|
|
12695
14181
|
/** @description Sort direction */
|
|
12696
14182
|
order?: "asc" | "desc";
|
|
12697
|
-
/** @description Only members holding this role */
|
|
14183
|
+
/** @description Only members holding this role anywhere in the organization, at its node or beneath */
|
|
12698
14184
|
role_id?: string;
|
|
12699
|
-
/** @description
|
|
12700
|
-
status?: "active" | "
|
|
14185
|
+
/** @description Which memberships to list: `active` (the default), `deactivated` for members who left, or `all` */
|
|
14186
|
+
status?: "active" | "deactivated" | "all";
|
|
12701
14187
|
};
|
|
12702
14188
|
header?: never;
|
|
12703
14189
|
path: {
|
|
@@ -12915,7 +14401,7 @@ interface operations {
|
|
|
12915
14401
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
12916
14402
|
};
|
|
12917
14403
|
};
|
|
12918
|
-
/** @description The identity is already a member of this organization */
|
|
14404
|
+
/** @description The identity is already a member of this organization (`organization.member_exists`); give them a role through the assignment routes */
|
|
12919
14405
|
409: {
|
|
12920
14406
|
headers: {
|
|
12921
14407
|
[name: string]: unknown;
|
|
@@ -12926,7 +14412,7 @@ interface operations {
|
|
|
12926
14412
|
* "error": {
|
|
12927
14413
|
* "statusCode": 409,
|
|
12928
14414
|
* "code": null,
|
|
12929
|
-
* "message": "The identity is already a member of this organization",
|
|
14415
|
+
* "message": "The identity is already a member of this organization (`organization.member_exists`); give them a role through the assignment routes",
|
|
12930
14416
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
12931
14417
|
* "path": "/api/v1/organizations/{id}/members",
|
|
12932
14418
|
* "method": "POST"
|
|
@@ -13064,140 +14550,6 @@ interface operations {
|
|
|
13064
14550
|
};
|
|
13065
14551
|
};
|
|
13066
14552
|
};
|
|
13067
|
-
ApiOrganizationsController_changeMemberRole: {
|
|
13068
|
-
parameters: {
|
|
13069
|
-
query?: never;
|
|
13070
|
-
header?: never;
|
|
13071
|
-
path: {
|
|
13072
|
-
id: string;
|
|
13073
|
-
identityId: string;
|
|
13074
|
-
};
|
|
13075
|
-
cookie?: never;
|
|
13076
|
-
};
|
|
13077
|
-
requestBody: {
|
|
13078
|
-
content: {
|
|
13079
|
-
"application/json": components["schemas"]["ChangeOrganizationMemberRoleDto"];
|
|
13080
|
-
};
|
|
13081
|
-
};
|
|
13082
|
-
responses: {
|
|
13083
|
-
/** @description Member role changed */
|
|
13084
|
-
200: {
|
|
13085
|
-
headers: {
|
|
13086
|
-
[name: string]: unknown;
|
|
13087
|
-
};
|
|
13088
|
-
content: {
|
|
13089
|
-
"application/json": {
|
|
13090
|
-
data: components["schemas"]["OrganizationMemberResponseDto"];
|
|
13091
|
-
};
|
|
13092
|
-
};
|
|
13093
|
-
};
|
|
13094
|
-
/** @description The request failed validation, or the role is inactive or a system role; or the request sent both an `X-API-Key` and an `Authorization` header */
|
|
13095
|
-
400: {
|
|
13096
|
-
headers: {
|
|
13097
|
-
[name: string]: unknown;
|
|
13098
|
-
};
|
|
13099
|
-
content: {
|
|
13100
|
-
/**
|
|
13101
|
-
* @example {
|
|
13102
|
-
* "error": {
|
|
13103
|
-
* "statusCode": 400,
|
|
13104
|
-
* "code": null,
|
|
13105
|
-
* "message": "The request failed validation, or the role is inactive or a system role; or the request sent both an `X-API-Key` and an `Authorization` header",
|
|
13106
|
-
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
13107
|
-
* "path": "/api/v1/organizations/{id}/members/{identityId}",
|
|
13108
|
-
* "method": "PATCH"
|
|
13109
|
-
* }
|
|
13110
|
-
* }
|
|
13111
|
-
*/
|
|
13112
|
-
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13113
|
-
};
|
|
13114
|
-
};
|
|
13115
|
-
/** @description Invalid or expired token */
|
|
13116
|
-
401: {
|
|
13117
|
-
headers: {
|
|
13118
|
-
[name: string]: unknown;
|
|
13119
|
-
};
|
|
13120
|
-
content: {
|
|
13121
|
-
/**
|
|
13122
|
-
* @example {
|
|
13123
|
-
* "error": {
|
|
13124
|
-
* "statusCode": 401,
|
|
13125
|
-
* "code": null,
|
|
13126
|
-
* "message": "Invalid or expired token",
|
|
13127
|
-
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
13128
|
-
* "path": "/api/v1/organizations",
|
|
13129
|
-
* "method": "GET"
|
|
13130
|
-
* }
|
|
13131
|
-
* }
|
|
13132
|
-
*/
|
|
13133
|
-
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13134
|
-
};
|
|
13135
|
-
};
|
|
13136
|
-
/** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
|
|
13137
|
-
403: {
|
|
13138
|
-
headers: {
|
|
13139
|
-
[name: string]: unknown;
|
|
13140
|
-
};
|
|
13141
|
-
content: {
|
|
13142
|
-
/**
|
|
13143
|
-
* @example {
|
|
13144
|
-
* "error": {
|
|
13145
|
-
* "statusCode": 403,
|
|
13146
|
-
* "code": null,
|
|
13147
|
-
* "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
|
|
13148
|
-
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
13149
|
-
* "path": "/api/v1/organizations",
|
|
13150
|
-
* "method": "GET"
|
|
13151
|
-
* }
|
|
13152
|
-
* }
|
|
13153
|
-
*/
|
|
13154
|
-
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13155
|
-
};
|
|
13156
|
-
};
|
|
13157
|
-
/** @description The organization or the role does not exist, or the identity is not a member of this organization */
|
|
13158
|
-
404: {
|
|
13159
|
-
headers: {
|
|
13160
|
-
[name: string]: unknown;
|
|
13161
|
-
};
|
|
13162
|
-
content: {
|
|
13163
|
-
/**
|
|
13164
|
-
* @example {
|
|
13165
|
-
* "error": {
|
|
13166
|
-
* "statusCode": 404,
|
|
13167
|
-
* "code": null,
|
|
13168
|
-
* "message": "The organization or the role does not exist, or the identity is not a member of this organization",
|
|
13169
|
-
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
13170
|
-
* "path": "/api/v1/organizations/{id}/members/{identityId}",
|
|
13171
|
-
* "method": "PATCH"
|
|
13172
|
-
* }
|
|
13173
|
-
* }
|
|
13174
|
-
*/
|
|
13175
|
-
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13176
|
-
};
|
|
13177
|
-
};
|
|
13178
|
-
/** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
|
|
13179
|
-
409: {
|
|
13180
|
-
headers: {
|
|
13181
|
-
[name: string]: unknown;
|
|
13182
|
-
};
|
|
13183
|
-
content: {
|
|
13184
|
-
/**
|
|
13185
|
-
* @example {
|
|
13186
|
-
* "error": {
|
|
13187
|
-
* "statusCode": 409,
|
|
13188
|
-
* "code": null,
|
|
13189
|
-
* "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
|
|
13190
|
-
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
13191
|
-
* "path": "/api/v1/organizations/{id}/members/{identityId}",
|
|
13192
|
-
* "method": "PATCH"
|
|
13193
|
-
* }
|
|
13194
|
-
* }
|
|
13195
|
-
*/
|
|
13196
|
-
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13197
|
-
};
|
|
13198
|
-
};
|
|
13199
|
-
};
|
|
13200
|
-
};
|
|
13201
14553
|
ApiOrganizationsController_resetMemberMfa: {
|
|
13202
14554
|
parameters: {
|
|
13203
14555
|
query?: never;
|
|
@@ -13514,7 +14866,7 @@ interface operations {
|
|
|
13514
14866
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
13515
14867
|
};
|
|
13516
14868
|
};
|
|
13517
|
-
/** @description
|
|
14869
|
+
/** @description The token is not an admin, API key or identity token, or the caller is an identity that does not hold, at the organization node or above, every permission the role carries (`assignment.grant_ceiling`); Console users and API keys are not bounded */
|
|
13518
14870
|
403: {
|
|
13519
14871
|
headers: {
|
|
13520
14872
|
[name: string]: unknown;
|
|
@@ -13525,10 +14877,10 @@ interface operations {
|
|
|
13525
14877
|
* "error": {
|
|
13526
14878
|
* "statusCode": 403,
|
|
13527
14879
|
* "code": null,
|
|
13528
|
-
* "message": "
|
|
14880
|
+
* "message": "The token is not an admin, API key or identity token, or the caller is an identity that does not hold, at the organization node or above, every permission the role carries (`assignment.grant_ceiling`); Console users and API keys are not bounded",
|
|
13529
14881
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
13530
|
-
* "path": "/api/v1/organizations",
|
|
13531
|
-
* "method": "
|
|
14882
|
+
* "path": "/api/v1/organizations/{id}/invites",
|
|
14883
|
+
* "method": "POST"
|
|
13532
14884
|
* }
|
|
13533
14885
|
* }
|
|
13534
14886
|
*/
|
|
@@ -13597,7 +14949,7 @@ interface operations {
|
|
|
13597
14949
|
};
|
|
13598
14950
|
content: {
|
|
13599
14951
|
"application/json": {
|
|
13600
|
-
items: components["schemas"]["
|
|
14952
|
+
items: components["schemas"]["OrganizationRoleResponseDto"][];
|
|
13601
14953
|
};
|
|
13602
14954
|
};
|
|
13603
14955
|
};
|
|
@@ -16871,8 +18223,7 @@ interface operations {
|
|
|
16871
18223
|
ApiRolesController_deleteRole: {
|
|
16872
18224
|
parameters: {
|
|
16873
18225
|
query?: never;
|
|
16874
|
-
header
|
|
16875
|
-
"if-match": string;
|
|
18226
|
+
header?: {
|
|
16876
18227
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
16877
18228
|
"If-Match"?: string;
|
|
16878
18229
|
};
|
|
@@ -17000,8 +18351,7 @@ interface operations {
|
|
|
17000
18351
|
ApiRolesController_updateRole: {
|
|
17001
18352
|
parameters: {
|
|
17002
18353
|
query?: never;
|
|
17003
|
-
header
|
|
17004
|
-
"if-match": string;
|
|
18354
|
+
header?: {
|
|
17005
18355
|
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
17006
18356
|
"If-Match"?: string;
|
|
17007
18357
|
};
|
|
@@ -17650,7 +19000,7 @@ interface operations {
|
|
|
17650
19000
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
17651
19001
|
};
|
|
17652
19002
|
};
|
|
17653
|
-
/** @description The identity already has this role at this node,
|
|
19003
|
+
/** @description The identity already has this role at this node, or the node sits beneath an organization the identity is not an active member of (`organization.membership_required`) */
|
|
17654
19004
|
409: {
|
|
17655
19005
|
headers: {
|
|
17656
19006
|
[name: string]: unknown;
|
|
@@ -17661,7 +19011,7 @@ interface operations {
|
|
|
17661
19011
|
* "error": {
|
|
17662
19012
|
* "statusCode": 409,
|
|
17663
19013
|
* "code": null,
|
|
17664
|
-
* "message": "The identity already has this role at this node,
|
|
19014
|
+
* "message": "The identity already has this role at this node, or the node sits beneath an organization the identity is not an active member of (`organization.membership_required`)",
|
|
17665
19015
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
17666
19016
|
* "path": "/api/v1/assignments",
|
|
17667
19017
|
* "method": "POST"
|
|
@@ -17775,12 +19125,36 @@ interface operations {
|
|
|
17775
19125
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
17776
19126
|
};
|
|
17777
19127
|
};
|
|
19128
|
+
/** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
|
|
19129
|
+
409: {
|
|
19130
|
+
headers: {
|
|
19131
|
+
[name: string]: unknown;
|
|
19132
|
+
};
|
|
19133
|
+
content: {
|
|
19134
|
+
/**
|
|
19135
|
+
* @example {
|
|
19136
|
+
* "error": {
|
|
19137
|
+
* "statusCode": 409,
|
|
19138
|
+
* "code": null,
|
|
19139
|
+
* "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
|
|
19140
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
19141
|
+
* "path": "/api/v1/assignments/{id}",
|
|
19142
|
+
* "method": "DELETE"
|
|
19143
|
+
* }
|
|
19144
|
+
* }
|
|
19145
|
+
*/
|
|
19146
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
19147
|
+
};
|
|
19148
|
+
};
|
|
17778
19149
|
};
|
|
17779
19150
|
};
|
|
17780
19151
|
ApiAssignmentsController_updateAssignment: {
|
|
17781
19152
|
parameters: {
|
|
17782
19153
|
query?: never;
|
|
17783
|
-
header?:
|
|
19154
|
+
header?: {
|
|
19155
|
+
/** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
|
|
19156
|
+
"If-Match"?: string;
|
|
19157
|
+
};
|
|
17784
19158
|
path: {
|
|
17785
19159
|
id: string;
|
|
17786
19160
|
};
|
|
@@ -17887,7 +19261,7 @@ interface operations {
|
|
|
17887
19261
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
17888
19262
|
};
|
|
17889
19263
|
};
|
|
17890
|
-
/** @description
|
|
19264
|
+
/** @description The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`) */
|
|
17891
19265
|
409: {
|
|
17892
19266
|
headers: {
|
|
17893
19267
|
[name: string]: unknown;
|
|
@@ -17898,7 +19272,7 @@ interface operations {
|
|
|
17898
19272
|
* "error": {
|
|
17899
19273
|
* "statusCode": 409,
|
|
17900
19274
|
* "code": null,
|
|
17901
|
-
* "message": "
|
|
19275
|
+
* "message": "The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`)",
|
|
17902
19276
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
17903
19277
|
* "path": "/api/v1/assignments/{id}",
|
|
17904
19278
|
* "method": "PATCH"
|
|
@@ -18014,6 +19388,27 @@ interface operations {
|
|
|
18014
19388
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
18015
19389
|
};
|
|
18016
19390
|
};
|
|
19391
|
+
/** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
|
|
19392
|
+
409: {
|
|
19393
|
+
headers: {
|
|
19394
|
+
[name: string]: unknown;
|
|
19395
|
+
};
|
|
19396
|
+
content: {
|
|
19397
|
+
/**
|
|
19398
|
+
* @example {
|
|
19399
|
+
* "error": {
|
|
19400
|
+
* "statusCode": 409,
|
|
19401
|
+
* "code": null,
|
|
19402
|
+
* "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
|
|
19403
|
+
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
19404
|
+
* "path": "/api/v1/assignments/bulk-remove",
|
|
19405
|
+
* "method": "POST"
|
|
19406
|
+
* }
|
|
19407
|
+
* }
|
|
19408
|
+
*/
|
|
19409
|
+
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
19410
|
+
};
|
|
19411
|
+
};
|
|
18017
19412
|
};
|
|
18018
19413
|
};
|
|
18019
19414
|
ApiAssignmentsController_bulkChangeRole: {
|
|
@@ -18124,7 +19519,7 @@ interface operations {
|
|
|
18124
19519
|
"application/json": components["schemas"]["ErrorResponseDto"];
|
|
18125
19520
|
};
|
|
18126
19521
|
};
|
|
18127
|
-
/** @description
|
|
19522
|
+
/** @description The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`) */
|
|
18128
19523
|
409: {
|
|
18129
19524
|
headers: {
|
|
18130
19525
|
[name: string]: unknown;
|
|
@@ -18135,7 +19530,7 @@ interface operations {
|
|
|
18135
19530
|
* "error": {
|
|
18136
19531
|
* "statusCode": 409,
|
|
18137
19532
|
* "code": null,
|
|
18138
|
-
* "message": "
|
|
19533
|
+
* "message": "The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`)",
|
|
18139
19534
|
* "timestamp": "2026-04-20T12:00:00.000Z",
|
|
18140
19535
|
* "path": "/api/v1/assignments/bulk-change-role",
|
|
18141
19536
|
* "method": "POST"
|
|
@@ -19081,8 +20476,7 @@ interface operations {
|
|
|
19081
20476
|
ApiHierarchySchemaController_updateSchema: {
|
|
19082
20477
|
parameters: {
|
|
19083
20478
|
query?: never;
|
|
19084
|
-
header
|
|
19085
|
-
"if-match": string;
|
|
20479
|
+
header?: {
|
|
19086
20480
|
/** @description Optimistic-lock token. Pass the `version` you read from the Environment — request fails 409 when the row has moved on. */
|
|
19087
20481
|
"If-Match"?: string;
|
|
19088
20482
|
};
|
|
@@ -21486,7 +22880,12 @@ declare class Assignments {
|
|
|
21486
22880
|
* answer, read the current assignments before retrying.
|
|
21487
22881
|
*/
|
|
21488
22882
|
create(input: RequestBody<"ApiAssignmentsController_assignRole">): Promise<ResponseBody<"ApiAssignmentsController_assignRole">>;
|
|
21489
|
-
|
|
22883
|
+
/**
|
|
22884
|
+
* Change the role or the window of a grant. Pass the `version` the
|
|
22885
|
+
* assignment was read with as `ifMatch`; a stale one answers 409
|
|
22886
|
+
* `assignment.version_mismatch` rather than overwriting a newer change.
|
|
22887
|
+
*/
|
|
22888
|
+
update(id: string, input: RequestBody<"ApiAssignmentsController_updateAssignment">, options?: ConcurrencyOptions): Promise<ResponseBody<"ApiAssignmentsController_updateAssignment">>;
|
|
21490
22889
|
delete(id: string): Promise<void>;
|
|
21491
22890
|
/**
|
|
21492
22891
|
* Grant many at once. Answers 207 with a per-item result rather than failing
|
|
@@ -21539,7 +22938,18 @@ declare class Identities {
|
|
|
21539
22938
|
* question at the node that matters. This is for showing a person what
|
|
21540
22939
|
* someone can do.
|
|
21541
22940
|
*/
|
|
21542
|
-
permissions(id: string): Promise<ResponseBody<"ApiIdentitiesController_getIdentityPermissions">>;
|
|
22941
|
+
permissions(id: string, query?: QueryParams<"ApiIdentitiesController_getIdentityPermissions">): Promise<ResponseBody<"ApiIdentitiesController_getIdentityPermissions">>;
|
|
22942
|
+
/**
|
|
22943
|
+
* Where the identity may act with one permission, answered by Canopy for a
|
|
22944
|
+
* list query: the minimal grant roots, and every node beneath them up to
|
|
22945
|
+
* `max_nodes` (null past it, with `complete: false`), or `env_wide` when a
|
|
22946
|
+
* root is the Environment's own root and no filter is needed.
|
|
22947
|
+
*
|
|
22948
|
+
* `LocalAuthorizer.accessibleNodes` answers the same question from its
|
|
22949
|
+
* cache without a call; this is the fresh answer, and the one for a process
|
|
22950
|
+
* that does not run the authorizer.
|
|
22951
|
+
*/
|
|
22952
|
+
accessibleNodes(id: string, query: QueryParams<"ApiIdentitiesController_getIdentityAccessibleNodes">): Promise<ResponseBody<"ApiIdentitiesController_getIdentityAccessibleNodes">>;
|
|
21543
22953
|
/**
|
|
21544
22954
|
* Every session the identity holds that is neither revoked nor expired,
|
|
21545
22955
|
* newest first: when and where it was signed in, when it expires, and the
|
|
@@ -21579,8 +22989,8 @@ type ItemOf$3<T> = T extends {
|
|
|
21579
22989
|
} ? Item : never;
|
|
21580
22990
|
|
|
21581
22991
|
/**
|
|
21582
|
-
* Tenant organizations: one per business customer,
|
|
21583
|
-
* each with its own authentication policy and identity provider. Every
|
|
22992
|
+
* Tenant organizations: one per business customer, membership apart from
|
|
22993
|
+
* the roles held inside it, each with its own authentication policy and identity provider. Every
|
|
21584
22994
|
* call here needs the Environment's organizations container switched on.
|
|
21585
22995
|
*/
|
|
21586
22996
|
declare class Organizations {
|
|
@@ -21605,8 +23015,12 @@ declare class Organizations {
|
|
|
21605
23015
|
deleteAll(): Promise<void>;
|
|
21606
23016
|
listMembers(id: string, query?: QueryParams<"ApiOrganizationsController_listMembers">): Paginator<OrganizationMemberItem>;
|
|
21607
23017
|
addMember(id: string, input: RequestBody<"ApiOrganizationsController_addMember">): Promise<ResponseBody<"ApiOrganizationsController_addMember">>;
|
|
21608
|
-
|
|
21609
|
-
|
|
23018
|
+
/**
|
|
23019
|
+
* Deactivates the membership and revokes every role the member holds at
|
|
23020
|
+
* the organization's nodes; the identity and its other memberships are
|
|
23021
|
+
* untouched. A role in the organization is changed through the
|
|
23022
|
+
* organization's assignment routes, not here.
|
|
23023
|
+
*/
|
|
21610
23024
|
removeMember(id: string, identityId: string): Promise<void>;
|
|
21611
23025
|
/**
|
|
21612
23026
|
* Clears a member's second factor, for one who lost their authenticator:
|
|
@@ -21839,6 +23253,39 @@ declare class Canopy {
|
|
|
21839
23253
|
* delay is short, so a longer value is refused rather than honoured.
|
|
21840
23254
|
*/
|
|
21841
23255
|
declare const MAX_TTL_MS = 300000;
|
|
23256
|
+
/**
|
|
23257
|
+
* The largest node set `accessibleNodes` builds unless told otherwise. Past
|
|
23258
|
+
* it the answer carries the roots alone, and the caller filters against its
|
|
23259
|
+
* own closure table or materialised path instead of an `IN (...)` list.
|
|
23260
|
+
*/
|
|
23261
|
+
declare const DEFAULT_MAX_NODES = 10000;
|
|
23262
|
+
/**
|
|
23263
|
+
* Why a check was denied, as far as the grant roots and the tree can say.
|
|
23264
|
+
*
|
|
23265
|
+
* - `permission_not_held`: no assignment grants the permission anywhere, in
|
|
23266
|
+
* effect or not.
|
|
23267
|
+
* - `outside_grants`: it is granted, but at no node on the lineage of the
|
|
23268
|
+
* node asked about.
|
|
23269
|
+
* - `expired`: a grant that would answer has ended, and none is in effect.
|
|
23270
|
+
* - `not_yet_effective`: a grant that would answer has not begun, and none
|
|
23271
|
+
* is in effect.
|
|
23272
|
+
* - `node_missing`: a `node` check named no node, which is a denial rather
|
|
23273
|
+
* than an error, because a request whose subject cannot be established
|
|
23274
|
+
* must not pass.
|
|
23275
|
+
*/
|
|
23276
|
+
type LocalDenialReason = "permission_not_held" | "outside_grants" | "expired" | "not_yet_effective" | "node_missing";
|
|
23277
|
+
/** The answer to a check: the verdict, and why when it is no. */
|
|
23278
|
+
interface LocalDecision {
|
|
23279
|
+
allowed: boolean;
|
|
23280
|
+
reason: LocalDenialReason | null;
|
|
23281
|
+
}
|
|
23282
|
+
/** What a decision hook receives, after the verdict is in. */
|
|
23283
|
+
interface LocalDecisionEvent {
|
|
23284
|
+
query: LocalAuthorizationQuery;
|
|
23285
|
+
decision: LocalDecision;
|
|
23286
|
+
/** How long the check took, reads included. */
|
|
23287
|
+
durationMs: number;
|
|
23288
|
+
}
|
|
21842
23289
|
interface LocalAuthorizerOptions {
|
|
21843
23290
|
/**
|
|
21844
23291
|
* How long grant roots and the hierarchy are reused, in milliseconds.
|
|
@@ -21871,6 +23318,19 @@ interface LocalAuthorizerOptions {
|
|
|
21871
23318
|
timeoutMs?: number;
|
|
21872
23319
|
/** Retries for those reads. */
|
|
21873
23320
|
maxRetries?: number;
|
|
23321
|
+
/**
|
|
23322
|
+
* The largest node set {@link LocalAuthorizer.accessibleNodes} builds
|
|
23323
|
+
* unless a call says otherwise. Defaults to {@link DEFAULT_MAX_NODES}.
|
|
23324
|
+
*/
|
|
23325
|
+
maxNodes?: number;
|
|
23326
|
+
/**
|
|
23327
|
+
* Called after every decision, allowed or not, with the question and the
|
|
23328
|
+
* answer. Never awaited and never allowed to fail the check: a hook that
|
|
23329
|
+
* throws is ignored. For audit trails and metrics.
|
|
23330
|
+
*/
|
|
23331
|
+
onDecision?: (event: LocalDecisionEvent) => void;
|
|
23332
|
+
/** Called after every denial, the same way. For alerting on refusals. */
|
|
23333
|
+
onDenied?: (event: LocalDecisionEvent) => void;
|
|
21874
23334
|
/** Injectable clock, for tests. */
|
|
21875
23335
|
now?: () => number;
|
|
21876
23336
|
}
|
|
@@ -21881,6 +23341,26 @@ interface LocalAuthorizationQuery {
|
|
|
21881
23341
|
scope?: "node" | "app_wide";
|
|
21882
23342
|
node_id?: string;
|
|
21883
23343
|
}
|
|
23344
|
+
/** Where an identity may act with one permission, shaped for a list query. */
|
|
23345
|
+
interface AccessibleNodes {
|
|
23346
|
+
/**
|
|
23347
|
+
* The nodes the permission is granted at, in effect now, that no other
|
|
23348
|
+
* such node already covers. Each reaches everything beneath it.
|
|
23349
|
+
*/
|
|
23350
|
+
roots: string[];
|
|
23351
|
+
/**
|
|
23352
|
+
* Every node beneath the roots, the roots included, for an `IN (...)`
|
|
23353
|
+
* filter. Null when `envWide`, or when the set would exceed the cap.
|
|
23354
|
+
*/
|
|
23355
|
+
nodes: Set<string> | null;
|
|
23356
|
+
/** False when the set exceeded the cap and `nodes` was not built. */
|
|
23357
|
+
complete: boolean;
|
|
23358
|
+
/**
|
|
23359
|
+
* True when a root is the Environment's own root: every node qualifies, so
|
|
23360
|
+
* a list needs no filter at all.
|
|
23361
|
+
*/
|
|
23362
|
+
envWide: boolean;
|
|
23363
|
+
}
|
|
21884
23364
|
interface LocalAuthorizerStats {
|
|
21885
23365
|
/** Reads of an identity's grant roots, one per refresh however many pages it took. */
|
|
21886
23366
|
grantFetches: number;
|
|
@@ -21900,8 +23380,11 @@ interface LocalAuthorizerStats {
|
|
|
21900
23380
|
declare class LocalAuthorizer {
|
|
21901
23381
|
private readonly client;
|
|
21902
23382
|
private readonly ttlMs;
|
|
23383
|
+
private readonly maxNodes;
|
|
21903
23384
|
private readonly now;
|
|
21904
23385
|
private readonly readOptions;
|
|
23386
|
+
private readonly onDecision;
|
|
23387
|
+
private readonly onDenied;
|
|
21905
23388
|
private readonly grants;
|
|
21906
23389
|
private tree;
|
|
21907
23390
|
/**
|
|
@@ -21917,7 +23400,7 @@ declare class LocalAuthorizer {
|
|
|
21917
23400
|
private stats;
|
|
21918
23401
|
constructor(client: CanopyClient, options?: LocalAuthorizerOptions);
|
|
21919
23402
|
/**
|
|
21920
|
-
* Whether the identity holds the permission.
|
|
23403
|
+
* Whether the identity holds the permission, and why not when it does not.
|
|
21921
23404
|
*
|
|
21922
23405
|
* Shaped like the API's own evaluate so a caller can swap one for the other.
|
|
21923
23406
|
* A `node` check with no node is a denial rather than an error: a request
|
|
@@ -21925,9 +23408,51 @@ declare class LocalAuthorizer {
|
|
|
21925
23408
|
*/
|
|
21926
23409
|
evaluate(query: LocalAuthorizationQuery, options?: {
|
|
21927
23410
|
signal?: AbortSignal;
|
|
21928
|
-
}): Promise<
|
|
21929
|
-
|
|
23411
|
+
}): Promise<LocalDecision>;
|
|
23412
|
+
/**
|
|
23413
|
+
* The nodes the identity holds the permission at, in effect now, reduced to
|
|
23414
|
+
* the ones no other such node already covers, and whether one of them is
|
|
23415
|
+
* the Environment's root. The roots alone are enough for an application
|
|
23416
|
+
* that keeps a closure table or a materialised path: it filters by "beneath
|
|
23417
|
+
* one of these" without an expanded set.
|
|
23418
|
+
*
|
|
23419
|
+
* Reads the tree, since minimality and `envWide` are questions about it; a
|
|
23420
|
+
* root the readable hierarchy does not contain raises
|
|
23421
|
+
* `authorizer.hierarchy_incomplete`, as a check at such a node does.
|
|
23422
|
+
*/
|
|
23423
|
+
grantRoots(identityId: string, permission: string): Promise<{
|
|
23424
|
+
roots: string[];
|
|
23425
|
+
envWide: boolean;
|
|
21930
23426
|
}>;
|
|
23427
|
+
/**
|
|
23428
|
+
* Where the identity may act with the permission, as the set a list query
|
|
23429
|
+
* filters by: {@link grantRoots} expanded through their descendants, up to
|
|
23430
|
+
* `maxNodes` (the authorizer's default unless given here).
|
|
23431
|
+
*
|
|
23432
|
+
* Past the cap `nodes` is null and `complete` false: the set is too large
|
|
23433
|
+
* to be worth an `IN (...)` list, and the caller filters by `roots`
|
|
23434
|
+
* instead. An `envWide` answer carries no set either, since every node
|
|
23435
|
+
* qualifies and a filter would only slow the query down.
|
|
23436
|
+
*
|
|
23437
|
+
* Computed from the same cached grant roots and tree a check uses, so a
|
|
23438
|
+
* list filtered by it and the check on a write cannot disagree, and it goes
|
|
23439
|
+
* stale on the same `ttlMs`.
|
|
23440
|
+
*/
|
|
23441
|
+
accessibleNodes(identityId: string, permission: string, options?: {
|
|
23442
|
+
maxNodes?: number;
|
|
23443
|
+
}): Promise<AccessibleNodes>;
|
|
23444
|
+
/**
|
|
23445
|
+
* Every permission the identity holds at the node, by grant or by
|
|
23446
|
+
* inheritance: the list a screen renders its controls from, answered from
|
|
23447
|
+
* the same cached grant roots and tree a check uses.
|
|
23448
|
+
*/
|
|
23449
|
+
permissionsAt(identityId: string, nodeId: string): Promise<string[]>;
|
|
23450
|
+
/**
|
|
23451
|
+
* {@link permissionsAt} for several nodes at once, as node → permissions:
|
|
23452
|
+
* the rows of a list each with their own controls, answered from one read
|
|
23453
|
+
* of the grant roots and one walk per node.
|
|
23454
|
+
*/
|
|
23455
|
+
permissionsAtMany(identityId: string, nodeIds: readonly string[]): Promise<Map<string, string[]>>;
|
|
21931
23456
|
private decide;
|
|
21932
23457
|
/** Counters for observability — how much traffic the cache is actually saving. */
|
|
21933
23458
|
snapshot(): LocalAuthorizerStats;
|
|
@@ -21954,19 +23479,29 @@ declare class LocalAuthorizer {
|
|
|
21954
23479
|
* top of it — size the TTL to the revocation latency you can promise.
|
|
21955
23480
|
*/
|
|
21956
23481
|
invalidate(identityId?: string): void;
|
|
21957
|
-
/**
|
|
21958
|
-
private
|
|
23482
|
+
/** Fire the decision hooks, after the verdict and without waiting on them. */
|
|
23483
|
+
private announce;
|
|
23484
|
+
/** The node and its ancestors, from the tree this client can read. */
|
|
23485
|
+
private lineageOf;
|
|
23486
|
+
private hierarchyIncomplete;
|
|
21959
23487
|
private grantRootsFor;
|
|
21960
23488
|
/**
|
|
21961
|
-
* Every page of the identity's grant roots,
|
|
23489
|
+
* Every page of the identity's grant roots, with their windows, folded
|
|
23490
|
+
* into permission → roots.
|
|
23491
|
+
*
|
|
23492
|
+
* Each row is one permission at one node for one assignment, so a
|
|
23493
|
+
* permission granted at three nodes arrives as three rows, possibly on
|
|
23494
|
+
* different pages. Stopping after the first page would under-report what
|
|
23495
|
+
* the identity holds: a false deny, the safe direction, but a wrong answer
|
|
23496
|
+
* all the same.
|
|
21962
23497
|
*
|
|
21963
|
-
*
|
|
21964
|
-
*
|
|
21965
|
-
*
|
|
21966
|
-
*
|
|
23498
|
+
* Rows outside their window are kept: they are what lets a denial say
|
|
23499
|
+
* `expired` or `not_yet_effective`, and the entry expires at the nearest
|
|
23500
|
+
* window boundary when that comes before the TTL, so a grant takes effect
|
|
23501
|
+
* or ends on time rather than up to `ttlMs` late.
|
|
21967
23502
|
*/
|
|
21968
23503
|
private fetchGrantRoots;
|
|
21969
|
-
private
|
|
23504
|
+
private treeEntry;
|
|
21970
23505
|
/**
|
|
21971
23506
|
* Revalidate rather than re-read. The hierarchy is the expensive half and
|
|
21972
23507
|
* the one that changes least, so the common case is a `304` and no transfer
|
|
@@ -22287,23 +23822,28 @@ interface CanopyTokenClaims {
|
|
|
22287
23822
|
* The organization this session is acting in — present only on identity
|
|
22288
23823
|
* tokens from an Environment with the organizations container on, for an
|
|
22289
23824
|
* identity that belongs to at least one organization. Always minted
|
|
22290
|
-
* together with `
|
|
23825
|
+
* together with `org_roles`; read the pair through {@link orgContext}
|
|
22291
23826
|
* rather than separately.
|
|
22292
23827
|
*/
|
|
22293
23828
|
org_id?: string;
|
|
22294
|
-
/**
|
|
22295
|
-
|
|
23829
|
+
/**
|
|
23830
|
+
* The names of the roles the identity holds at the organization's own node,
|
|
23831
|
+
* sorted; empty for a member who holds none there. Membership is admission,
|
|
23832
|
+
* not a role: a member may hold roles only beneath the organization, or
|
|
23833
|
+
* none at all.
|
|
23834
|
+
*/
|
|
23835
|
+
org_roles?: string[];
|
|
22296
23836
|
[claim: string]: unknown;
|
|
22297
23837
|
}
|
|
22298
23838
|
/**
|
|
22299
23839
|
* The organization context a verified token carries: which organization the
|
|
22300
|
-
* session is acting in, and the
|
|
23840
|
+
* session is acting in, and the roles it holds at that organization's node.
|
|
22301
23841
|
*/
|
|
22302
23842
|
interface CanopyOrgContext {
|
|
22303
23843
|
/** The organization's id — also a hierarchy node id, usable as `node_id`. */
|
|
22304
23844
|
orgId: string;
|
|
22305
|
-
/** The
|
|
22306
|
-
|
|
23845
|
+
/** The roles' names (not ids) held at the organization node: what `org_roles` carries. Empty for a member holding none there. */
|
|
23846
|
+
orgRoles: string[];
|
|
22307
23847
|
}
|
|
22308
23848
|
/**
|
|
22309
23849
|
* The organization context of a verified token, or `null` when it has none.
|
|
@@ -22311,16 +23851,18 @@ interface CanopyOrgContext {
|
|
|
22311
23851
|
* `null` is an ordinary answer, not a failure: it is every token from an
|
|
22312
23852
|
* Environment without the organizations container on, and every identity
|
|
22313
23853
|
* that belongs to no organization yet. Branch on it rather than on the raw claims —
|
|
22314
|
-
* Canopy mints `org_id` and `
|
|
23854
|
+
* Canopy mints `org_id` and `org_roles` together, and this helper refuses a
|
|
22315
23855
|
* half-present pair instead of letting one claim be read as though the other
|
|
22316
|
-
* were there.
|
|
23856
|
+
* were there. An empty `orgRoles` is a member of the organization holding no
|
|
23857
|
+
* role at its node; authorize such a session by evaluating, never by the
|
|
23858
|
+
* list's length.
|
|
22317
23859
|
*
|
|
22318
23860
|
* ```ts
|
|
22319
23861
|
* const claims = await verifier.verify(token);
|
|
22320
23862
|
* const org = orgContext(claims);
|
|
22321
23863
|
*
|
|
22322
23864
|
* if (org) {
|
|
22323
|
-
* // acting inside org.orgId
|
|
23865
|
+
* // acting inside org.orgId, holding org.orgRoles at its node
|
|
22324
23866
|
* }
|
|
22325
23867
|
* ```
|
|
22326
23868
|
*/
|
|
@@ -22432,4 +23974,4 @@ type WebhookEventData<Name extends WebhookEventName> = WebhookEvent<Name>["data"
|
|
|
22432
23974
|
*/
|
|
22433
23975
|
declare function isWebhookEvent<Name extends WebhookEventName>(delivery: WebhookDelivery, name: Name): delivery is WebhookEvent<Name>;
|
|
22434
23976
|
|
|
22435
|
-
export { type AssignmentItem, Assignments, type CallOptions, Canopy, CanopyAuthorizerError, CanopyClient, type CanopyClientOptions, CanopyConnectionError, CanopyError, type CanopyErrorBody, type CanopyOrgContext, type CanopyTokenClaims, CanopyTokenError, type Collection, type ConcurrencyOptions, type ConditionalResult, type CursorPagination, type FailureStatus, Identities, type IdentityAssignmentItem, type IdentityItem, type IdentitySessionItem, type LocalAuthorizationQuery, LocalAuthorizer, type LocalAuthorizerOptions, type LocalAuthorizerStats, MAX_TTL_MS, type OffsetPagination, type OperationId, type OrganizationDirectoryGroupItem, type OrganizationInviteItem, type OrganizationItem, type OrganizationMemberItem, Organizations, type PageFetcher, type PageParams, type PaginateOptions, type Pagination, Paginator, type PartialSuccess, type PermissionItem, Permissions, type QueryParams, type RequestBody, type RequestOptions, type ResponseBody, type RoleItem, Roles, type Schema, TokenVerifier, type TokenVerifierOptions, type WebhookDelivery, type WebhookEvent, type WebhookEventData, type WebhookEventName, authorizationErrorStatus, type components, isCanopyAuthorizerError, isCanopyConnectionError, isCanopyError, isCanopyTokenError, isCursorPagination, isWebhookEvent, type operations, orgContext, paginate, type paths, tokenErrorStatus, withConcurrency };
|
|
23977
|
+
export { type AccessibleNodes, type AssignmentItem, Assignments, type CallOptions, Canopy, CanopyAuthorizerError, CanopyClient, type CanopyClientOptions, CanopyConnectionError, CanopyError, type CanopyErrorBody, type CanopyOrgContext, type CanopyTokenClaims, CanopyTokenError, type Collection, type ConcurrencyOptions, type ConditionalResult, type CursorPagination, DEFAULT_MAX_NODES, type FailureStatus, Identities, type IdentityAssignmentItem, type IdentityItem, type IdentitySessionItem, type LocalAuthorizationQuery, LocalAuthorizer, type LocalAuthorizerOptions, type LocalAuthorizerStats, type LocalDecision, type LocalDecisionEvent, type LocalDenialReason, MAX_TTL_MS, type OffsetPagination, type OperationId, type OrganizationDirectoryGroupItem, type OrganizationInviteItem, type OrganizationItem, type OrganizationMemberItem, Organizations, type PageFetcher, type PageParams, type PaginateOptions, type Pagination, Paginator, type PartialSuccess, type PermissionItem, Permissions, type QueryParams, type RequestBody, type RequestOptions, type ResponseBody, type RoleItem, Roles, type Schema, TokenVerifier, type TokenVerifierOptions, type WebhookDelivery, type WebhookEvent, type WebhookEventData, type WebhookEventName, authorizationErrorStatus, type components, isCanopyAuthorizerError, isCanopyConnectionError, isCanopyError, isCanopyTokenError, isCursorPagination, isWebhookEvent, type operations, orgContext, paginate, type paths, tokenErrorStatus, withConcurrency };
|