@opengeni/contracts 2.15.2 → 3.0.0-canary.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/dist/atlassian.js +10 -9
- package/dist/{chunk-NPYLOZAP.js → chunk-5LYFSZ7O.js} +12 -12
- package/dist/{chunk-6TCVR53X.js → chunk-O5LEQHDM.js} +2 -2
- package/dist/{chunk-QP3BIGSC.js → chunk-OO4AEMQB.js} +7633 -7650
- package/dist/chunk-OO4AEMQB.js.map +1 -0
- package/dist/chunk-P3HLDT77.js +59 -0
- package/dist/chunk-P3HLDT77.js.map +1 -0
- package/dist/chunk-SSWEWU3V.js +348 -0
- package/dist/chunk-SSWEWU3V.js.map +1 -0
- package/dist/chunk-TEMFILR7.js +143 -0
- package/dist/chunk-TEMFILR7.js.map +1 -0
- package/dist/connect.d.ts +325 -0
- package/dist/connect.js +182 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-authority.js +28 -334
- package/dist/connection-authority.js.map +1 -1
- package/dist/editable-artifact-codec-registry.js +2 -2
- package/dist/editable-artifact-live.js +2 -2
- package/dist/editable-artifact-serialized-commit.js +3 -3
- package/dist/editable-artifacts.js +24 -24
- package/dist/external-identities.d.ts +620 -0
- package/dist/external-identities.js +34 -0
- package/dist/external-identities.js.map +1 -0
- package/dist/google-drive.js +12 -11
- package/dist/google-drive.js.map +1 -1
- package/dist/host-mcp-bindings.d.ts +297 -0
- package/dist/host-mcp-bindings.js +195 -0
- package/dist/host-mcp-bindings.js.map +1 -0
- package/dist/index.d.ts +149 -71
- package/dist/index.js +85 -81
- package/dist/personal-github.js +10 -9
- package/dist/personal-github.js.map +1 -1
- package/package.json +13 -1
- package/src/connect.ts +202 -0
- package/src/external-identities.ts +213 -0
- package/src/host-mcp-bindings.ts +226 -0
- package/src/index.ts +158 -68
- package/dist/chunk-QP3BIGSC.js.map +0 -1
- /package/dist/{chunk-NPYLOZAP.js.map → chunk-5LYFSZ7O.js.map} +0 -0
- /package/dist/{chunk-6TCVR53X.js.map → chunk-O5LEQHDM.js.map} +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// src/permissions.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var Permission = z.enum([
|
|
4
|
+
"account:read",
|
|
5
|
+
"account:admin",
|
|
6
|
+
"members:manage",
|
|
7
|
+
"workspace:create",
|
|
8
|
+
"billing:read",
|
|
9
|
+
"billing:manage",
|
|
10
|
+
"workspace:read",
|
|
11
|
+
"workspace:admin",
|
|
12
|
+
"sessions:create",
|
|
13
|
+
"sessions:read",
|
|
14
|
+
"sessions:control",
|
|
15
|
+
"stream:view",
|
|
16
|
+
"stream:control",
|
|
17
|
+
"stream:acknowledge",
|
|
18
|
+
"files:upload",
|
|
19
|
+
"files:read",
|
|
20
|
+
"files:write",
|
|
21
|
+
"terminal:attach",
|
|
22
|
+
"documents:manage",
|
|
23
|
+
"documents:search",
|
|
24
|
+
"scheduled_tasks:manage",
|
|
25
|
+
"scheduled_tasks:run",
|
|
26
|
+
"github:manage",
|
|
27
|
+
"github:use",
|
|
28
|
+
"api_keys:manage",
|
|
29
|
+
"connections:read",
|
|
30
|
+
"connections:write",
|
|
31
|
+
"capabilities:manage",
|
|
32
|
+
/** @deprecated alias of variable-sets:manage */
|
|
33
|
+
"environments:manage",
|
|
34
|
+
/** @deprecated alias of variable-sets:use */
|
|
35
|
+
"environments:use",
|
|
36
|
+
"variable-sets:list",
|
|
37
|
+
"variable-sets:read",
|
|
38
|
+
"variable-sets:write",
|
|
39
|
+
"variable-sets:manage",
|
|
40
|
+
"variable-sets:attach",
|
|
41
|
+
"variable-sets:use",
|
|
42
|
+
"secrets:list",
|
|
43
|
+
"secrets:read",
|
|
44
|
+
"secrets:write",
|
|
45
|
+
"mcp_servers:attach",
|
|
46
|
+
"codemode:call",
|
|
47
|
+
"goals:manage",
|
|
48
|
+
"enrollments:read",
|
|
49
|
+
"enrollments:manage",
|
|
50
|
+
"rigs:use",
|
|
51
|
+
"rigs:manage",
|
|
52
|
+
"artifacts:read",
|
|
53
|
+
"artifacts:publish"
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
Permission
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=chunk-P3HLDT77.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/permissions.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/** Canonical public permission vocabulary shared by operational and control-plane contracts. */\nexport const Permission = z.enum([\n \"account:read\",\n \"account:admin\",\n \"members:manage\",\n \"workspace:create\",\n \"billing:read\",\n \"billing:manage\",\n \"workspace:read\",\n \"workspace:admin\",\n \"sessions:create\",\n \"sessions:read\",\n \"sessions:control\",\n \"stream:view\",\n \"stream:control\",\n \"stream:acknowledge\",\n \"files:upload\",\n \"files:read\",\n \"files:write\",\n \"terminal:attach\",\n \"documents:manage\",\n \"documents:search\",\n \"scheduled_tasks:manage\",\n \"scheduled_tasks:run\",\n \"github:manage\",\n \"github:use\",\n \"api_keys:manage\",\n \"connections:read\",\n \"connections:write\",\n \"capabilities:manage\",\n /** @deprecated alias of variable-sets:manage */\n \"environments:manage\",\n /** @deprecated alias of variable-sets:use */\n \"environments:use\",\n \"variable-sets:list\",\n \"variable-sets:read\",\n \"variable-sets:write\",\n \"variable-sets:manage\",\n \"variable-sets:attach\",\n \"variable-sets:use\",\n \"secrets:list\",\n \"secrets:read\",\n \"secrets:write\",\n \"mcp_servers:attach\",\n \"codemode:call\",\n \"goals:manage\",\n \"enrollments:read\",\n \"enrollments:manage\",\n \"rigs:use\",\n \"rigs:manage\",\n \"artifacts:read\",\n \"artifacts:publish\",\n]);\nexport type Permission = z.infer<typeof Permission>;\n"],"mappings":";AAAA,SAAS,SAAS;AAGX,IAAM,aAAa,EAAE,KAAK;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;","names":[]}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConnectionKind,
|
|
3
|
+
ManagedUserResourceGrantMode,
|
|
4
|
+
SessionTenancyVisibility,
|
|
5
|
+
UserResourceAuthorityGrant,
|
|
6
|
+
UserResourceDelegation
|
|
7
|
+
} from "./chunk-OO4AEMQB.js";
|
|
8
|
+
|
|
9
|
+
// src/connection-authority.ts
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
var ConnectionUseAction = z.literal("connection.use");
|
|
12
|
+
var ConnectionAuthorityEnvelope = z.object({
|
|
13
|
+
scope: z.enum(["workspace", "user"]).default("workspace"),
|
|
14
|
+
userDelegation: UserResourceDelegation.optional()
|
|
15
|
+
}).strict().superRefine((value, context) => {
|
|
16
|
+
if (value.scope === "workspace" && value.userDelegation !== void 0) {
|
|
17
|
+
context.addIssue({
|
|
18
|
+
code: "custom",
|
|
19
|
+
path: ["userDelegation"],
|
|
20
|
+
message: "workspace connections cannot carry user delegation"
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (value.scope === "user" && value.userDelegation === void 0) {
|
|
25
|
+
context.addIssue({
|
|
26
|
+
code: "custom",
|
|
27
|
+
path: ["userDelegation"],
|
|
28
|
+
message: "user connections require an immutable delegation"
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (value.userDelegation && value.userDelegation.action !== ConnectionUseAction.value) {
|
|
33
|
+
context.addIssue({
|
|
34
|
+
code: "custom",
|
|
35
|
+
path: ["userDelegation", "action"],
|
|
36
|
+
message: "connection delegation must use connection.use"
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
var ConnectionAuthorityGrant = UserResourceAuthorityGrant.extend({
|
|
41
|
+
action: ConnectionUseAction
|
|
42
|
+
}).strict();
|
|
43
|
+
var ConnectionAuthoritySummary = z.object({
|
|
44
|
+
authorityId: z.string().uuid(),
|
|
45
|
+
resourceId: z.string().uuid(),
|
|
46
|
+
originWorkspaceId: z.string().uuid().nullable(),
|
|
47
|
+
generation: z.number().int().positive(),
|
|
48
|
+
status: z.enum(["active", "retained", "revoked"]),
|
|
49
|
+
grants: z.array(ConnectionAuthorityGrant)
|
|
50
|
+
}).strict();
|
|
51
|
+
var ListConnectionAuthoritiesQuery = z.object({
|
|
52
|
+
scope: z.literal("user"),
|
|
53
|
+
cursor: z.string().uuid().optional(),
|
|
54
|
+
limit: z.coerce.number().int().min(1).max(100).default(50)
|
|
55
|
+
}).strict();
|
|
56
|
+
var ListConnectionAuthoritiesResponse = z.object({
|
|
57
|
+
scope: z.literal("user"),
|
|
58
|
+
authorities: z.array(ConnectionAuthoritySummary),
|
|
59
|
+
nextCursor: z.string().uuid().nullable()
|
|
60
|
+
}).strict();
|
|
61
|
+
var IssueConnectionUseGrantRequest = z.object({
|
|
62
|
+
scope: z.literal("user"),
|
|
63
|
+
mode: ManagedUserResourceGrantMode,
|
|
64
|
+
context: SessionTenancyVisibility,
|
|
65
|
+
sessionId: z.string().uuid().nullable().optional(),
|
|
66
|
+
expectedAuthorityEpoch: z.number().int().positive().nullable().optional(),
|
|
67
|
+
workspaceSharedAcknowledged: z.boolean().default(false)
|
|
68
|
+
}).strict().superRefine((value, context) => {
|
|
69
|
+
if (value.context === "workspace_shared" && !value.workspaceSharedAcknowledged) {
|
|
70
|
+
context.addIssue({
|
|
71
|
+
code: "custom",
|
|
72
|
+
path: ["workspaceSharedAcknowledged"],
|
|
73
|
+
message: "workspace_shared requires durable shared-output acknowledgement"
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (value.mode === "always" && (value.sessionId || value.expectedAuthorityEpoch)) {
|
|
77
|
+
context.addIssue({ code: "custom", path: ["sessionId"], message: "always is unbound" });
|
|
78
|
+
}
|
|
79
|
+
if (value.mode === "session" && (!value.sessionId || !value.expectedAuthorityEpoch)) {
|
|
80
|
+
context.addIssue({
|
|
81
|
+
code: "custom",
|
|
82
|
+
path: ["sessionId"],
|
|
83
|
+
message: "session requires a target session and expectedAuthorityEpoch"
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
var RevokeConnectionUseGrantQuery = z.object({ scope: z.literal("user") }).strict();
|
|
88
|
+
var ConnectionUseGrantMutationResponse = z.object({
|
|
89
|
+
scope: z.literal("user"),
|
|
90
|
+
grant: ConnectionAuthorityGrant
|
|
91
|
+
}).strict();
|
|
92
|
+
var ConnectionUseGrantRevocationResponse = z.object({
|
|
93
|
+
scope: z.literal("user"),
|
|
94
|
+
grant: z.object({
|
|
95
|
+
grantId: z.string().uuid(),
|
|
96
|
+
generation: z.number().int().positive(),
|
|
97
|
+
status: z.literal("revoked"),
|
|
98
|
+
revokedAt: z.string().datetime()
|
|
99
|
+
}).strict()
|
|
100
|
+
}).strict();
|
|
101
|
+
var ConnectionAuthoritySelectionSource = z.enum([
|
|
102
|
+
"explicit_workspace",
|
|
103
|
+
"legacy_workspace_omission",
|
|
104
|
+
"legacy_user_compatibility",
|
|
105
|
+
"user_delegation"
|
|
106
|
+
]);
|
|
107
|
+
var ConnectionUseSelectionSource = z.string().min(1).max(128).regex(/^[a-z0-9](?:[a-z0-9._:-]*[a-z0-9])?$/u);
|
|
108
|
+
var AcceptedConnectionWork = z.discriminatedUnion("kind", [
|
|
109
|
+
z.object({
|
|
110
|
+
kind: z.literal("turn"),
|
|
111
|
+
turnId: z.string().uuid()
|
|
112
|
+
}).strict(),
|
|
113
|
+
z.object({
|
|
114
|
+
kind: z.literal("scheduled_task"),
|
|
115
|
+
taskId: z.string().uuid(),
|
|
116
|
+
taskAuthorityRevision: z.number().int().positive(),
|
|
117
|
+
runId: z.string().uuid()
|
|
118
|
+
}).strict()
|
|
119
|
+
]);
|
|
120
|
+
var ConnectionUseAuthoritySnapshot = z.object({
|
|
121
|
+
organizationId: z.string().uuid(),
|
|
122
|
+
originWorkspaceId: z.string().uuid(),
|
|
123
|
+
targetWorkspaceId: z.string().uuid(),
|
|
124
|
+
targetSessionId: z.string().uuid(),
|
|
125
|
+
targetSessionVisibility: SessionTenancyVisibility,
|
|
126
|
+
targetSessionAuthorityEpoch: z.number().int().positive(),
|
|
127
|
+
acceptedWork: AcceptedConnectionWork,
|
|
128
|
+
connectionId: z.string().uuid(),
|
|
129
|
+
connectionGeneration: z.number().int().positive(),
|
|
130
|
+
connectionStatus: z.literal("active"),
|
|
131
|
+
providerDomain: z.string().min(1).max(2048),
|
|
132
|
+
connectionKind: ConnectionKind,
|
|
133
|
+
scope: z.enum(["workspace", "user", "legacy_user"]),
|
|
134
|
+
ownerSubjectId: z.string().min(1).max(512).nullable(),
|
|
135
|
+
ownerOrganizationMembershipId: z.string().uuid().nullable(),
|
|
136
|
+
ownerMembershipAuthorizationRevision: z.number().int().positive().nullable().default(null),
|
|
137
|
+
authoritySource: ConnectionAuthoritySelectionSource,
|
|
138
|
+
selectionSources: z.array(ConnectionUseSelectionSource).min(1).max(128),
|
|
139
|
+
userDelegation: UserResourceDelegation.nullable()
|
|
140
|
+
}).strict().superRefine((value, context) => {
|
|
141
|
+
const ownedBySubject = value.scope !== "workspace";
|
|
142
|
+
const delegated = value.scope === "user";
|
|
143
|
+
if (ownedBySubject !== (value.ownerSubjectId !== null)) {
|
|
144
|
+
context.addIssue({
|
|
145
|
+
code: "custom",
|
|
146
|
+
path: ["ownerSubjectId"],
|
|
147
|
+
message: "personal connections retain an owner subject"
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (delegated !== (value.ownerOrganizationMembershipId !== null)) {
|
|
151
|
+
context.addIssue({
|
|
152
|
+
code: "custom",
|
|
153
|
+
path: ["ownerOrganizationMembershipId"],
|
|
154
|
+
message: "only user connections retain an owner membership"
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (delegated !== (value.ownerMembershipAuthorizationRevision !== null)) {
|
|
158
|
+
context.addIssue({
|
|
159
|
+
code: "custom",
|
|
160
|
+
path: ["ownerMembershipAuthorizationRevision"],
|
|
161
|
+
message: "only user connections retain an owner membership revision"
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (delegated !== (value.userDelegation !== null)) {
|
|
165
|
+
context.addIssue({
|
|
166
|
+
code: "custom",
|
|
167
|
+
path: ["userDelegation"],
|
|
168
|
+
message: "only user connections retain a delegation"
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (delegated && value.authoritySource !== "user_delegation") {
|
|
172
|
+
context.addIssue({
|
|
173
|
+
code: "custom",
|
|
174
|
+
path: ["authoritySource"],
|
|
175
|
+
message: "user connections require user_delegation provenance"
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
if (!delegated && value.authoritySource === "user_delegation") {
|
|
179
|
+
context.addIssue({
|
|
180
|
+
code: "custom",
|
|
181
|
+
path: ["authoritySource"],
|
|
182
|
+
message: "non-delegated connections cannot claim user delegation provenance"
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (value.scope === "legacy_user" && value.authoritySource !== "legacy_user_compatibility") {
|
|
186
|
+
context.addIssue({
|
|
187
|
+
code: "custom",
|
|
188
|
+
path: ["authoritySource"],
|
|
189
|
+
message: "legacy user connections require explicit compatibility provenance"
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (value.scope === "workspace" && value.authoritySource === "legacy_user_compatibility") {
|
|
193
|
+
context.addIssue({
|
|
194
|
+
code: "custom",
|
|
195
|
+
path: ["authoritySource"],
|
|
196
|
+
message: "workspace connections cannot claim legacy user provenance"
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (!delegated && value.originWorkspaceId !== value.targetWorkspaceId) {
|
|
200
|
+
context.addIssue({
|
|
201
|
+
code: "custom",
|
|
202
|
+
path: ["originWorkspaceId"],
|
|
203
|
+
message: "workspace connections must be owned by the target workspace"
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const delegation = value.userDelegation;
|
|
207
|
+
if (!delegation) return;
|
|
208
|
+
const exactFacts = [
|
|
209
|
+
[
|
|
210
|
+
delegation.organizationId === value.organizationId,
|
|
211
|
+
["userDelegation", "organizationId"],
|
|
212
|
+
"delegation organization mismatch"
|
|
213
|
+
],
|
|
214
|
+
[
|
|
215
|
+
delegation.workspaceId === value.targetWorkspaceId,
|
|
216
|
+
["userDelegation", "workspaceId"],
|
|
217
|
+
"delegation target workspace mismatch"
|
|
218
|
+
],
|
|
219
|
+
[
|
|
220
|
+
delegation.action === ConnectionUseAction.value,
|
|
221
|
+
["userDelegation", "action"],
|
|
222
|
+
"delegation action mismatch"
|
|
223
|
+
],
|
|
224
|
+
[
|
|
225
|
+
delegation.context === value.targetSessionVisibility,
|
|
226
|
+
["userDelegation", "context"],
|
|
227
|
+
"delegation visibility mismatch"
|
|
228
|
+
]
|
|
229
|
+
];
|
|
230
|
+
for (const [matches, path, message] of exactFacts) {
|
|
231
|
+
if (!matches) context.addIssue({ code: "custom", path, message });
|
|
232
|
+
}
|
|
233
|
+
if (delegation.sessionId !== null && delegation.sessionId !== value.targetSessionId) {
|
|
234
|
+
context.addIssue({
|
|
235
|
+
code: "custom",
|
|
236
|
+
path: ["userDelegation", "sessionId"],
|
|
237
|
+
message: "delegation session mismatch"
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (delegation.authorityEpoch !== null && delegation.authorityEpoch !== value.targetSessionAuthorityEpoch) {
|
|
241
|
+
context.addIssue({
|
|
242
|
+
code: "custom",
|
|
243
|
+
path: ["userDelegation", "authorityEpoch"],
|
|
244
|
+
message: "delegation authority epoch mismatch"
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
var ConnectionUseDenialReason = z.enum([
|
|
249
|
+
"tenant_mismatch",
|
|
250
|
+
"workspace_access_inactive",
|
|
251
|
+
"session_inactive",
|
|
252
|
+
"session_identity_changed",
|
|
253
|
+
"session_visibility_changed",
|
|
254
|
+
"session_authority_epoch_changed",
|
|
255
|
+
"accepted_attempt_authority_required",
|
|
256
|
+
"accepted_snapshot_digest_changed",
|
|
257
|
+
"connection_missing",
|
|
258
|
+
"connection_identity_changed",
|
|
259
|
+
"connection_generation_changed",
|
|
260
|
+
"connection_status_inactive",
|
|
261
|
+
"connection_owner_changed",
|
|
262
|
+
"owner_membership_inactive",
|
|
263
|
+
"authority_missing",
|
|
264
|
+
"authority_identity_changed",
|
|
265
|
+
"authority_generation_changed",
|
|
266
|
+
"authority_status_inactive",
|
|
267
|
+
"grant_missing",
|
|
268
|
+
"grant_identity_changed",
|
|
269
|
+
"grant_generation_changed",
|
|
270
|
+
"grant_status_inactive",
|
|
271
|
+
"grant_expired",
|
|
272
|
+
"grant_already_consumed"
|
|
273
|
+
]);
|
|
274
|
+
var ConnectionUseAttributionFields = z.object({
|
|
275
|
+
organizationId: z.string().uuid(),
|
|
276
|
+
workspaceId: z.string().uuid(),
|
|
277
|
+
sessionId: z.string().uuid(),
|
|
278
|
+
connectionId: z.string().uuid(),
|
|
279
|
+
connectionGeneration: z.number().int().positive(),
|
|
280
|
+
scope: z.enum(["workspace", "user", "legacy_user"]),
|
|
281
|
+
ownerSubjectId: z.string().min(1).max(512).nullable(),
|
|
282
|
+
authorityId: z.string().uuid().nullable(),
|
|
283
|
+
grantId: z.string().uuid().nullable()
|
|
284
|
+
}).strict();
|
|
285
|
+
function refineConnectionUseAttribution(value, context) {
|
|
286
|
+
const personal = value.scope !== "workspace";
|
|
287
|
+
for (const field of ["ownerSubjectId"]) {
|
|
288
|
+
if (personal !== (value[field] !== null)) {
|
|
289
|
+
context.addIssue({
|
|
290
|
+
code: "custom",
|
|
291
|
+
path: [field],
|
|
292
|
+
message: personal ? `personal attribution requires ${field}` : `workspace attribution cannot carry ${field}`
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const delegated = value.scope === "user";
|
|
297
|
+
for (const field of ["authorityId", "grantId"]) {
|
|
298
|
+
if (delegated !== (value[field] !== null)) {
|
|
299
|
+
context.addIssue({
|
|
300
|
+
code: "custom",
|
|
301
|
+
path: [field],
|
|
302
|
+
message: delegated ? `delegated personal attribution requires ${field}` : `non-delegated attribution cannot carry ${field}`
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
var ConnectionUseAttribution = ConnectionUseAttributionFields.superRefine(
|
|
308
|
+
refineConnectionUseAttribution
|
|
309
|
+
);
|
|
310
|
+
var ConnectionUseAuditFact = ConnectionUseAttributionFields.extend({
|
|
311
|
+
outcome: z.enum(["authorized", "denied"]),
|
|
312
|
+
denialReason: ConnectionUseDenialReason.nullable(),
|
|
313
|
+
occurredAt: z.string().datetime({ offset: true })
|
|
314
|
+
}).superRefine((value, context) => {
|
|
315
|
+
refineConnectionUseAttribution(value, context);
|
|
316
|
+
if (value.outcome === "denied" !== (value.denialReason !== null)) {
|
|
317
|
+
context.addIssue({
|
|
318
|
+
code: "custom",
|
|
319
|
+
path: ["denialReason"],
|
|
320
|
+
message: "only denied connection use carries a denial reason"
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
var ConnectionUseAuthorizationResult = z.discriminatedUnion("status", [
|
|
325
|
+
z.object({ status: z.literal("authorized"), attribution: ConnectionUseAttribution }).strict(),
|
|
326
|
+
z.object({ status: z.literal("denied"), reason: ConnectionUseDenialReason }).strict()
|
|
327
|
+
]);
|
|
328
|
+
|
|
329
|
+
export {
|
|
330
|
+
ConnectionUseAction,
|
|
331
|
+
ConnectionAuthorityEnvelope,
|
|
332
|
+
ConnectionAuthorityGrant,
|
|
333
|
+
ConnectionAuthoritySummary,
|
|
334
|
+
ListConnectionAuthoritiesQuery,
|
|
335
|
+
ListConnectionAuthoritiesResponse,
|
|
336
|
+
IssueConnectionUseGrantRequest,
|
|
337
|
+
RevokeConnectionUseGrantQuery,
|
|
338
|
+
ConnectionUseGrantMutationResponse,
|
|
339
|
+
ConnectionUseGrantRevocationResponse,
|
|
340
|
+
ConnectionAuthoritySelectionSource,
|
|
341
|
+
ConnectionUseSelectionSource,
|
|
342
|
+
ConnectionUseAuthoritySnapshot,
|
|
343
|
+
ConnectionUseDenialReason,
|
|
344
|
+
ConnectionUseAttribution,
|
|
345
|
+
ConnectionUseAuditFact,
|
|
346
|
+
ConnectionUseAuthorizationResult
|
|
347
|
+
};
|
|
348
|
+
//# sourceMappingURL=chunk-SSWEWU3V.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connection-authority.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n ConnectionKind,\n ManagedUserResourceGrantMode,\n SessionTenancyVisibility,\n UserResourceAuthorityGrant,\n UserResourceDelegation,\n} from \"./index\";\n\n/** The only generic grant action that authorizes use of a connection. */\nexport const ConnectionUseAction = z.literal(\"connection.use\");\nexport type ConnectionUseAction = z.infer<typeof ConnectionUseAction>;\n\n/**\n * Connection authority is either workspace-owned or user-owned. Omission is\n * intentionally compatible with the historical workspace connection path.\n */\nexport const ConnectionAuthorityEnvelope = z\n .object({\n scope: z.enum([\"workspace\", \"user\"]).default(\"workspace\"),\n userDelegation: UserResourceDelegation.optional(),\n })\n .strict()\n .superRefine((value, context) => {\n if (value.scope === \"workspace\" && value.userDelegation !== undefined) {\n context.addIssue({\n code: \"custom\",\n path: [\"userDelegation\"],\n message: \"workspace connections cannot carry user delegation\",\n });\n return;\n }\n if (value.scope === \"user\" && value.userDelegation === undefined) {\n context.addIssue({\n code: \"custom\",\n path: [\"userDelegation\"],\n message: \"user connections require an immutable delegation\",\n });\n return;\n }\n if (value.userDelegation && value.userDelegation.action !== ConnectionUseAction.value) {\n context.addIssue({\n code: \"custom\",\n path: [\"userDelegation\", \"action\"],\n message: \"connection delegation must use connection.use\",\n });\n }\n });\nexport type ConnectionAuthorityEnvelope = z.infer<typeof ConnectionAuthorityEnvelope>;\n\nexport const ConnectionAuthorityGrant = UserResourceAuthorityGrant.extend({\n action: ConnectionUseAction,\n}).strict();\nexport type ConnectionAuthorityGrant = z.infer<typeof ConnectionAuthorityGrant>;\n\n/** Owner-only opaque projection; connection identity and owner metadata stay server-side. */\nexport const ConnectionAuthoritySummary = z\n .object({\n authorityId: z.string().uuid(),\n resourceId: z.string().uuid(),\n originWorkspaceId: z.string().uuid().nullable(),\n generation: z.number().int().positive(),\n status: z.enum([\"active\", \"retained\", \"revoked\"]),\n grants: z.array(ConnectionAuthorityGrant),\n })\n .strict();\nexport type ConnectionAuthoritySummary = z.infer<typeof ConnectionAuthoritySummary>;\n\nexport const ListConnectionAuthoritiesQuery = z\n .object({\n scope: z.literal(\"user\"),\n cursor: z.string().uuid().optional(),\n limit: z.coerce.number().int().min(1).max(100).default(50),\n })\n .strict();\nexport const ListConnectionAuthoritiesResponse = z\n .object({\n scope: z.literal(\"user\"),\n authorities: z.array(ConnectionAuthoritySummary),\n nextCursor: z.string().uuid().nullable(),\n })\n .strict();\n\nexport const IssueConnectionUseGrantRequest = z\n .object({\n scope: z.literal(\"user\"),\n mode: ManagedUserResourceGrantMode,\n context: SessionTenancyVisibility,\n sessionId: z.string().uuid().nullable().optional(),\n expectedAuthorityEpoch: z.number().int().positive().nullable().optional(),\n workspaceSharedAcknowledged: z.boolean().default(false),\n })\n .strict()\n .superRefine((value, context) => {\n if (value.context === \"workspace_shared\" && !value.workspaceSharedAcknowledged) {\n context.addIssue({\n code: \"custom\",\n path: [\"workspaceSharedAcknowledged\"],\n message: \"workspace_shared requires durable shared-output acknowledgement\",\n });\n }\n if (value.mode === \"always\" && (value.sessionId || value.expectedAuthorityEpoch)) {\n context.addIssue({ code: \"custom\", path: [\"sessionId\"], message: \"always is unbound\" });\n }\n if (value.mode === \"session\" && (!value.sessionId || !value.expectedAuthorityEpoch)) {\n context.addIssue({\n code: \"custom\",\n path: [\"sessionId\"],\n message: \"session requires a target session and expectedAuthorityEpoch\",\n });\n }\n });\nexport type IssueConnectionUseGrantRequest = z.infer<typeof IssueConnectionUseGrantRequest>;\n\nexport const RevokeConnectionUseGrantQuery = z.object({ scope: z.literal(\"user\") }).strict();\n\nexport const ConnectionUseGrantMutationResponse = z\n .object({\n scope: z.literal(\"user\"),\n grant: ConnectionAuthorityGrant,\n })\n .strict();\nexport type ConnectionUseGrantMutationResponse = z.infer<typeof ConnectionUseGrantMutationResponse>;\n\nexport const ConnectionUseGrantRevocationResponse = z\n .object({\n scope: z.literal(\"user\"),\n grant: z\n .object({\n grantId: z.string().uuid(),\n generation: z.number().int().positive(),\n status: z.literal(\"revoked\"),\n revokedAt: z.string().datetime(),\n })\n .strict(),\n })\n .strict();\nexport type ConnectionUseGrantRevocationResponse = z.infer<\n typeof ConnectionUseGrantRevocationResponse\n>;\n\nexport const ConnectionAuthoritySelectionSource = z.enum([\n \"explicit_workspace\",\n \"legacy_workspace_omission\",\n \"legacy_user_compatibility\",\n \"user_delegation\",\n]);\nexport type ConnectionAuthoritySelectionSource = z.infer<typeof ConnectionAuthoritySelectionSource>;\n\nexport const ConnectionUseSelectionSource = z\n .string()\n .min(1)\n .max(128)\n .regex(/^[a-z0-9](?:[a-z0-9._:-]*[a-z0-9])?$/u);\nexport type ConnectionUseSelectionSource = z.infer<typeof ConnectionUseSelectionSource>;\n\nconst AcceptedConnectionWork = z.discriminatedUnion(\"kind\", [\n z\n .object({\n kind: z.literal(\"turn\"),\n turnId: z.string().uuid(),\n })\n .strict(),\n z\n .object({\n kind: z.literal(\"scheduled_task\"),\n taskId: z.string().uuid(),\n taskAuthorityRevision: z.number().int().positive(),\n runId: z.string().uuid(),\n })\n .strict(),\n]);\n\n/**\n * Internal, credential-free authority frozen when work is accepted. Personal\n * owner identity is retained only for live authorization and usage/audit\n * attribution; it is never part of the public delegation envelope.\n */\nexport const ConnectionUseAuthoritySnapshot = z\n .object({\n organizationId: z.string().uuid(),\n originWorkspaceId: z.string().uuid(),\n targetWorkspaceId: z.string().uuid(),\n targetSessionId: z.string().uuid(),\n targetSessionVisibility: SessionTenancyVisibility,\n targetSessionAuthorityEpoch: z.number().int().positive(),\n acceptedWork: AcceptedConnectionWork,\n connectionId: z.string().uuid(),\n connectionGeneration: z.number().int().positive(),\n connectionStatus: z.literal(\"active\"),\n providerDomain: z.string().min(1).max(2048),\n connectionKind: ConnectionKind,\n scope: z.enum([\"workspace\", \"user\", \"legacy_user\"]),\n ownerSubjectId: z.string().min(1).max(512).nullable(),\n ownerOrganizationMembershipId: z.string().uuid().nullable(),\n ownerMembershipAuthorizationRevision: z.number().int().positive().nullable().default(null),\n authoritySource: ConnectionAuthoritySelectionSource,\n selectionSources: z.array(ConnectionUseSelectionSource).min(1).max(128),\n userDelegation: UserResourceDelegation.nullable(),\n })\n .strict()\n .superRefine((value, context) => {\n const ownedBySubject = value.scope !== \"workspace\";\n const delegated = value.scope === \"user\";\n if (ownedBySubject !== (value.ownerSubjectId !== null)) {\n context.addIssue({\n code: \"custom\",\n path: [\"ownerSubjectId\"],\n message: \"personal connections retain an owner subject\",\n });\n }\n if (delegated !== (value.ownerOrganizationMembershipId !== null)) {\n context.addIssue({\n code: \"custom\",\n path: [\"ownerOrganizationMembershipId\"],\n message: \"only user connections retain an owner membership\",\n });\n }\n if (delegated !== (value.ownerMembershipAuthorizationRevision !== null)) {\n context.addIssue({\n code: \"custom\",\n path: [\"ownerMembershipAuthorizationRevision\"],\n message: \"only user connections retain an owner membership revision\",\n });\n }\n if (delegated !== (value.userDelegation !== null)) {\n context.addIssue({\n code: \"custom\",\n path: [\"userDelegation\"],\n message: \"only user connections retain a delegation\",\n });\n }\n if (delegated && value.authoritySource !== \"user_delegation\") {\n context.addIssue({\n code: \"custom\",\n path: [\"authoritySource\"],\n message: \"user connections require user_delegation provenance\",\n });\n }\n if (!delegated && value.authoritySource === \"user_delegation\") {\n context.addIssue({\n code: \"custom\",\n path: [\"authoritySource\"],\n message: \"non-delegated connections cannot claim user delegation provenance\",\n });\n }\n if (value.scope === \"legacy_user\" && value.authoritySource !== \"legacy_user_compatibility\") {\n context.addIssue({\n code: \"custom\",\n path: [\"authoritySource\"],\n message: \"legacy user connections require explicit compatibility provenance\",\n });\n }\n if (value.scope === \"workspace\" && value.authoritySource === \"legacy_user_compatibility\") {\n context.addIssue({\n code: \"custom\",\n path: [\"authoritySource\"],\n message: \"workspace connections cannot claim legacy user provenance\",\n });\n }\n if (!delegated && value.originWorkspaceId !== value.targetWorkspaceId) {\n context.addIssue({\n code: \"custom\",\n path: [\"originWorkspaceId\"],\n message: \"workspace connections must be owned by the target workspace\",\n });\n }\n const delegation = value.userDelegation;\n if (!delegation) return;\n const exactFacts: Array<[boolean, (string | number)[], string]> = [\n [\n delegation.organizationId === value.organizationId,\n [\"userDelegation\", \"organizationId\"],\n \"delegation organization mismatch\",\n ],\n [\n delegation.workspaceId === value.targetWorkspaceId,\n [\"userDelegation\", \"workspaceId\"],\n \"delegation target workspace mismatch\",\n ],\n [\n delegation.action === ConnectionUseAction.value,\n [\"userDelegation\", \"action\"],\n \"delegation action mismatch\",\n ],\n [\n delegation.context === value.targetSessionVisibility,\n [\"userDelegation\", \"context\"],\n \"delegation visibility mismatch\",\n ],\n ];\n for (const [matches, path, message] of exactFacts) {\n if (!matches) context.addIssue({ code: \"custom\", path, message });\n }\n if (delegation.sessionId !== null && delegation.sessionId !== value.targetSessionId) {\n context.addIssue({\n code: \"custom\",\n path: [\"userDelegation\", \"sessionId\"],\n message: \"delegation session mismatch\",\n });\n }\n if (\n delegation.authorityEpoch !== null &&\n delegation.authorityEpoch !== value.targetSessionAuthorityEpoch\n ) {\n context.addIssue({\n code: \"custom\",\n path: [\"userDelegation\", \"authorityEpoch\"],\n message: \"delegation authority epoch mismatch\",\n });\n }\n });\nexport type ConnectionUseAuthoritySnapshot = z.infer<typeof ConnectionUseAuthoritySnapshot>;\n\nexport const ConnectionUseDenialReason = z.enum([\n \"tenant_mismatch\",\n \"workspace_access_inactive\",\n \"session_inactive\",\n \"session_identity_changed\",\n \"session_visibility_changed\",\n \"session_authority_epoch_changed\",\n \"accepted_attempt_authority_required\",\n \"accepted_snapshot_digest_changed\",\n \"connection_missing\",\n \"connection_identity_changed\",\n \"connection_generation_changed\",\n \"connection_status_inactive\",\n \"connection_owner_changed\",\n \"owner_membership_inactive\",\n \"authority_missing\",\n \"authority_identity_changed\",\n \"authority_generation_changed\",\n \"authority_status_inactive\",\n \"grant_missing\",\n \"grant_identity_changed\",\n \"grant_generation_changed\",\n \"grant_status_inactive\",\n \"grant_expired\",\n \"grant_already_consumed\",\n]);\nexport type ConnectionUseDenialReason = z.infer<typeof ConnectionUseDenialReason>;\n\nconst ConnectionUseAttributionFields = z\n .object({\n organizationId: z.string().uuid(),\n workspaceId: z.string().uuid(),\n sessionId: z.string().uuid(),\n connectionId: z.string().uuid(),\n connectionGeneration: z.number().int().positive(),\n scope: z.enum([\"workspace\", \"user\", \"legacy_user\"]),\n ownerSubjectId: z.string().min(1).max(512).nullable(),\n authorityId: z.string().uuid().nullable(),\n grantId: z.string().uuid().nullable(),\n })\n .strict();\n\nfunction refineConnectionUseAttribution(\n value: z.infer<typeof ConnectionUseAttributionFields>,\n context: z.RefinementCtx,\n): void {\n const personal = value.scope !== \"workspace\";\n for (const field of [\"ownerSubjectId\"] as const) {\n if (personal !== (value[field] !== null)) {\n context.addIssue({\n code: \"custom\",\n path: [field],\n message: personal\n ? `personal attribution requires ${field}`\n : `workspace attribution cannot carry ${field}`,\n });\n }\n }\n const delegated = value.scope === \"user\";\n for (const field of [\"authorityId\", \"grantId\"] as const) {\n if (delegated !== (value[field] !== null)) {\n context.addIssue({\n code: \"custom\",\n path: [field],\n message: delegated\n ? `delegated personal attribution requires ${field}`\n : `non-delegated attribution cannot carry ${field}`,\n });\n }\n }\n}\n\n/** Metadata-only attribution emitted after pre-use authorization. */\nexport const ConnectionUseAttribution = ConnectionUseAttributionFields.superRefine(\n refineConnectionUseAttribution,\n);\nexport type ConnectionUseAttribution = z.infer<typeof ConnectionUseAttribution>;\n\nexport const ConnectionUseAuditFact = ConnectionUseAttributionFields.extend({\n outcome: z.enum([\"authorized\", \"denied\"]),\n denialReason: ConnectionUseDenialReason.nullable(),\n occurredAt: z.string().datetime({ offset: true }),\n}).superRefine((value, context) => {\n refineConnectionUseAttribution(value, context);\n if ((value.outcome === \"denied\") !== (value.denialReason !== null)) {\n context.addIssue({\n code: \"custom\",\n path: [\"denialReason\"],\n message: \"only denied connection use carries a denial reason\",\n });\n }\n});\nexport type ConnectionUseAuditFact = z.infer<typeof ConnectionUseAuditFact>;\n\nexport const ConnectionUseAuthorizationResult = z.discriminatedUnion(\"status\", [\n z.object({ status: z.literal(\"authorized\"), attribution: ConnectionUseAttribution }).strict(),\n z.object({ status: z.literal(\"denied\"), reason: ConnectionUseDenialReason }).strict(),\n]);\nexport type ConnectionUseAuthorizationResult = z.infer<typeof ConnectionUseAuthorizationResult>;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Permission
|
|
3
|
+
} from "./chunk-P3HLDT77.js";
|
|
4
|
+
|
|
5
|
+
// src/external-identities.ts
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
var encoder = new TextEncoder();
|
|
8
|
+
function opaqueText(maxBytes) {
|
|
9
|
+
return z.string().min(1).max(maxBytes).refine(
|
|
10
|
+
(value) => !value.includes("\0") && !/[\uD800-\uDFFF]/u.test(value) && encoder.encode(value).byteLength <= maxBytes,
|
|
11
|
+
{
|
|
12
|
+
message: `Identifier must be valid PostgreSQL Unicode text of at most ${maxBytes} UTF-8 bytes`
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
var externalId = opaqueText(1024);
|
|
17
|
+
var source = opaqueText(200);
|
|
18
|
+
var externalSubject = z.string().regex(/^external_user:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$(?![\s\S])/);
|
|
19
|
+
var nativeSubject = z.string().min(1).max(1024).regex(/^user:[^\r\n]+$(?![\s\S])/);
|
|
20
|
+
var ExternalIdentityReference = z.object({
|
|
21
|
+
externalId,
|
|
22
|
+
source: source.default("default")
|
|
23
|
+
}).strict();
|
|
24
|
+
var AddExternalWorkspaceMemberRequest = z.object({
|
|
25
|
+
identity: ExternalIdentityReference,
|
|
26
|
+
permissions: z.array(Permission).min(1).max(Permission.options.length)
|
|
27
|
+
}).strict();
|
|
28
|
+
var UpdateExternalIdentityMembershipRequest = z.object({
|
|
29
|
+
kind: z.enum(["suspend", "reactivate", "offboard"]),
|
|
30
|
+
expectedAuthorizationRevision: z.number().int().positive().safe(),
|
|
31
|
+
operationId: z.string().uuid(),
|
|
32
|
+
reason: z.string().max(512).optional()
|
|
33
|
+
}).strict();
|
|
34
|
+
var ExternalActorSelection = z.discriminatedUnion("mode", [
|
|
35
|
+
z.object({ mode: z.literal("external"), identity: ExternalIdentityReference }).strict(),
|
|
36
|
+
z.object({
|
|
37
|
+
mode: z.literal("linked_native"),
|
|
38
|
+
identity: ExternalIdentityReference,
|
|
39
|
+
linkId: z.string().uuid(),
|
|
40
|
+
expectedLinkRevision: z.number().int().positive().safe()
|
|
41
|
+
}).strict()
|
|
42
|
+
]);
|
|
43
|
+
var ExternalIdentity = z.object({
|
|
44
|
+
id: z.string().uuid(),
|
|
45
|
+
accountId: z.string().uuid(),
|
|
46
|
+
source,
|
|
47
|
+
externalId,
|
|
48
|
+
subjectId: externalSubject,
|
|
49
|
+
organizationMembershipId: z.string().uuid(),
|
|
50
|
+
personalWorkspaceId: z.string().uuid(),
|
|
51
|
+
status: z.enum(["active", "disabled", "revoked"]),
|
|
52
|
+
authorizationRevision: z.number().int().positive().safe()
|
|
53
|
+
}).strict();
|
|
54
|
+
var ExternalActorAttribution = z.object({
|
|
55
|
+
accountId: z.string().uuid(),
|
|
56
|
+
authenticatingApiKeyId: z.string().uuid(),
|
|
57
|
+
externalIdentityId: z.string().uuid(),
|
|
58
|
+
externalSubjectId: externalSubject,
|
|
59
|
+
externalAuthorizationRevision: z.number().int().positive().safe(),
|
|
60
|
+
effectiveSubjectId: z.string().min(1).max(1024),
|
|
61
|
+
actingMode: z.enum(["external", "linked_native"]),
|
|
62
|
+
linkId: z.string().uuid().optional(),
|
|
63
|
+
linkRevision: z.number().int().positive().safe().optional()
|
|
64
|
+
}).strict().superRefine((value, context) => {
|
|
65
|
+
if (value.actingMode === "external") {
|
|
66
|
+
if (value.effectiveSubjectId !== value.externalSubjectId || value.linkId !== void 0 || value.linkRevision !== void 0) {
|
|
67
|
+
context.addIssue({
|
|
68
|
+
code: "custom",
|
|
69
|
+
message: "External mode cannot delegate native identity"
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
} else if (!value.linkId || !value.linkRevision || !nativeSubject.safeParse(value.effectiveSubjectId).success) {
|
|
73
|
+
context.addIssue({
|
|
74
|
+
code: "custom",
|
|
75
|
+
message: "Linked mode requires exact native delegation provenance"
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
var ExternalActorContinuation = z.object({
|
|
80
|
+
identity: ExternalIdentityReference,
|
|
81
|
+
actor: ExternalActorAttribution
|
|
82
|
+
}).strict();
|
|
83
|
+
var ExternalIdentityLink = z.object({
|
|
84
|
+
id: z.string().uuid(),
|
|
85
|
+
accountId: z.string().uuid(),
|
|
86
|
+
externalIdentityId: z.string().uuid(),
|
|
87
|
+
externalIdentity: ExternalIdentityReference.optional(),
|
|
88
|
+
nativeSubjectId: nativeSubject.nullable(),
|
|
89
|
+
status: z.enum(["pending", "active", "revoked", "expired"]),
|
|
90
|
+
revision: z.number().int().positive().safe(),
|
|
91
|
+
permissions: z.array(Permission).max(Permission.options.length),
|
|
92
|
+
expiresAt: z.string().datetime({ offset: true }).nullable()
|
|
93
|
+
}).strict().refine(
|
|
94
|
+
(value) => value.status !== "active" || value.nativeSubjectId !== null,
|
|
95
|
+
"An active link requires a confirmed native identity"
|
|
96
|
+
);
|
|
97
|
+
var ExternalIdentityLinkPage = z.object({
|
|
98
|
+
links: z.array(ExternalIdentityLink).max(50),
|
|
99
|
+
nextCursor: z.string().uuid().nullable()
|
|
100
|
+
}).strict();
|
|
101
|
+
var BeginExternalIdentityLinkRequest = z.object({
|
|
102
|
+
permissions: z.array(Permission).min(1).max(Permission.options.length),
|
|
103
|
+
expiresAt: z.string().datetime({ offset: true }).nullable().default(null)
|
|
104
|
+
}).strict();
|
|
105
|
+
var ConfirmExternalIdentityLinkRequest = z.object({
|
|
106
|
+
challenge: z.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
107
|
+
expectedRevision: z.number().int().positive().safe(),
|
|
108
|
+
permissions: z.array(Permission).min(1).max(Permission.options.length)
|
|
109
|
+
}).strict();
|
|
110
|
+
var BeginExternalIdentityLinkResponse = z.object({
|
|
111
|
+
link: ExternalIdentityLink,
|
|
112
|
+
challenge: z.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
113
|
+
confirmBefore: z.string().datetime({ offset: true })
|
|
114
|
+
}).strict();
|
|
115
|
+
var ExternalIdentityLinkPreview = z.object({
|
|
116
|
+
link: ExternalIdentityLink,
|
|
117
|
+
externalIdentity: ExternalIdentityReference,
|
|
118
|
+
nativeSubjectId: nativeSubject,
|
|
119
|
+
organizationId: z.string().uuid()
|
|
120
|
+
}).strict();
|
|
121
|
+
var ExternalLinkWorkSnapshot = z.object({
|
|
122
|
+
identity: ExternalIdentityReference,
|
|
123
|
+
actor: ExternalActorAttribution.refine((value) => value.actingMode === "linked_native"),
|
|
124
|
+
permissions: z.array(Permission).max(Permission.options.length)
|
|
125
|
+
}).strict();
|
|
126
|
+
|
|
127
|
+
export {
|
|
128
|
+
ExternalIdentityReference,
|
|
129
|
+
AddExternalWorkspaceMemberRequest,
|
|
130
|
+
UpdateExternalIdentityMembershipRequest,
|
|
131
|
+
ExternalActorSelection,
|
|
132
|
+
ExternalIdentity,
|
|
133
|
+
ExternalActorAttribution,
|
|
134
|
+
ExternalActorContinuation,
|
|
135
|
+
ExternalIdentityLink,
|
|
136
|
+
ExternalIdentityLinkPage,
|
|
137
|
+
BeginExternalIdentityLinkRequest,
|
|
138
|
+
ConfirmExternalIdentityLinkRequest,
|
|
139
|
+
BeginExternalIdentityLinkResponse,
|
|
140
|
+
ExternalIdentityLinkPreview,
|
|
141
|
+
ExternalLinkWorkSnapshot
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=chunk-TEMFILR7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/external-identities.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { Permission } from \"./permissions\";\n\n// External identifiers are opaque, case-sensitive strings. In particular a\n// native-looking identifier is still host data, never a native subject claim.\n// Bound bytes, not just JS code units: these values share a PostgreSQL B-tree\n// index entry. Never normalize/truncate an identifier to make it fit, and reject\n// text that the driver would replace or PostgreSQL cannot represent.\nconst encoder = new TextEncoder();\nfunction opaqueText(maxBytes: number) {\n return z\n .string()\n .min(1)\n .max(maxBytes)\n .refine(\n (value) =>\n !value.includes(\"\\0\") &&\n !/[\\uD800-\\uDFFF]/u.test(value) &&\n encoder.encode(value).byteLength <= maxBytes,\n {\n message: `Identifier must be valid PostgreSQL Unicode text of at most ${maxBytes} UTF-8 bytes`,\n },\n );\n}\nconst externalId = opaqueText(1024);\nconst source = opaqueText(200);\nconst externalSubject = z\n .string()\n .regex(/^external_user:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$(?![\\s\\S])/);\nconst nativeSubject = z\n .string()\n .min(1)\n .max(1024)\n .regex(/^user:[^\\r\\n]+$(?![\\s\\S])/);\nexport const ExternalIdentityReference = z\n .object({\n externalId,\n source: source.default(\"default\"),\n })\n .strict();\nexport type ExternalIdentityReference = z.infer<typeof ExternalIdentityReference>;\n\nexport const AddExternalWorkspaceMemberRequest = z\n .object({\n identity: ExternalIdentityReference,\n permissions: z.array(Permission).min(1).max(Permission.options.length),\n })\n .strict();\nexport type AddExternalWorkspaceMemberRequest = z.infer<typeof AddExternalWorkspaceMemberRequest>;\n\n/** Uses the organization membership ID returned by lazy identity admission.\n * Reactivation restores admission only, not revoked work or workspace grants. */\nexport const UpdateExternalIdentityMembershipRequest = z\n .object({\n kind: z.enum([\"suspend\", \"reactivate\", \"offboard\"]),\n expectedAuthorizationRevision: z.number().int().positive().safe(),\n operationId: z.string().uuid(),\n reason: z.string().max(512).optional(),\n })\n .strict();\nexport type UpdateExternalIdentityMembershipRequest = z.infer<\n typeof UpdateExternalIdentityMembershipRequest\n>;\n\nexport const ExternalActorSelection = z.discriminatedUnion(\"mode\", [\n z.object({ mode: z.literal(\"external\"), identity: ExternalIdentityReference }).strict(),\n z\n .object({\n mode: z.literal(\"linked_native\"),\n identity: ExternalIdentityReference,\n linkId: z.string().uuid(),\n expectedLinkRevision: z.number().int().positive().safe(),\n })\n .strict(),\n]);\nexport type ExternalActorSelection = z.infer<typeof ExternalActorSelection>;\n\nexport const ExternalIdentity = z\n .object({\n id: z.string().uuid(),\n accountId: z.string().uuid(),\n source,\n externalId,\n subjectId: externalSubject,\n organizationMembershipId: z.string().uuid(),\n personalWorkspaceId: z.string().uuid(),\n status: z.enum([\"active\", \"disabled\", \"revoked\"]),\n authorizationRevision: z.number().int().positive().safe(),\n })\n .strict();\nexport type ExternalIdentity = z.infer<typeof ExternalIdentity>;\n\n// Audit attribution, not authentication. Only the canonical access resolver\n// may establish provenance; accepting this JSON from a browser proves nothing.\nexport const ExternalActorAttribution = z\n .object({\n accountId: z.string().uuid(),\n authenticatingApiKeyId: z.string().uuid(),\n externalIdentityId: z.string().uuid(),\n externalSubjectId: externalSubject,\n externalAuthorizationRevision: z.number().int().positive().safe(),\n effectiveSubjectId: z.string().min(1).max(1024),\n actingMode: z.enum([\"external\", \"linked_native\"]),\n linkId: z.string().uuid().optional(),\n linkRevision: z.number().int().positive().safe().optional(),\n })\n .strict()\n .superRefine((value, context) => {\n if (value.actingMode === \"external\") {\n if (\n value.effectiveSubjectId !== value.externalSubjectId ||\n value.linkId !== undefined ||\n value.linkRevision !== undefined\n ) {\n context.addIssue({\n code: \"custom\",\n message: \"External mode cannot delegate native identity\",\n });\n }\n } else if (\n !value.linkId ||\n !value.linkRevision ||\n !nativeSubject.safeParse(value.effectiveSubjectId).success\n ) {\n context.addIssue({\n code: \"custom\",\n message: \"Linked mode requires exact native delegation provenance\",\n });\n }\n });\nexport type ExternalActorAttribution = z.infer<typeof ExternalActorAttribution>;\n\n/** Server-signed/encrypted continuation data, never sufficient live authority. */\nexport const ExternalActorContinuation = z\n .object({\n identity: ExternalIdentityReference,\n actor: ExternalActorAttribution,\n })\n .strict();\nexport type ExternalActorContinuation = z.infer<typeof ExternalActorContinuation>;\n\nexport const ExternalIdentityLink = z\n .object({\n id: z.string().uuid(),\n accountId: z.string().uuid(),\n externalIdentityId: z.string().uuid(),\n externalIdentity: ExternalIdentityReference.optional(),\n nativeSubjectId: nativeSubject.nullable(),\n status: z.enum([\"pending\", \"active\", \"revoked\", \"expired\"]),\n revision: z.number().int().positive().safe(),\n permissions: z.array(Permission).max(Permission.options.length),\n expiresAt: z.string().datetime({ offset: true }).nullable(),\n })\n .strict()\n .refine(\n (value) => value.status !== \"active\" || value.nativeSubjectId !== null,\n \"An active link requires a confirmed native identity\",\n );\nexport type ExternalIdentityLink = z.infer<typeof ExternalIdentityLink>;\n\nexport const ExternalIdentityLinkPage = z\n .object({\n links: z.array(ExternalIdentityLink).max(50),\n nextCursor: z.string().uuid().nullable(),\n })\n .strict();\nexport type ExternalIdentityLinkPage = z.infer<typeof ExternalIdentityLinkPage>;\n\n/** A native confirmation may narrow this request, never broaden it. The\n * challenge is delivered once to the host and is not an authentication token. */\nexport const BeginExternalIdentityLinkRequest = z\n .object({\n permissions: z.array(Permission).min(1).max(Permission.options.length),\n expiresAt: z.string().datetime({ offset: true }).nullable().default(null),\n })\n .strict();\nexport type BeginExternalIdentityLinkRequest = z.input<typeof BeginExternalIdentityLinkRequest>;\nexport const ConfirmExternalIdentityLinkRequest = z\n .object({\n challenge: z.string().regex(/^[A-Za-z0-9_-]{43}$/),\n expectedRevision: z.number().int().positive().safe(),\n permissions: z.array(Permission).min(1).max(Permission.options.length),\n })\n .strict();\nexport type ConfirmExternalIdentityLinkRequest = z.infer<typeof ConfirmExternalIdentityLinkRequest>;\nexport const BeginExternalIdentityLinkResponse = z\n .object({\n link: ExternalIdentityLink,\n challenge: z.string().regex(/^[A-Za-z0-9_-]{43}$/),\n confirmBefore: z.string().datetime({ offset: true }),\n })\n .strict();\nexport type BeginExternalIdentityLinkResponse = z.infer<typeof BeginExternalIdentityLinkResponse>;\nexport const ExternalIdentityLinkPreview = z\n .object({\n link: ExternalIdentityLink,\n externalIdentity: ExternalIdentityReference,\n nativeSubjectId: nativeSubject,\n organizationId: z.string().uuid(),\n })\n .strict();\nexport type ExternalIdentityLinkPreview = z.infer<typeof ExternalIdentityLinkPreview>;\n\n/** Immutable accepted-work restriction, not a browser credential. Original key\n * identity remains audit-only; durable use validates the live link and members. */\nexport const ExternalLinkWorkSnapshot = z\n .object({\n identity: ExternalIdentityReference,\n actor: ExternalActorAttribution.refine((value) => value.actingMode === \"linked_native\"),\n permissions: z.array(Permission).max(Permission.options.length),\n })\n .strict();\nexport type ExternalLinkWorkSnapshot = z.infer<typeof ExternalLinkWorkSnapshot>;\n"],"mappings":"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","names":[]}
|