@privos_ai/app-server 0.1.0 → 0.4.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/README.md +189 -0
- package/dist/app-descriptor.d.ts +17 -0
- package/dist/app-descriptor.d.ts.map +1 -1
- package/dist/app-descriptor.js +38 -0
- package/dist/app-descriptor.js.map +1 -1
- package/dist/context/platform-context.d.ts +43 -0
- package/dist/context/platform-context.d.ts.map +1 -0
- package/dist/context/platform-context.js +37 -0
- package/dist/context/platform-context.js.map +1 -0
- package/dist/context/tool-call-context.d.ts +3 -0
- package/dist/context/tool-call-context.d.ts.map +1 -1
- package/dist/direct/express-router.d.ts +5 -0
- package/dist/direct/express-router.d.ts.map +1 -1
- package/dist/direct/express-router.js +104 -12
- package/dist/direct/express-router.js.map +1 -1
- package/dist/direct/http-ingress.d.ts.map +1 -1
- package/dist/direct/http-ingress.js +10 -0
- package/dist/direct/http-ingress.js.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest-lint-cli.d.ts +3 -0
- package/dist/manifest-lint-cli.d.ts.map +1 -0
- package/dist/manifest-lint-cli.js +18 -0
- package/dist/manifest-lint-cli.js.map +1 -0
- package/dist/manifest-tools.d.ts +15 -0
- package/dist/manifest-tools.d.ts.map +1 -0
- package/dist/manifest-tools.js +0 -0
- package/dist/manifest-tools.js.map +1 -0
- package/dist/relay/relay-client.d.ts +5 -1
- package/dist/relay/relay-client.d.ts.map +1 -1
- package/dist/relay/relay-client.js +81 -10
- package/dist/relay/relay-client.js.map +1 -1
- package/dist/runtime.d.ts +3 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +28 -1
- package/dist/runtime.js.map +1 -1
- package/dist/workload/dispatch-assertion.d.ts +167 -0
- package/dist/workload/dispatch-assertion.d.ts.map +1 -0
- package/dist/workload/dispatch-assertion.js +653 -0
- package/dist/workload/dispatch-assertion.js.map +1 -0
- package/dist/workload/index.d.ts +7 -0
- package/dist/workload/index.d.ts.map +1 -0
- package/dist/workload/index.js +4 -0
- package/dist/workload/index.js.map +1 -0
- package/dist/workload/publisher-runtime-trust.d.ts +118 -0
- package/dist/workload/publisher-runtime-trust.d.ts.map +1 -0
- package/dist/workload/publisher-runtime-trust.js +918 -0
- package/dist/workload/publisher-runtime-trust.js.map +1 -0
- package/dist/workload/workload-identity.d.ts +118 -0
- package/dist/workload/workload-identity.d.ts.map +1 -0
- package/dist/workload/workload-identity.js +451 -0
- package/dist/workload/workload-identity.js.map +1 -0
- package/package.json +13 -1
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import net from 'node:net';
|
|
4
|
+
export const DEFAULT_WORKLOAD_SOCKET = '/run/privos/identity.sock';
|
|
5
|
+
export class WorkloadIdentityError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
status;
|
|
8
|
+
constructor(code, message, status) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.name = 'WorkloadIdentityError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class WorkloadPermissionDeniedError extends WorkloadIdentityError {
|
|
16
|
+
requiredScope;
|
|
17
|
+
constructor(requiredScope) {
|
|
18
|
+
super('PERMISSION_DENIED', 'The installation does not grant this capability.', 403);
|
|
19
|
+
this.requiredScope = requiredScope;
|
|
20
|
+
this.name = 'WorkloadPermissionDeniedError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function encode(value) {
|
|
24
|
+
return Buffer.from(JSON.stringify(value), 'utf8').toString('base64url');
|
|
25
|
+
}
|
|
26
|
+
function thumbprint(jwk) {
|
|
27
|
+
return crypto
|
|
28
|
+
.createHash('sha256')
|
|
29
|
+
.update(JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }))
|
|
30
|
+
.digest('base64url');
|
|
31
|
+
}
|
|
32
|
+
function normalizedHtu(value) {
|
|
33
|
+
const url = new URL(value);
|
|
34
|
+
url.search = '';
|
|
35
|
+
url.hash = '';
|
|
36
|
+
return url.toString();
|
|
37
|
+
}
|
|
38
|
+
function validateHubOrigin(value) {
|
|
39
|
+
if (typeof value !== 'string')
|
|
40
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
41
|
+
const url = new URL(value);
|
|
42
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
|
|
43
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
44
|
+
}
|
|
45
|
+
return url.origin;
|
|
46
|
+
}
|
|
47
|
+
function parseBinding(attestation, nonce, publicJwk, now) {
|
|
48
|
+
const parts = attestation.split('.');
|
|
49
|
+
if (parts.length !== 3 || parts.some((part) => !part)) {
|
|
50
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
51
|
+
}
|
|
52
|
+
let payload;
|
|
53
|
+
try {
|
|
54
|
+
payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
58
|
+
}
|
|
59
|
+
if (payload.type !== 'node-workload-attestation' ||
|
|
60
|
+
payload.nonce !== nonce ||
|
|
61
|
+
payload.dpopJkt !== thumbprint(publicJwk) ||
|
|
62
|
+
!Number.isInteger(payload.iat) ||
|
|
63
|
+
!Number.isInteger(payload.exp) ||
|
|
64
|
+
Number(payload.iat) > Math.floor(now / 1_000) + 30 ||
|
|
65
|
+
Number(payload.exp) < Math.floor(now / 1_000) ||
|
|
66
|
+
Number(payload.exp) - Number(payload.iat) > 60) {
|
|
67
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
68
|
+
}
|
|
69
|
+
return payload.protocolVersion === 3 ? bindingFromGenerationAttestation(payload) : bindingFromReplicaAttestation(payload);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A node running an App Library generation attests the generation instead of a
|
|
73
|
+
* standalone replica: the installation is the runtime installation, the receipt
|
|
74
|
+
* is the approval receipt, and the epoch is the authorization epoch. All three
|
|
75
|
+
* generation hashes are canonical-JSON SHA-256 in base64url, never the
|
|
76
|
+
* `sha256:<hex>` digest form the replica attestation uses.
|
|
77
|
+
*/
|
|
78
|
+
function bindingFromGenerationAttestation(payload) {
|
|
79
|
+
const identifiers = [
|
|
80
|
+
'workspaceId',
|
|
81
|
+
'runtimeInstallationId',
|
|
82
|
+
'mcpAppId',
|
|
83
|
+
'replicaId',
|
|
84
|
+
'clusterId',
|
|
85
|
+
'deploymentId',
|
|
86
|
+
'generationId',
|
|
87
|
+
];
|
|
88
|
+
const artifactHashes = ['approvalReceiptHash', 'resourceManifestHash', 'runtimeResourceInventoryHash'];
|
|
89
|
+
if (identifiers.some((field) => typeof payload[field] !== 'string' || String(payload[field]).length === 0) ||
|
|
90
|
+
artifactHashes.some((field) => typeof payload[field] !== 'string' || !/^[A-Za-z0-9_-]{43}$/.test(String(payload[field]))) ||
|
|
91
|
+
typeof payload.manifestDigest !== 'string' ||
|
|
92
|
+
!/^sha256:[a-f0-9]{64}$/.test(payload.manifestDigest) ||
|
|
93
|
+
!Number.isInteger(payload.authorizationEpoch) ||
|
|
94
|
+
Number(payload.authorizationEpoch) < 1 ||
|
|
95
|
+
!Number.isInteger(payload.generationNumber) ||
|
|
96
|
+
Number(payload.generationNumber) < 1) {
|
|
97
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
workspaceId: String(payload.workspaceId),
|
|
101
|
+
installationId: String(payload.runtimeInstallationId),
|
|
102
|
+
mcpAppId: String(payload.mcpAppId),
|
|
103
|
+
replicaId: String(payload.replicaId),
|
|
104
|
+
receiptHash: String(payload.approvalReceiptHash),
|
|
105
|
+
grantEpoch: Number(payload.authorizationEpoch),
|
|
106
|
+
generation: {
|
|
107
|
+
clusterId: String(payload.clusterId),
|
|
108
|
+
deploymentId: String(payload.deploymentId),
|
|
109
|
+
generationId: String(payload.generationId),
|
|
110
|
+
generationNumber: Number(payload.generationNumber),
|
|
111
|
+
manifestDigest: payload.manifestDigest,
|
|
112
|
+
resourceManifestHash: String(payload.resourceManifestHash),
|
|
113
|
+
runtimeResourceInventoryHash: String(payload.runtimeResourceInventoryHash),
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function bindingFromReplicaAttestation(payload) {
|
|
118
|
+
const identifiers = ['workspaceId', 'installationId', 'mcpAppId', 'replicaId'];
|
|
119
|
+
if (identifiers.some((field) => typeof payload[field] !== 'string' || String(payload[field]).length === 0) ||
|
|
120
|
+
typeof payload.receiptHash !== 'string' ||
|
|
121
|
+
!/^sha256:[a-f0-9]{64}$/.test(payload.receiptHash) ||
|
|
122
|
+
!Number.isInteger(payload.grantEpoch) ||
|
|
123
|
+
Number(payload.grantEpoch) < 1) {
|
|
124
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
workspaceId: String(payload.workspaceId),
|
|
128
|
+
installationId: String(payload.installationId),
|
|
129
|
+
mcpAppId: String(payload.mcpAppId),
|
|
130
|
+
replicaId: String(payload.replicaId),
|
|
131
|
+
receiptHash: payload.receiptHash,
|
|
132
|
+
grantEpoch: Number(payload.grantEpoch),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function parseScopes(value) {
|
|
136
|
+
if (typeof value !== 'string')
|
|
137
|
+
throw new WorkloadIdentityError('TOKEN_RESPONSE_INVALID', 'The workload token response is invalid.');
|
|
138
|
+
const scopes = value.split(/\s+/).filter(Boolean);
|
|
139
|
+
if (new Set(scopes).size !== scopes.length ||
|
|
140
|
+
scopes.some((scope) => !/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)+$/.test(scope))) {
|
|
141
|
+
throw new WorkloadIdentityError('TOKEN_RESPONSE_INVALID', 'The workload token response is invalid.');
|
|
142
|
+
}
|
|
143
|
+
return scopes.sort();
|
|
144
|
+
}
|
|
145
|
+
function capabilitiesEqual(left, right) {
|
|
146
|
+
return JSON.stringify({ ...left, updatedAt: 0 }) === JSON.stringify({ ...right, updatedAt: 0 });
|
|
147
|
+
}
|
|
148
|
+
function retryAllowed(method, mode) {
|
|
149
|
+
if (mode === 'never')
|
|
150
|
+
return false;
|
|
151
|
+
if (mode === 'idempotent')
|
|
152
|
+
return true;
|
|
153
|
+
return ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'].includes(method);
|
|
154
|
+
}
|
|
155
|
+
export class WorkloadIdentityClient {
|
|
156
|
+
socketPath;
|
|
157
|
+
fetchImplementation;
|
|
158
|
+
brokerRequester;
|
|
159
|
+
now;
|
|
160
|
+
refreshSkewMs;
|
|
161
|
+
privateJwk;
|
|
162
|
+
publicJwk;
|
|
163
|
+
token;
|
|
164
|
+
ready = false;
|
|
165
|
+
context;
|
|
166
|
+
monitor;
|
|
167
|
+
listeners = new Set();
|
|
168
|
+
capabilities;
|
|
169
|
+
constructor(options = {}) {
|
|
170
|
+
const normalized = typeof options === 'string' ? { socketPath: options } : options;
|
|
171
|
+
this.socketPath = normalized.socketPath ?? process.env.PRIVOS_WORKLOAD_SOCKET ?? DEFAULT_WORKLOAD_SOCKET;
|
|
172
|
+
this.fetchImplementation = normalized.fetch ?? fetch;
|
|
173
|
+
this.brokerRequester = normalized.brokerRequest;
|
|
174
|
+
this.now = normalized.now ?? Date.now;
|
|
175
|
+
this.refreshSkewMs = normalized.refreshSkewMs ?? 30_000;
|
|
176
|
+
const pair = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' });
|
|
177
|
+
this.privateJwk = pair.privateKey.export({ format: 'jwk' });
|
|
178
|
+
this.publicJwk = pair.publicKey.export({ format: 'jwk' });
|
|
179
|
+
this.capabilities = Object.freeze({
|
|
180
|
+
status: this.isAvailable() ? 'pairing' : 'unavailable',
|
|
181
|
+
scopes: Object.freeze([]),
|
|
182
|
+
updatedAt: this.now(),
|
|
183
|
+
...(this.isAvailable() ? {} : { reason: 'BROKER_UNAVAILABLE' }),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
isAvailable() {
|
|
187
|
+
return Boolean(this.brokerRequester) || fs.existsSync(this.socketPath);
|
|
188
|
+
}
|
|
189
|
+
proof(input) {
|
|
190
|
+
const header = encode({ alg: 'ES256', typ: 'dpop+jwt', jwk: this.publicJwk });
|
|
191
|
+
const payload = encode({
|
|
192
|
+
htu: normalizedHtu(input.htu),
|
|
193
|
+
htm: input.htm.toUpperCase(),
|
|
194
|
+
iat: Math.floor(this.now() / 1_000),
|
|
195
|
+
jti: crypto.randomUUID(),
|
|
196
|
+
...(input.nonce ? { nonce: input.nonce } : {}),
|
|
197
|
+
...(input.ath ? { ath: input.ath } : {}),
|
|
198
|
+
});
|
|
199
|
+
const signingInput = Buffer.from(`${header}.${payload}`, 'utf8');
|
|
200
|
+
const key = crypto.createPrivateKey({ key: this.privateJwk, format: 'jwk' });
|
|
201
|
+
const signature = crypto.sign('sha256', signingInput, { key, dsaEncoding: 'ieee-p1363' }).toString('base64url');
|
|
202
|
+
return `${header}.${payload}.${signature}`;
|
|
203
|
+
}
|
|
204
|
+
updateCapabilities(input) {
|
|
205
|
+
const next = Object.freeze({
|
|
206
|
+
...input,
|
|
207
|
+
scopes: Object.freeze([...input.scopes].sort()),
|
|
208
|
+
updatedAt: this.now(),
|
|
209
|
+
});
|
|
210
|
+
if (capabilitiesEqual(this.capabilities, next))
|
|
211
|
+
return;
|
|
212
|
+
this.capabilities = next;
|
|
213
|
+
for (const listener of this.listeners) {
|
|
214
|
+
try {
|
|
215
|
+
listener(next);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// A consumer callback must never break token refresh or expose credentials through an error path.
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
contextCapabilities(status, scopes, reason) {
|
|
223
|
+
const binding = this.context?.binding;
|
|
224
|
+
this.updateCapabilities({
|
|
225
|
+
status,
|
|
226
|
+
scopes,
|
|
227
|
+
...(binding
|
|
228
|
+
? {
|
|
229
|
+
workspaceId: binding.workspaceId,
|
|
230
|
+
installationId: binding.installationId,
|
|
231
|
+
mcpAppId: binding.mcpAppId,
|
|
232
|
+
replicaId: binding.replicaId,
|
|
233
|
+
receiptHash: binding.receiptHash,
|
|
234
|
+
grantEpoch: binding.grantEpoch,
|
|
235
|
+
}
|
|
236
|
+
: {}),
|
|
237
|
+
...(reason ? { reason } : {}),
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
async attest() {
|
|
241
|
+
const nonce = crypto.randomBytes(24).toString('base64url');
|
|
242
|
+
const broker = await this.requestBroker({ op: 'attest', publicJwk: this.publicJwk, nonce });
|
|
243
|
+
if (!broker ||
|
|
244
|
+
broker.ok !== true ||
|
|
245
|
+
typeof broker.attestation !== 'string' ||
|
|
246
|
+
typeof broker.hubKid !== 'string' ||
|
|
247
|
+
!broker.hubPublicJwk ||
|
|
248
|
+
thumbprint(broker.hubPublicJwk) !== broker.hubKid) {
|
|
249
|
+
throw new WorkloadIdentityError('HUB_IDENTITY_INVALID', 'The workload broker Hub identity is invalid.');
|
|
250
|
+
}
|
|
251
|
+
const hubOrigin = validateHubOrigin(broker.hubOrigin);
|
|
252
|
+
const binding = parseBinding(broker.attestation, nonce, this.publicJwk, this.now());
|
|
253
|
+
this.context = { hubOrigin, hubKid: broker.hubKid, hubPublicJwk: broker.hubPublicJwk, binding };
|
|
254
|
+
return { broker: { ...broker, hubOrigin }, nonce };
|
|
255
|
+
}
|
|
256
|
+
requestBroker(request) {
|
|
257
|
+
if (this.brokerRequester)
|
|
258
|
+
return this.brokerRequester(request);
|
|
259
|
+
if (!fs.existsSync(this.socketPath)) {
|
|
260
|
+
return Promise.reject(new WorkloadIdentityError('BROKER_UNAVAILABLE', 'The PrivOS workload identity broker is unavailable.'));
|
|
261
|
+
}
|
|
262
|
+
return new Promise((resolve, reject) => {
|
|
263
|
+
const socket = net.createConnection(this.socketPath);
|
|
264
|
+
let buffer = '';
|
|
265
|
+
const timeout = setTimeout(() => socket.destroy(new WorkloadIdentityError('BROKER_UNAVAILABLE', 'The PrivOS workload identity broker timed out.')), 5_000);
|
|
266
|
+
socket.setEncoding('utf8');
|
|
267
|
+
socket.once('connect', () => socket.write(`${JSON.stringify(request)}\n`));
|
|
268
|
+
socket.on('data', (chunk) => {
|
|
269
|
+
buffer += chunk;
|
|
270
|
+
if (buffer.length > 32_768) {
|
|
271
|
+
socket.destroy(new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.'));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const end = buffer.indexOf('\n');
|
|
275
|
+
if (end < 0)
|
|
276
|
+
return;
|
|
277
|
+
clearTimeout(timeout);
|
|
278
|
+
socket.end();
|
|
279
|
+
try {
|
|
280
|
+
const parsed = JSON.parse(buffer.slice(0, end));
|
|
281
|
+
if (!parsed.ok)
|
|
282
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker denied identity.');
|
|
283
|
+
resolve(parsed);
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
reject(error instanceof WorkloadIdentityError ? error : new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.'));
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
socket.once('error', (error) => {
|
|
290
|
+
clearTimeout(timeout);
|
|
291
|
+
reject(error);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
async ensureReady() {
|
|
296
|
+
if (this.ready)
|
|
297
|
+
return;
|
|
298
|
+
this.contextCapabilities('pairing', []);
|
|
299
|
+
const { broker, nonce } = await this.attest();
|
|
300
|
+
const target = `${broker.hubOrigin}/api/v1/mcp-workload.ready`;
|
|
301
|
+
const response = await this.fetchImplementation(target, {
|
|
302
|
+
method: 'POST',
|
|
303
|
+
headers: { 'content-type': 'application/json', dpop: this.proof({ htu: target, htm: 'POST', nonce }) },
|
|
304
|
+
body: JSON.stringify({ attestation: broker.attestation }),
|
|
305
|
+
signal: AbortSignal.timeout(10_000),
|
|
306
|
+
});
|
|
307
|
+
if (!response.ok) {
|
|
308
|
+
this.contextCapabilities('stale', [], 'READINESS_DENIED');
|
|
309
|
+
throw new WorkloadIdentityError('READINESS_DENIED', 'PrivOS did not accept workload readiness.', response.status);
|
|
310
|
+
}
|
|
311
|
+
this.ready = true;
|
|
312
|
+
this.contextCapabilities('paired', []);
|
|
313
|
+
}
|
|
314
|
+
async issueAccessToken() {
|
|
315
|
+
await this.ensureReady();
|
|
316
|
+
const { broker, nonce } = await this.attest();
|
|
317
|
+
const target = `${broker.hubOrigin}/api/v1/mcp-workload.token`;
|
|
318
|
+
const response = await this.fetchImplementation(target, {
|
|
319
|
+
method: 'POST',
|
|
320
|
+
headers: { 'content-type': 'application/json', dpop: this.proof({ htu: target, htm: 'POST', nonce }) },
|
|
321
|
+
body: JSON.stringify({ attestation: broker.attestation }),
|
|
322
|
+
signal: AbortSignal.timeout(10_000),
|
|
323
|
+
});
|
|
324
|
+
if (!response.ok) {
|
|
325
|
+
this.token = undefined;
|
|
326
|
+
this.contextCapabilities('stale', [], 'TOKEN_DENIED');
|
|
327
|
+
throw new WorkloadIdentityError('TOKEN_DENIED', 'PrivOS did not issue workload authorization.', response.status);
|
|
328
|
+
}
|
|
329
|
+
let body;
|
|
330
|
+
try {
|
|
331
|
+
body = await response.json();
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
throw new WorkloadIdentityError('TOKEN_RESPONSE_INVALID', 'The workload token response is invalid.');
|
|
335
|
+
}
|
|
336
|
+
if (typeof body.access_token !== 'string' ||
|
|
337
|
+
body.access_token.length < 32 ||
|
|
338
|
+
body.token_type !== 'DPoP' ||
|
|
339
|
+
typeof body.expires_in !== 'number' ||
|
|
340
|
+
!Number.isFinite(body.expires_in) ||
|
|
341
|
+
body.expires_in <= 0 ||
|
|
342
|
+
body.expires_in > 600) {
|
|
343
|
+
throw new WorkloadIdentityError('TOKEN_RESPONSE_INVALID', 'The workload token response is invalid.');
|
|
344
|
+
}
|
|
345
|
+
const scopes = parseScopes(body.scope ?? '');
|
|
346
|
+
const token = { value: body.access_token, expiresAt: this.now() + body.expires_in * 1_000, scopes };
|
|
347
|
+
this.token = token;
|
|
348
|
+
this.contextCapabilities('active', scopes);
|
|
349
|
+
return token;
|
|
350
|
+
}
|
|
351
|
+
async getAccessToken(options = {}) {
|
|
352
|
+
if (!options.forceRefresh && this.token && this.token.expiresAt - this.now() > this.refreshSkewMs)
|
|
353
|
+
return this.token.value;
|
|
354
|
+
return (await this.issueAccessToken()).value;
|
|
355
|
+
}
|
|
356
|
+
async getEffectiveCapabilities(options = {}) {
|
|
357
|
+
await this.getAccessToken(options);
|
|
358
|
+
return this.capabilities;
|
|
359
|
+
}
|
|
360
|
+
peekEffectiveCapabilities() {
|
|
361
|
+
return this.capabilities;
|
|
362
|
+
}
|
|
363
|
+
toJSON() {
|
|
364
|
+
return { type: 'WorkloadIdentityClient', capabilities: this.capabilities };
|
|
365
|
+
}
|
|
366
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
367
|
+
return this.toJSON();
|
|
368
|
+
}
|
|
369
|
+
onCapabilitiesChanged(listener) {
|
|
370
|
+
this.listeners.add(listener);
|
|
371
|
+
return () => this.listeners.delete(listener);
|
|
372
|
+
}
|
|
373
|
+
requireCapability(scope) {
|
|
374
|
+
if (!this.capabilities.scopes.includes(scope)) {
|
|
375
|
+
throw new WorkloadIdentityError('CAPABILITY_NOT_GRANTED', `The optional capability "${scope}" is not granted.`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
startCapabilityMonitor(intervalMs = 60_000) {
|
|
379
|
+
if (!Number.isFinite(intervalMs) || intervalMs < 5_000)
|
|
380
|
+
throw new RangeError('Capability monitor interval must be at least 5000 ms.');
|
|
381
|
+
if (!this.monitor) {
|
|
382
|
+
this.monitor = setInterval(() => {
|
|
383
|
+
void this.getEffectiveCapabilities({ forceRefresh: true }).catch(() => undefined);
|
|
384
|
+
}, intervalMs);
|
|
385
|
+
this.monitor.unref();
|
|
386
|
+
}
|
|
387
|
+
return () => this.stopCapabilityMonitor();
|
|
388
|
+
}
|
|
389
|
+
stopCapabilityMonitor() {
|
|
390
|
+
if (this.monitor)
|
|
391
|
+
clearInterval(this.monitor);
|
|
392
|
+
this.monitor = undefined;
|
|
393
|
+
}
|
|
394
|
+
async performAuthorizedFetch(target, init, token) {
|
|
395
|
+
const headers = new Headers(init.headers);
|
|
396
|
+
headers.set('authorization', `DPoP ${token}`);
|
|
397
|
+
headers.set('dpop', this.proof({
|
|
398
|
+
htu: target.toString(),
|
|
399
|
+
htm: init.method ?? 'GET',
|
|
400
|
+
ath: crypto.createHash('sha256').update(token, 'utf8').digest('base64url'),
|
|
401
|
+
}));
|
|
402
|
+
return this.fetchImplementation(target, { ...init, headers });
|
|
403
|
+
}
|
|
404
|
+
async authorizedFetch(input, init = {}) {
|
|
405
|
+
await this.ensureReady();
|
|
406
|
+
const context = await this.brokerContext();
|
|
407
|
+
const target = new URL(input, context.hubOrigin);
|
|
408
|
+
if (target.origin !== context.hubOrigin) {
|
|
409
|
+
throw new WorkloadIdentityError('TARGET_ORIGIN_INVALID', 'Workload authorization can only be sent to the bound PrivOS Hub.');
|
|
410
|
+
}
|
|
411
|
+
const { retryMode = 'safe-methods', requiredScope: _requiredScope, ...requestInit } = init;
|
|
412
|
+
const method = (requestInit.method ?? 'GET').toUpperCase();
|
|
413
|
+
const token = await this.getAccessToken();
|
|
414
|
+
const response = await this.performAuthorizedFetch(target, requestInit, token);
|
|
415
|
+
if (response.status !== 401)
|
|
416
|
+
return response;
|
|
417
|
+
this.token = undefined;
|
|
418
|
+
this.contextCapabilities('stale', [], 'AUTHORIZATION_STALE');
|
|
419
|
+
if (!retryAllowed(method, retryMode))
|
|
420
|
+
return response;
|
|
421
|
+
const retryToken = await this.getAccessToken({ forceRefresh: true });
|
|
422
|
+
return this.performAuthorizedFetch(target, requestInit, retryToken);
|
|
423
|
+
}
|
|
424
|
+
async authorizedRequest(input, init = {}) {
|
|
425
|
+
const response = await this.authorizedFetch(input, init);
|
|
426
|
+
if (response.status === 403)
|
|
427
|
+
throw new WorkloadPermissionDeniedError(init.requiredScope);
|
|
428
|
+
if (response.status === 401) {
|
|
429
|
+
throw new WorkloadIdentityError('AUTHORIZATION_STALE', 'Workload authorization is stale.', 401);
|
|
430
|
+
}
|
|
431
|
+
return response;
|
|
432
|
+
}
|
|
433
|
+
async brokerContext() {
|
|
434
|
+
if (!this.context)
|
|
435
|
+
await this.attest();
|
|
436
|
+
if (!this.context)
|
|
437
|
+
throw new WorkloadIdentityError('BROKER_RESPONSE_INVALID', 'The workload broker response is invalid.');
|
|
438
|
+
return this.context;
|
|
439
|
+
}
|
|
440
|
+
dispose() {
|
|
441
|
+
this.stopCapabilityMonitor();
|
|
442
|
+
this.token = undefined;
|
|
443
|
+
this.listeners.clear();
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
let defaultClient;
|
|
447
|
+
export function getWorkloadIdentityClient() {
|
|
448
|
+
defaultClient ??= new WorkloadIdentityClient();
|
|
449
|
+
return defaultClient;
|
|
450
|
+
}
|
|
451
|
+
//# sourceMappingURL=workload-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-identity.js","sourceRoot":"","sources":["../../src/workload/workload-identity.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@privos_ai/app-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Business-agnostic PrivOS MCP App server runtime — Direct HTTP + Relay WebSocket",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"privos-app-lint": "./dist/manifest-lint-cli.js"
|
|
10
|
+
},
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
13
|
"types": "./dist/index.d.ts",
|
|
@@ -25,6 +28,14 @@
|
|
|
25
28
|
"./relay": {
|
|
26
29
|
"types": "./dist/relay/relay-client.d.ts",
|
|
27
30
|
"import": "./dist/relay/relay-client.js"
|
|
31
|
+
},
|
|
32
|
+
"./workload": {
|
|
33
|
+
"types": "./dist/workload/index.d.ts",
|
|
34
|
+
"import": "./dist/workload/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./manifest-tools": {
|
|
37
|
+
"types": "./dist/manifest-tools.d.ts",
|
|
38
|
+
"import": "./dist/manifest-tools.js"
|
|
28
39
|
}
|
|
29
40
|
},
|
|
30
41
|
"files": [
|
|
@@ -41,6 +52,7 @@
|
|
|
41
52
|
"test": "vitest run",
|
|
42
53
|
"test:watch": "vitest",
|
|
43
54
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
55
|
+
"manifest:lint": "npm run build --silent && node dist/manifest-lint-cli.js",
|
|
44
56
|
"pack:check": "npm pack --dry-run"
|
|
45
57
|
},
|
|
46
58
|
"peerDependencies": {
|