@agent-deck/backend 1.7.7 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/execution-authority/bearer.d.ts +15 -0
  3. package/dist/execution-authority/bearer.d.ts.map +1 -0
  4. package/dist/execution-authority/bearer.js +35 -0
  5. package/dist/execution-authority/bearer.js.map +1 -0
  6. package/dist/execution-authority/index.d.ts +6 -0
  7. package/dist/execution-authority/index.d.ts.map +1 -0
  8. package/dist/execution-authority/index.js +8 -0
  9. package/dist/execution-authority/index.js.map +1 -0
  10. package/dist/execution-authority/ledger.d.ts +85 -0
  11. package/dist/execution-authority/ledger.d.ts.map +1 -0
  12. package/dist/execution-authority/ledger.js +507 -0
  13. package/dist/execution-authority/ledger.js.map +1 -0
  14. package/dist/execution-authority/store.d.ts +55 -0
  15. package/dist/execution-authority/store.d.ts.map +1 -0
  16. package/dist/execution-authority/store.js +256 -0
  17. package/dist/execution-authority/store.js.map +1 -0
  18. package/dist/execution-authority/types.d.ts +119 -0
  19. package/dist/execution-authority/types.d.ts.map +1 -0
  20. package/dist/execution-authority/types.js +9 -0
  21. package/dist/execution-authority/types.js.map +1 -0
  22. package/dist/lib/agent-deck-context.d.ts +1 -1
  23. package/dist/lib/agent-deck-context.d.ts.map +1 -1
  24. package/dist/lib/agent-deck-context.js +14 -1
  25. package/dist/lib/agent-deck-context.js.map +1 -1
  26. package/dist/lib/backend-api-error.d.ts.map +1 -1
  27. package/dist/lib/backend-api-error.js +4 -0
  28. package/dist/lib/backend-api-error.js.map +1 -1
  29. package/dist/lib/bound-deck-scope.d.ts.map +1 -1
  30. package/dist/lib/bound-deck-scope.js +4 -0
  31. package/dist/lib/bound-deck-scope.js.map +1 -1
  32. package/dist/lib/execution-authority-http.d.ts +23 -0
  33. package/dist/lib/execution-authority-http.d.ts.map +1 -0
  34. package/dist/lib/execution-authority-http.js +101 -0
  35. package/dist/lib/execution-authority-http.js.map +1 -0
  36. package/dist/mcp-server.d.ts +11 -4
  37. package/dist/mcp-server.d.ts.map +1 -1
  38. package/dist/mcp-server.js +159 -72
  39. package/dist/mcp-server.js.map +1 -1
  40. package/dist/mcp-session-binding.d.ts +18 -1
  41. package/dist/mcp-session-binding.d.ts.map +1 -1
  42. package/dist/mcp-session-binding.js +41 -7
  43. package/dist/mcp-session-binding.js.map +1 -1
  44. package/dist/mcp-tools/policy.d.ts +10 -0
  45. package/dist/mcp-tools/policy.d.ts.map +1 -1
  46. package/dist/mcp-tools/policy.js +56 -0
  47. package/dist/mcp-tools/policy.js.map +1 -1
  48. package/dist/mcp-tools/register.d.ts +5 -0
  49. package/dist/mcp-tools/register.d.ts.map +1 -1
  50. package/dist/mcp-tools/register.js +98 -1
  51. package/dist/mcp-tools/register.js.map +1 -1
  52. package/dist/models/database.d.ts +2 -0
  53. package/dist/models/database.d.ts.map +1 -1
  54. package/dist/models/database.js +5 -0
  55. package/dist/models/database.js.map +1 -1
  56. package/dist/routes/decks.d.ts.map +1 -1
  57. package/dist/routes/decks.js +6 -2
  58. package/dist/routes/decks.js.map +1 -1
  59. package/dist/routes/execution-authority.d.ts +8 -0
  60. package/dist/routes/execution-authority.d.ts.map +1 -0
  61. package/dist/routes/execution-authority.js +506 -0
  62. package/dist/routes/execution-authority.js.map +1 -0
  63. package/dist/routes/scope.d.ts.map +1 -1
  64. package/dist/routes/scope.js +39 -1
  65. package/dist/routes/scope.js.map +1 -1
  66. package/dist/routes/services.d.ts.map +1 -1
  67. package/dist/routes/services.js +7 -1
  68. package/dist/routes/services.js.map +1 -1
  69. package/dist/scope/live-display-registry.d.ts +3 -0
  70. package/dist/scope/live-display-registry.d.ts.map +1 -1
  71. package/dist/scope/live-display-registry.js +4 -0
  72. package/dist/scope/live-display-registry.js.map +1 -1
  73. package/dist/server/index.d.ts +2 -0
  74. package/dist/server/index.d.ts.map +1 -1
  75. package/dist/server/index.js +5 -0
  76. package/dist/server/index.js.map +1 -1
  77. package/dist/trusted-session/auth.d.ts +6 -1
  78. package/dist/trusted-session/auth.d.ts.map +1 -1
  79. package/dist/trusted-session/auth.js +33 -6
  80. package/dist/trusted-session/auth.js.map +1 -1
  81. package/dist/trusted-session/policy-hook.d.ts.map +1 -1
  82. package/dist/trusted-session/policy-hook.js +51 -1
  83. package/dist/trusted-session/policy-hook.js.map +1 -1
  84. package/dist/trusted-session/route-policy-registry.d.ts.map +1 -1
  85. package/dist/trusted-session/route-policy-registry.js +41 -0
  86. package/dist/trusted-session/route-policy-registry.js.map +1 -1
  87. package/package.json +2 -2
@@ -0,0 +1,506 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerExecutionAuthorityRoutes = exports.EnrollmentAuthError = void 0;
4
+ const http_auth_1 = require("../lib/http-auth");
5
+ const auth_1 = require("../trusted-session/auth");
6
+ const bearer_1 = require("../execution-authority/bearer");
7
+ const execution_authority_http_1 = require("../lib/execution-authority-http");
8
+ class EnrollmentAuthError extends Error {
9
+ contract;
10
+ constructor(contract) {
11
+ super(contract.message);
12
+ this.contract = contract;
13
+ this.name = 'EnrollmentAuthError';
14
+ }
15
+ }
16
+ exports.EnrollmentAuthError = EnrollmentAuthError;
17
+ function intersectTools(policy, hint) {
18
+ if (hint === undefined)
19
+ return policy;
20
+ const key = (t) => `${t.serviceId}\0${t.toolName}`;
21
+ const allowed = new Set(policy.map(key));
22
+ return hint.filter((t) => allowed.has(key(t)));
23
+ }
24
+ function requireEnrollmentAuth(request, store) {
25
+ const token = (0, http_auth_1.parseBearerToken)({ headers: request.headers });
26
+ if (!token) {
27
+ throw new EnrollmentAuthError({
28
+ ok: false,
29
+ error_code: 'COORDINATOR_NOT_ENROLLED',
30
+ message: 'Enrollment bearer required (enr_…:secret)',
31
+ });
32
+ }
33
+ const parsed = (0, bearer_1.parseEnrollmentBearer)(token);
34
+ if (!parsed) {
35
+ throw new EnrollmentAuthError({
36
+ ok: false,
37
+ error_code: 'COORDINATOR_NOT_ENROLLED',
38
+ message: 'Enrollment bearer required (enr_…:secret)',
39
+ });
40
+ }
41
+ const enrollment = store.getEnrollment(parsed.enrollmentId);
42
+ if (!enrollment) {
43
+ throw new EnrollmentAuthError({
44
+ ok: false,
45
+ error_code: 'COORDINATOR_NOT_ENROLLED',
46
+ message: 'Unknown enrollment',
47
+ correlation: { enrollmentId: parsed.enrollmentId },
48
+ });
49
+ }
50
+ if (enrollment.status !== 'active') {
51
+ throw new EnrollmentAuthError({
52
+ ok: false,
53
+ error_code: 'ENROLLMENT_REVOKED',
54
+ message: 'Enrollment is revoked',
55
+ reason: 'enrollment_revoked',
56
+ correlation: { enrollmentId: parsed.enrollmentId },
57
+ });
58
+ }
59
+ if (!store.verifyEnrollmentSecret(parsed.enrollmentId, parsed.secret)) {
60
+ throw new EnrollmentAuthError({
61
+ ok: false,
62
+ error_code: 'COORDINATOR_NOT_ENROLLED',
63
+ message: 'Invalid enrollment secret',
64
+ correlation: { enrollmentId: parsed.enrollmentId },
65
+ });
66
+ }
67
+ return { enrollmentId: parsed.enrollmentId };
68
+ }
69
+ /** Shared enrollment bearer resolve used by coordinator metadata + mint routes. */
70
+ function resolveEnrollmentAuth(request, store) {
71
+ try {
72
+ const { enrollmentId } = requireEnrollmentAuth(request, store);
73
+ const enrollment = store.getEnrollment(enrollmentId);
74
+ if (!enrollment) {
75
+ return {
76
+ ok: false,
77
+ contract: {
78
+ ok: false,
79
+ error_code: 'COORDINATOR_NOT_ENROLLED',
80
+ message: 'Unknown enrollment',
81
+ correlation: { enrollmentId },
82
+ },
83
+ };
84
+ }
85
+ return { ok: true, enrollmentId, enrollment };
86
+ }
87
+ catch (error) {
88
+ if (error instanceof EnrollmentAuthError) {
89
+ return { ok: false, contract: error.contract };
90
+ }
91
+ throw error;
92
+ }
93
+ }
94
+ function deckNotPermittedError(enrollmentId, deckId) {
95
+ return {
96
+ ok: false,
97
+ error_code: 'RESOURCE_OUT_OF_SCOPE',
98
+ message: 'Deck is not in allowedDeckIds',
99
+ reason: 'deck_not_permitted',
100
+ correlation: { enrollmentId, deckId },
101
+ };
102
+ }
103
+ function deckNotFoundError(enrollmentId, deckId) {
104
+ return {
105
+ ok: false,
106
+ error_code: 'RESOURCE_OUT_OF_SCOPE',
107
+ message: 'Deck not found',
108
+ reason: 'deck_not_found',
109
+ correlation: { enrollmentId, deckId },
110
+ };
111
+ }
112
+ /**
113
+ * Fastify decodes path params, so `/decks/x%2Fy/playbooks` yields `deckId === "x/y"`
114
+ * while the route-policy `[^/]+` still matched one encoded segment. Reject before scope checks.
115
+ */
116
+ function invalidDeckIdPathSegment(deckId) {
117
+ if (!deckId.includes('/'))
118
+ return null;
119
+ return {
120
+ ok: false,
121
+ error_code: 'INVALID_MINT_REQUEST',
122
+ message: 'deckId must be a single path segment',
123
+ correlation: { deckId },
124
+ };
125
+ }
126
+ /** Re-check enrollment after awaits so revoke cannot race a successful response. */
127
+ function revalidateActiveEnrollment(store, enrollmentId, deckId) {
128
+ const enrollment = store.getEnrollment(enrollmentId);
129
+ if (!enrollment || enrollment.status !== 'active') {
130
+ return {
131
+ ok: false,
132
+ error_code: 'ENROLLMENT_REVOKED',
133
+ message: 'Enrollment is revoked',
134
+ reason: 'enrollment_revoked',
135
+ correlation: { enrollmentId },
136
+ };
137
+ }
138
+ if (deckId !== undefined && !enrollment.allowedDeckIds.includes(deckId)) {
139
+ return deckNotPermittedError(enrollmentId, deckId);
140
+ }
141
+ return null;
142
+ }
143
+ async function requireEnrollmentOrTrustedWriter(request, store) {
144
+ try {
145
+ return { kind: 'enrollment', ...requireEnrollmentAuth(request, store) };
146
+ }
147
+ catch (error) {
148
+ if (!(error instanceof EnrollmentAuthError))
149
+ throw error;
150
+ try {
151
+ await (0, auth_1.requireTrustedWriterBearer)(request);
152
+ return { kind: 'trusted-writer' };
153
+ }
154
+ catch {
155
+ throw error;
156
+ }
157
+ }
158
+ }
159
+ const registerExecutionAuthorityRoutes = async (fastify) => {
160
+ const store = () => fastify.executionAuthorityStore;
161
+ fastify.post('/enrollments', async (request, reply) => {
162
+ try {
163
+ await (0, auth_1.requireTrustedWriterBearer)(request);
164
+ }
165
+ catch (error) {
166
+ if (error instanceof auth_1.TrustedAuthError) {
167
+ return (0, auth_1.sendTrustedAuthError)(reply, error);
168
+ }
169
+ throw error;
170
+ }
171
+ const body = (request.body ?? {});
172
+ if (!body.coordinatorId?.trim() || !Array.isArray(body.allowedDeckIds) || body.allowedDeckIds.length === 0) {
173
+ return reply.status(400).send({
174
+ ok: false,
175
+ error_code: 'INVALID_MINT_REQUEST',
176
+ message: 'coordinatorId and allowedDeckIds are required',
177
+ });
178
+ }
179
+ const result = store().enrollCoordinator({
180
+ coordinatorId: body.coordinatorId.trim(),
181
+ allowedDeckIds: body.allowedDeckIds.map(String),
182
+ });
183
+ if (!result.ok) {
184
+ return (0, execution_authority_http_1.sendContractError)(reply, result, (0, execution_authority_http_1.statusForContract)(result));
185
+ }
186
+ return { ok: true, data: result.data };
187
+ });
188
+ fastify.get('/enrollments/:id', async (request, reply) => {
189
+ try {
190
+ await (0, auth_1.requireTrustedWriterBearer)(request);
191
+ }
192
+ catch (error) {
193
+ if (error instanceof auth_1.TrustedAuthError) {
194
+ return (0, auth_1.sendTrustedAuthError)(reply, error);
195
+ }
196
+ throw error;
197
+ }
198
+ const enrollment = store().getEnrollment(request.params.id);
199
+ if (!enrollment) {
200
+ return reply.status(404).send({
201
+ ok: false,
202
+ error_code: 'COORDINATOR_NOT_ENROLLED',
203
+ message: 'Unknown enrollment',
204
+ });
205
+ }
206
+ return { ok: true, data: enrollment };
207
+ });
208
+ fastify.post('/enrollments/:id/revoke', async (request, reply) => {
209
+ try {
210
+ await (0, auth_1.requireTrustedWriterBearer)(request);
211
+ }
212
+ catch (error) {
213
+ if (error instanceof auth_1.TrustedAuthError) {
214
+ return (0, auth_1.sendTrustedAuthError)(reply, error);
215
+ }
216
+ throw error;
217
+ }
218
+ const result = store().revokeEnrollment(request.params.id);
219
+ if (!result.ok) {
220
+ return (0, execution_authority_http_1.sendContractError)(reply, result, (0, execution_authority_http_1.statusForContract)(result));
221
+ }
222
+ return { ok: true, data: result.data };
223
+ });
224
+ fastify.get('/decks', async (request, reply) => {
225
+ const auth = resolveEnrollmentAuth(request, store());
226
+ if (!auth.ok) {
227
+ return (0, execution_authority_http_1.sendContractError)(reply, auth.contract, (0, execution_authority_http_1.statusForContract)(auth.contract));
228
+ }
229
+ const decks = [];
230
+ for (const id of auth.enrollment.allowedDeckIds) {
231
+ const deck = await fastify.db.getDeck(id);
232
+ if (deck) {
233
+ decks.push({ id: deck.id, name: deck.name });
234
+ }
235
+ }
236
+ const stale = revalidateActiveEnrollment(store(), auth.enrollmentId);
237
+ if (stale) {
238
+ return (0, execution_authority_http_1.sendContractError)(reply, stale, (0, execution_authority_http_1.statusForContract)(stale));
239
+ }
240
+ return { ok: true, data: { decks } };
241
+ });
242
+ fastify.get('/decks/:deckId/playbooks', async (request, reply) => {
243
+ const auth = resolveEnrollmentAuth(request, store());
244
+ if (!auth.ok) {
245
+ return (0, execution_authority_http_1.sendContractError)(reply, auth.contract, (0, execution_authority_http_1.statusForContract)(auth.contract));
246
+ }
247
+ const { deckId } = request.params;
248
+ const badSegment = invalidDeckIdPathSegment(deckId);
249
+ if (badSegment) {
250
+ return (0, execution_authority_http_1.sendContractError)(reply, badSegment, (0, execution_authority_http_1.statusForContract)(badSegment));
251
+ }
252
+ if (!auth.enrollment.allowedDeckIds.includes(deckId)) {
253
+ return (0, execution_authority_http_1.sendContractError)(reply, deckNotPermittedError(auth.enrollmentId, deckId));
254
+ }
255
+ // Fail closed for deleted-but-still-allowed decks (distinct from not-in-allowedDeckIds).
256
+ // Sibling GET /decks omits missing ids from the list; path-param discovery must not.
257
+ if (!(await fastify.db.hasDeck(deckId))) {
258
+ return (0, execution_authority_http_1.sendContractError)(reply, deckNotFoundError(auth.enrollmentId, deckId));
259
+ }
260
+ const playbooks = await fastify.playbookManager.listSummariesForDeck(deckId);
261
+ const stale = revalidateActiveEnrollment(store(), auth.enrollmentId, deckId);
262
+ if (stale) {
263
+ return (0, execution_authority_http_1.sendContractError)(reply, stale, (0, execution_authority_http_1.statusForContract)(stale));
264
+ }
265
+ return { ok: true, data: playbooks };
266
+ });
267
+ fastify.post('/authorities', async (request, reply) => {
268
+ const auth = resolveEnrollmentAuth(request, store());
269
+ if (!auth.ok) {
270
+ return (0, execution_authority_http_1.sendContractError)(reply, auth.contract, (0, execution_authority_http_1.statusForContract)(auth.contract));
271
+ }
272
+ const { enrollmentId } = auth;
273
+ const body = (request.body ?? {});
274
+ if (body.enrollmentId && body.enrollmentId !== enrollmentId) {
275
+ return reply.status(400).send({
276
+ ok: false,
277
+ error_code: 'INVALID_MINT_REQUEST',
278
+ message: 'enrollmentId does not match bearer',
279
+ });
280
+ }
281
+ if (!body.runId?.trim() ||
282
+ !body.attemptId?.trim() ||
283
+ !body.deckId?.trim() ||
284
+ !body.idempotencyKey?.trim() ||
285
+ body.audience !== 'dealer-worker' ||
286
+ !(body.ttlMs > 0)) {
287
+ return reply.status(400).send({
288
+ ok: false,
289
+ error_code: 'INVALID_MINT_REQUEST',
290
+ message: 'runId, attemptId, deckId, audience=dealer-worker, idempotencyKey, ttlMs>0 required',
291
+ });
292
+ }
293
+ const deckId = body.deckId.trim();
294
+ // Scope check before existence so missing out-of-scope ids stay deck_not_permitted.
295
+ if (!auth.enrollment.allowedDeckIds.includes(deckId)) {
296
+ return (0, execution_authority_http_1.sendContractError)(reply, deckNotPermittedError(enrollmentId, deckId));
297
+ }
298
+ const deck = await fastify.db.getDeck(deckId);
299
+ if (!deck) {
300
+ return (0, execution_authority_http_1.sendContractError)(reply, deckNotFoundError(enrollmentId, deckId));
301
+ }
302
+ const services = deck.services ?? [];
303
+ const allowedTools = [];
304
+ const allowedServices = [];
305
+ for (const service of services) {
306
+ allowedServices.push(service.id);
307
+ const discovered = await fastify.serviceManager.discoverServiceTools(service.id, {
308
+ forAgent: true,
309
+ });
310
+ if (Array.isArray(discovered)) {
311
+ for (const tool of discovered) {
312
+ allowedTools.push({ serviceId: service.id, toolName: tool.name });
313
+ }
314
+ }
315
+ }
316
+ const narrowedTools = intersectTools(allowedTools, body.toolScopeHint);
317
+ const narrowedServiceIds = [...new Set(narrowedTools.map((t) => t.serviceId))];
318
+ // undefined hint → full deck services; explicit hint (incl. []) → services from snapshot only
319
+ const mintServices = body.toolScopeHint === undefined ? allowedServices : narrowedServiceIds;
320
+ const stale = revalidateActiveEnrollment(store(), enrollmentId, deckId);
321
+ if (stale) {
322
+ return (0, execution_authority_http_1.sendContractError)(reply, stale, (0, execution_authority_http_1.statusForContract)(stale));
323
+ }
324
+ const result = store().mintAuthority({
325
+ enrollmentId,
326
+ runId: body.runId.trim(),
327
+ attemptId: body.attemptId.trim(),
328
+ deckId,
329
+ audience: 'dealer-worker',
330
+ idempotencyKey: body.idempotencyKey.trim(),
331
+ allowedServices: mintServices,
332
+ allowedTools: narrowedTools,
333
+ ttlMs: body.ttlMs,
334
+ });
335
+ if (!result.ok) {
336
+ return (0, execution_authority_http_1.sendContractError)(reply, result, (0, execution_authority_http_1.statusForContract)(result));
337
+ }
338
+ return { ok: true, data: result.data };
339
+ });
340
+ fastify.get('/authorities/:id', async (request, reply) => {
341
+ let principal;
342
+ try {
343
+ principal = await requireEnrollmentOrTrustedWriter(request, store());
344
+ }
345
+ catch (error) {
346
+ if (error instanceof EnrollmentAuthError) {
347
+ return (0, execution_authority_http_1.sendContractError)(reply, error.contract, (0, execution_authority_http_1.statusForContract)(error.contract));
348
+ }
349
+ throw error;
350
+ }
351
+ const peeked = store().peekAuthority(request.params.id);
352
+ if (!peeked ||
353
+ (principal.kind === 'enrollment' && peeked.enrollmentId !== principal.enrollmentId)) {
354
+ return (0, execution_authority_http_1.sendContractError)(reply, {
355
+ ok: false,
356
+ error_code: 'AUTHORITY_UNKNOWN',
357
+ message: 'Unknown authority',
358
+ correlation: { authorityId: request.params.id },
359
+ }, 404);
360
+ }
361
+ const result = store().inspectAuthority(request.params.id);
362
+ if (!result.ok) {
363
+ return (0, execution_authority_http_1.sendContractError)(reply, result, (0, execution_authority_http_1.statusForContract)(result));
364
+ }
365
+ return { ok: true, data: result.data };
366
+ });
367
+ fastify.post('/authorities/:id/revoke', async (request, reply) => {
368
+ let principal;
369
+ try {
370
+ principal = await requireEnrollmentOrTrustedWriter(request, store());
371
+ }
372
+ catch (error) {
373
+ if (error instanceof EnrollmentAuthError) {
374
+ return (0, execution_authority_http_1.sendContractError)(reply, error.contract, (0, execution_authority_http_1.statusForContract)(error.contract));
375
+ }
376
+ throw error;
377
+ }
378
+ const peeked = store().peekAuthority(request.params.id);
379
+ if (!peeked ||
380
+ (principal.kind === 'enrollment' && peeked.enrollmentId !== principal.enrollmentId)) {
381
+ return (0, execution_authority_http_1.sendContractError)(reply, {
382
+ ok: false,
383
+ error_code: 'AUTHORITY_UNKNOWN',
384
+ message: 'Unknown authority',
385
+ correlation: { authorityId: request.params.id },
386
+ }, 404);
387
+ }
388
+ const result = store().revokeAuthority(request.params.id);
389
+ if (!result.ok) {
390
+ return (0, execution_authority_http_1.sendContractError)(reply, result, (0, execution_authority_http_1.statusForContract)(result));
391
+ }
392
+ return { ok: true, data: result.data };
393
+ });
394
+ fastify.get('/audit', async (request, reply) => {
395
+ let principal;
396
+ try {
397
+ principal = await requireEnrollmentOrTrustedWriter(request, store());
398
+ }
399
+ catch (error) {
400
+ if (error instanceof EnrollmentAuthError) {
401
+ return (0, execution_authority_http_1.sendContractError)(reply, error.contract, (0, execution_authority_http_1.statusForContract)(error.contract));
402
+ }
403
+ throw error;
404
+ }
405
+ const q = request.query;
406
+ if (principal.kind === 'enrollment') {
407
+ if (q.enrollmentId && q.enrollmentId !== principal.enrollmentId) {
408
+ return (0, execution_authority_http_1.sendContractError)(reply, {
409
+ ok: false,
410
+ error_code: 'RESOURCE_OUT_OF_SCOPE',
411
+ message: 'Cannot query audit for another enrollment',
412
+ correlation: { enrollmentId: principal.enrollmentId },
413
+ }, 403);
414
+ }
415
+ if (q.authorityId) {
416
+ const owned = store().peekAuthority(q.authorityId);
417
+ if (!owned || owned.enrollmentId !== principal.enrollmentId) {
418
+ return (0, execution_authority_http_1.sendContractError)(reply, {
419
+ ok: false,
420
+ error_code: 'AUTHORITY_UNKNOWN',
421
+ message: 'Unknown authority',
422
+ correlation: { authorityId: q.authorityId },
423
+ }, 404);
424
+ }
425
+ }
426
+ }
427
+ const events = store().listAuditEvents({
428
+ runId: q.runId,
429
+ attemptId: q.attemptId,
430
+ authorityId: q.authorityId,
431
+ enrollmentId: principal.kind === 'enrollment' ? principal.enrollmentId : q.enrollmentId,
432
+ requestId: q.requestId,
433
+ });
434
+ return { ok: true, data: { events } };
435
+ });
436
+ fastify.post('/mcp/connect', async (request, reply) => {
437
+ const body = (request.body ?? {});
438
+ const token = (0, http_auth_1.parseBearerToken)(request);
439
+ const fromBearer = token ? (0, bearer_1.parseAuthorityBearer)(token) : null;
440
+ const authorityId = fromBearer?.authorityId ?? body.authorityId?.trim();
441
+ const authoritySecret = fromBearer?.secret ?? body.authoritySecret?.trim();
442
+ const audience = body.audience?.trim() || 'dealer-worker';
443
+ if (!authorityId || !authoritySecret) {
444
+ return reply.status(401).send({
445
+ ok: false,
446
+ error_code: 'AUTHORITY_SECRET_INVALID',
447
+ message: 'authorityId and authoritySecret required',
448
+ });
449
+ }
450
+ const auth = store().authenticateAuthority(authorityId, authoritySecret);
451
+ if (!auth.ok) {
452
+ return (0, execution_authority_http_1.sendContractError)(reply, auth, (0, execution_authority_http_1.statusForContract)(auth));
453
+ }
454
+ if (audience !== auth.data.audience) {
455
+ return reply.status(403).send({
456
+ ok: false,
457
+ error_code: 'AUDIENCE_MISMATCH',
458
+ message: 'Caller audience does not match authority audience',
459
+ correlation: { authorityId },
460
+ });
461
+ }
462
+ return {
463
+ ok: true,
464
+ data: {
465
+ authorityId: auth.data.authorityId,
466
+ deckId: auth.data.deckId,
467
+ audience: auth.data.audience,
468
+ runId: auth.data.runId,
469
+ attemptId: auth.data.attemptId,
470
+ allowedServices: auth.data.allowedServices,
471
+ allowedTools: auth.data.allowedTools,
472
+ expiresAt: auth.data.expiresAt,
473
+ status: auth.data.status,
474
+ },
475
+ };
476
+ });
477
+ /** Authorize one tool call under execution authority (MCP / internal). */
478
+ fastify.post('/authorize-call', async (request, reply) => {
479
+ const body = (request.body ?? {});
480
+ if (!body.authorityId ||
481
+ !body.authoritySecret ||
482
+ !body.audience ||
483
+ !body.serviceId ||
484
+ !body.toolName) {
485
+ return reply.status(400).send({
486
+ ok: false,
487
+ error_code: 'INVALID_MINT_REQUEST',
488
+ message: 'authorityId, authoritySecret, audience, serviceId, toolName required',
489
+ });
490
+ }
491
+ const result = store().invokeAuthorizedCall({
492
+ authorityId: body.authorityId,
493
+ authoritySecret: body.authoritySecret,
494
+ audience: body.audience,
495
+ serviceId: body.serviceId,
496
+ toolName: body.toolName,
497
+ requiresInteraction: body.requiresInteraction,
498
+ });
499
+ if (!result.ok) {
500
+ return (0, execution_authority_http_1.sendContractError)(reply, result, (0, execution_authority_http_1.statusForContract)(result));
501
+ }
502
+ return { ok: true, data: result.data };
503
+ });
504
+ };
505
+ exports.registerExecutionAuthorityRoutes = registerExecutionAuthorityRoutes;
506
+ //# sourceMappingURL=execution-authority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-authority.js","sourceRoot":"","sources":["../../src/routes/execution-authority.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/routes/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAiC1C,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,eAAe,iBAoLjE"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/routes/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAsE1C,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,eAAe,iBAyMjE"}
@@ -5,6 +5,7 @@ const zod_1 = require("zod");
5
5
  const shared_1 = require("@agent-deck/shared");
6
6
  const agent_deck_context_1 = require("../lib/agent-deck-context");
7
7
  const client_scope_1 = require("../lib/client-scope");
8
+ const execution_authority_http_1 = require("../lib/execution-authority-http");
8
9
  const display_1 = require("../scope/display");
9
10
  const LiveDisplayBodySchema = zod_1.z.object({
10
11
  mcpSessionId: zod_1.z.string().min(1),
@@ -24,6 +25,28 @@ const DeckWorkspaceBodySchema = zod_1.z.object({
24
25
  workspaceRoot: zod_1.z.string().min(1),
25
26
  deckId: zod_1.z.string().uuid(),
26
27
  });
28
+ function assertAuthorityDeniedLiveDisplay(request) {
29
+ const principal = request.requestPrincipal;
30
+ if (principal?.kind === 'execution-authority') {
31
+ throw new execution_authority_http_1.AuthorityContractAuthError({
32
+ ok: false,
33
+ error_code: 'INTERACTION_REQUIRED',
34
+ message: 'Control-plane decision required; do not hold the worker',
35
+ correlation: principal.authority
36
+ ? { authorityId: principal.authority.authorityId }
37
+ : undefined,
38
+ });
39
+ }
40
+ }
41
+ function assertAuthorityLiveDisplayWrite(request, deckId) {
42
+ assertAuthorityDeniedLiveDisplay(request);
43
+ void deckId;
44
+ return undefined;
45
+ }
46
+ function assertAuthorityLiveDisplaySession(request, entry) {
47
+ assertAuthorityDeniedLiveDisplay(request);
48
+ void entry;
49
+ }
27
50
  async function registerScopeRoutes(fastify) {
28
51
  fastify.get('/deck', async (request, reply) => {
29
52
  try {
@@ -95,10 +118,17 @@ async function registerScopeRoutes(fastify) {
95
118
  error: parsed.error.issues.map((issue) => issue.message).join('; '),
96
119
  });
97
120
  }
98
- const entry = fastify.liveDisplayRegistry.upsert(parsed.data);
121
+ const authorityId = assertAuthorityLiveDisplayWrite(request, parsed.data.deckId);
122
+ const entry = fastify.liveDisplayRegistry.upsert({
123
+ ...parsed.data,
124
+ authorityId,
125
+ });
99
126
  return reply.send({ success: true, data: { badge: entry.badge } });
100
127
  }
101
128
  catch (error) {
129
+ if (error instanceof execution_authority_http_1.AuthorityContractAuthError) {
130
+ return (0, execution_authority_http_1.sendContractError)(reply, error.contract);
131
+ }
102
132
  return reply.status(403).send({
103
133
  success: false,
104
134
  error: error instanceof Error ? error.message : 'Forbidden',
@@ -115,10 +145,14 @@ async function registerScopeRoutes(fastify) {
115
145
  error: 'mcpSessionId is required',
116
146
  });
117
147
  }
148
+ assertAuthorityLiveDisplaySession(request, fastify.liveDisplayRegistry.get(mcpSessionId));
118
149
  fastify.liveDisplayRegistry.remove(mcpSessionId);
119
150
  return reply.send({ success: true });
120
151
  }
121
152
  catch (error) {
153
+ if (error instanceof execution_authority_http_1.AuthorityContractAuthError) {
154
+ return (0, execution_authority_http_1.sendContractError)(reply, error.contract);
155
+ }
122
156
  return reply.status(403).send({
123
157
  success: false,
124
158
  error: error instanceof Error ? error.message : 'Forbidden',
@@ -135,12 +169,16 @@ async function registerScopeRoutes(fastify) {
135
169
  error: 'mcpSessionId is required',
136
170
  });
137
171
  }
172
+ assertAuthorityLiveDisplaySession(request, fastify.liveDisplayRegistry.get(mcpSessionId));
138
173
  const parsed = LiveDisplayTouchSchema.safeParse(request.body ?? {});
139
174
  const at = parsed.success && parsed.data.at ? parsed.data.at : new Date().toISOString();
140
175
  fastify.liveDisplayRegistry.touch(mcpSessionId, at);
141
176
  return reply.send({ success: true });
142
177
  }
143
178
  catch (error) {
179
+ if (error instanceof execution_authority_http_1.AuthorityContractAuthError) {
180
+ return (0, execution_authority_http_1.sendContractError)(reply, error.contract);
181
+ }
144
182
  return reply.status(403).send({
145
183
  success: false,
146
184
  error: error instanceof Error ? error.message : 'Forbidden',