@mandatez/sdk 0.1.2 → 0.1.8

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 (62) hide show
  1. package/README.md +193 -95
  2. package/dist/attestations/index.d.ts +50 -0
  3. package/dist/attestations/index.d.ts.map +1 -0
  4. package/dist/attestations/index.js +30 -0
  5. package/dist/attestations/index.js.map +1 -0
  6. package/dist/client.d.ts +183 -0
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +256 -3
  9. package/dist/client.js.map +1 -1
  10. package/dist/exporters/datadog.d.ts +34 -0
  11. package/dist/exporters/datadog.d.ts.map +1 -0
  12. package/dist/exporters/datadog.js +69 -0
  13. package/dist/exporters/datadog.js.map +1 -0
  14. package/dist/exporters/index.d.ts +26 -0
  15. package/dist/exporters/index.d.ts.map +1 -0
  16. package/dist/exporters/index.js +5 -0
  17. package/dist/exporters/index.js.map +1 -0
  18. package/dist/exporters/otel.d.ts +38 -0
  19. package/dist/exporters/otel.d.ts.map +1 -0
  20. package/dist/exporters/otel.js +115 -0
  21. package/dist/exporters/otel.js.map +1 -0
  22. package/dist/exporters/splunk.d.ts +33 -0
  23. package/dist/exporters/splunk.d.ts.map +1 -0
  24. package/dist/exporters/splunk.js +62 -0
  25. package/dist/exporters/splunk.js.map +1 -0
  26. package/dist/exporters/webhook.d.ts +33 -0
  27. package/dist/exporters/webhook.d.ts.map +1 -0
  28. package/dist/exporters/webhook.js +52 -0
  29. package/dist/exporters/webhook.js.map +1 -0
  30. package/dist/identity/hibp.d.ts +39 -0
  31. package/dist/identity/hibp.d.ts.map +1 -0
  32. package/dist/identity/hibp.js +85 -0
  33. package/dist/identity/hibp.js.map +1 -0
  34. package/dist/index.d.ts +16 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +8 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/integrations/langchain/decorator.d.ts +31 -0
  39. package/dist/integrations/langchain/decorator.d.ts.map +1 -0
  40. package/dist/integrations/langchain/decorator.js +36 -0
  41. package/dist/integrations/langchain/decorator.js.map +1 -0
  42. package/dist/policies/templates.d.ts +223 -0
  43. package/dist/policies/templates.d.ts.map +1 -0
  44. package/dist/policies/templates.js +102 -0
  45. package/dist/policies/templates.js.map +1 -0
  46. package/dist/risk/index.d.ts +58 -0
  47. package/dist/risk/index.d.ts.map +1 -0
  48. package/dist/risk/index.js +45 -0
  49. package/dist/risk/index.js.map +1 -0
  50. package/dist/transport/supabase.d.ts +29 -0
  51. package/dist/transport/supabase.d.ts.map +1 -1
  52. package/dist/transport/supabase.js +81 -0
  53. package/dist/transport/supabase.js.map +1 -1
  54. package/dist/trust/posture.d.ts +24 -0
  55. package/dist/trust/posture.d.ts.map +1 -0
  56. package/dist/trust/posture.js +79 -0
  57. package/dist/trust/posture.js.map +1 -0
  58. package/dist/wrapper/index.d.ts +26 -0
  59. package/dist/wrapper/index.d.ts.map +1 -0
  60. package/dist/wrapper/index.js +162 -0
  61. package/dist/wrapper/index.js.map +1 -0
  62. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -2,6 +2,10 @@ import { createSignedEvent } from './events/signing.js';
2
2
  import { SupabaseTransport } from './transport/supabase.js';
3
3
  import { PolicyEngine } from './policy/index.js';
4
4
  import { OversightGate } from './oversight/index.js';
5
+ import { computeTrustScore } from './trust/posture.js';
6
+ import { checkIdentity as hibpCheckIdentity } from './identity/hibp.js';
7
+ import { getRiskScore as fetchRiskScore, computeRiskScore as triggerRiskScoreCompute, } from './risk/index.js';
8
+ const DEFAULT_DIRECTORY_URL = 'https://core-directory.vercel.app';
5
9
  /**
6
10
  * Main SDK surface for developers.
7
11
  *
@@ -15,10 +19,25 @@ export class MandateZClient {
15
19
  transport;
16
20
  policyEngine;
17
21
  oversightGate;
22
+ trustProfile = null;
23
+ hibpApiKey;
24
+ directoryUrl;
25
+ exporters;
26
+ apiUrl;
27
+ apiKey;
28
+ batchConfig;
29
+ buffer = [];
30
+ bufferFlushTimer = null;
18
31
  constructor(config) {
19
32
  this.agentId = config.agentId;
20
33
  this.ownerId = config.ownerId;
21
34
  this.privateKey = config.privateKey;
35
+ this.hibpApiKey = config.hibpApiKey ?? null;
36
+ this.directoryUrl = (config.directoryUrl ?? DEFAULT_DIRECTORY_URL).replace(/\/+$/, '');
37
+ this.exporters = config.exporters ?? [];
38
+ this.apiUrl = config.apiUrl ? config.apiUrl.replace(/\/+$/, '') : null;
39
+ this.apiKey = config.apiKey ?? null;
40
+ this.batchConfig = config.batchConfig ?? null;
22
41
  this.transport = new SupabaseTransport({
23
42
  supabaseUrl: config.supabaseUrl,
24
43
  supabaseAnonKey: config.supabaseAnonKey,
@@ -68,7 +87,11 @@ export class MandateZClient {
68
87
  }, input.waitForApproval);
69
88
  outcome = oversightResult.outcome;
70
89
  }
71
- // Step 4: Sign and emit
90
+ // Step 4: Sign and emit — include trust_score in metadata
91
+ const metadata = {
92
+ ...(input.metadata ?? {}),
93
+ trust_score: this.trustProfile?.trust_score ?? 0,
94
+ };
72
95
  const eventInput = {
73
96
  agent_id: this.agentId,
74
97
  owner_id: this.ownerId,
@@ -76,10 +99,240 @@ export class MandateZClient {
76
99
  resource: input.resource,
77
100
  outcome,
78
101
  policy_id: policyId ?? null,
79
- metadata: input.metadata ?? {},
102
+ metadata,
80
103
  };
81
104
  const signed = await createSignedEvent(eventInput, this.privateKey);
82
- return this.transport.emitEvent(signed);
105
+ // Buffering mode: queue the signed event and let the batch flush handle
106
+ // delivery. The returned event is authoritative (already signed) even
107
+ // though it has not yet reached the server.
108
+ if (this.batchConfig?.enabled) {
109
+ this.enqueue(signed);
110
+ this.fanOutToExporters(signed);
111
+ return signed;
112
+ }
113
+ const emitted = await this.transport.emitEvent(signed);
114
+ // Fire-and-forget: recompute trust score in background
115
+ this.recomputeTrustScore().catch(() => { });
116
+ // Fire-and-forget: fan out to every configured exporter in parallel.
117
+ // Exporter failures are logged but never block the main flow.
118
+ this.fanOutToExporters(emitted);
119
+ return emitted;
120
+ }
121
+ /**
122
+ * Signs each input event locally and posts the batch to /api/events/batch.
123
+ *
124
+ * Requires `apiUrl` in config. The endpoint rejects the entire batch if
125
+ * any signature or schema check fails, so a returned `rejected` count is
126
+ * either 0 (all accepted) or equal to the input length (nothing inserted).
127
+ */
128
+ async trackBatch(events) {
129
+ if (!this.apiUrl) {
130
+ throw new Error('MandateZClient: apiUrl is required in config to call trackBatch()');
131
+ }
132
+ if (events.length === 0) {
133
+ return { accepted: 0, rejected: 0, errors: [] };
134
+ }
135
+ const signed = await Promise.all(events.map((input) => createSignedEvent({
136
+ agent_id: this.agentId,
137
+ owner_id: this.ownerId,
138
+ action_type: input.action_type,
139
+ resource: input.resource,
140
+ outcome: input.outcome ?? 'allowed',
141
+ policy_id: input.policy_id ?? null,
142
+ metadata: input.metadata ?? {},
143
+ }, this.privateKey)));
144
+ return this.postBatch(signed);
145
+ }
146
+ /**
147
+ * Flushes any buffered events immediately. Callers should invoke this
148
+ * during graceful shutdown to avoid dropping queued events.
149
+ */
150
+ async flush() {
151
+ if (this.bufferFlushTimer) {
152
+ clearTimeout(this.bufferFlushTimer);
153
+ this.bufferFlushTimer = null;
154
+ }
155
+ const pending = this.buffer;
156
+ this.buffer = [];
157
+ if (pending.length === 0) {
158
+ return { accepted: 0, rejected: 0, errors: [] };
159
+ }
160
+ return this.postBatch(pending);
161
+ }
162
+ enqueue(event) {
163
+ if (!this.batchConfig)
164
+ return;
165
+ this.buffer.push(event);
166
+ if (this.buffer.length >= this.batchConfig.maxSize) {
167
+ void this.flush().catch(() => { });
168
+ return;
169
+ }
170
+ if (!this.bufferFlushTimer) {
171
+ this.bufferFlushTimer = setTimeout(() => {
172
+ this.bufferFlushTimer = null;
173
+ void this.flush().catch(() => { });
174
+ }, this.batchConfig.maxWaitMs);
175
+ }
176
+ }
177
+ async postBatch(events) {
178
+ if (!this.apiUrl) {
179
+ throw new Error('MandateZClient: apiUrl is required to flush batched events');
180
+ }
181
+ const headers = { 'Content-Type': 'application/json' };
182
+ if (this.apiKey)
183
+ headers['Authorization'] = `Bearer ${this.apiKey}`;
184
+ const res = await fetch(`${this.apiUrl}/api/events/batch`, {
185
+ method: 'POST',
186
+ headers,
187
+ body: JSON.stringify({ owner_id: this.ownerId, events }),
188
+ });
189
+ const payload = (await res.json().catch(() => ({})));
190
+ if (!res.ok) {
191
+ return {
192
+ accepted: payload.accepted ?? 0,
193
+ rejected: payload.rejected ?? events.length,
194
+ errors: payload.errors ?? [
195
+ { index: -1, reason: 'http_error', detail: payload.error ?? `HTTP ${res.status}` },
196
+ ],
197
+ };
198
+ }
199
+ return {
200
+ accepted: payload.accepted ?? 0,
201
+ rejected: payload.rejected ?? 0,
202
+ errors: payload.errors ?? [],
203
+ };
204
+ }
205
+ fanOutToExporters(event) {
206
+ if (this.exporters.length === 0)
207
+ return;
208
+ for (const exporter of this.exporters) {
209
+ // Each exporter runs independently; one failing cannot affect another.
210
+ exporter.export(event).catch((err) => {
211
+ const message = err instanceof Error ? err.message : String(err);
212
+ // eslint-disable-next-line no-console
213
+ console.warn(`[mandatez] exporter "${exporter.name}" failed: ${message}`);
214
+ });
215
+ }
216
+ }
217
+ /**
218
+ * Fetches all events for this agent from Supabase, recomputes
219
+ * the trust score, and updates the agents table.
220
+ */
221
+ async recomputeTrustScore() {
222
+ const events = await this.transport.fetchAgentEvents(this.agentId);
223
+ const profile = computeTrustScore(events);
224
+ this.trustProfile = profile;
225
+ await this.transport.updateAgentTrust(this.agentId, profile);
226
+ return profile;
227
+ }
228
+ /**
229
+ * Returns the last computed trust profile, or null if not yet computed.
230
+ */
231
+ getTrustProfile() {
232
+ return this.trustProfile;
233
+ }
234
+ /**
235
+ * Checks an email against HaveIBeenPwned, stores the result in
236
+ * Supabase (identity_checks table), and returns a recommendation.
237
+ *
238
+ * Recommendation logic:
239
+ * - status=clean → allow
240
+ * - status=flagged → onFlagged (default: 'restrict')
241
+ * - status=blocked → block (cannot be overridden)
242
+ */
243
+ async checkIdentity(input) {
244
+ if (!this.hibpApiKey) {
245
+ throw new Error('MandateZClient: hibpApiKey is required in config to call checkIdentity()');
246
+ }
247
+ const result = await hibpCheckIdentity(input.email, this.hibpApiKey);
248
+ const agentId = input.agentId ?? this.agentId;
249
+ // Fire-and-forget persistence — don't let Supabase failures block the caller
250
+ this.transport
251
+ .insertIdentityCheck({
252
+ ownerId: this.ownerId,
253
+ agentId,
254
+ email: input.email,
255
+ result,
256
+ })
257
+ .catch(() => { });
258
+ const onFlagged = input.onFlagged ?? 'restrict';
259
+ let recommendation;
260
+ if (result.status === 'blocked')
261
+ recommendation = 'block';
262
+ else if (result.status === 'flagged')
263
+ recommendation = onFlagged;
264
+ else
265
+ recommendation = 'allow';
266
+ return { ...result, recommendation };
267
+ }
268
+ /**
269
+ * Verify another agent's MandateZ credentials before transacting with it.
270
+ *
271
+ * Calls the MandateZ directory's /api/agents/verify endpoint and returns
272
+ * whether the target agent meets the minimum trust score and grade you
273
+ * specified. Use this at the edge of any cross-agent interaction.
274
+ *
275
+ * @example
276
+ * const result = await client.verifyAgent({
277
+ * requestingAgentId: 'ag_my_agent',
278
+ * targetAgentId: 'ag_partner_agent',
279
+ * requiredMinScore: 70,
280
+ * });
281
+ * if (!result.verified) {
282
+ * throw new Error('Partner agent failed MandateZ verification');
283
+ * }
284
+ */
285
+ async verifyAgent(input) {
286
+ const res = await fetch(`${this.directoryUrl}/api/agents/verify`, {
287
+ method: 'POST',
288
+ headers: { 'Content-Type': 'application/json' },
289
+ body: JSON.stringify({
290
+ requesting_agent_id: input.requestingAgentId,
291
+ target_agent_id: input.targetAgentId,
292
+ required_min_score: input.requiredMinScore,
293
+ required_min_grade: input.requiredMinGrade,
294
+ }),
295
+ });
296
+ if (!res.ok) {
297
+ const err = (await res.json().catch(() => ({})));
298
+ throw new Error(err.error
299
+ ? `MandateZ verifyAgent failed: ${err.error}`
300
+ : `MandateZ verifyAgent failed: HTTP ${res.status}`);
301
+ }
302
+ const raw = (await res.json());
303
+ return {
304
+ verified: raw.verified,
305
+ targetTrustScore: raw.target_agent.trust_score,
306
+ targetTrustGrade: raw.target_agent.trust_grade,
307
+ targetPublicKey: raw.target_agent.public_key,
308
+ verificationId: raw.verification.verification_id,
309
+ raw,
310
+ };
311
+ }
312
+ /**
313
+ * Fetch the most recent risk score for an agent from the MandateZ
314
+ * dashboard. The server auto-computes a fresh score if none exists yet,
315
+ * so this never returns null.
316
+ *
317
+ * Requires `apiUrl` and `apiKey` in the client config.
318
+ */
319
+ async getRiskScore(agentId) {
320
+ if (!this.apiUrl || !this.apiKey) {
321
+ throw new Error('MandateZClient: apiUrl and apiKey are required in config to call getRiskScore()');
322
+ }
323
+ return fetchRiskScore(agentId, { apiUrl: this.apiUrl, apiKey: this.apiKey });
324
+ }
325
+ /**
326
+ * Trigger a fresh risk-score recomputation for an agent. The returned
327
+ * record is the newly persisted snapshot.
328
+ *
329
+ * Requires `apiUrl` and `apiKey` in the client config.
330
+ */
331
+ async computeRiskScore(agentId, windowDays) {
332
+ if (!this.apiUrl || !this.apiKey) {
333
+ throw new Error('MandateZClient: apiUrl and apiKey are required in config to call computeRiskScore()');
334
+ }
335
+ return triggerRiskScoreCompute(agentId, { apiUrl: this.apiUrl, apiKey: this.apiKey }, windowDays);
83
336
  }
84
337
  }
85
338
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA6BrD;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACjB,OAAO,CAAS;IAChB,OAAO,CAAS;IAChB,UAAU,CAAS;IACnB,SAAS,CAAoB;IAC7B,YAAY,CAAe;IAC3B,aAAa,CAAuB;IAE5C,YAAY,MAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,IAAI,iBAAiB,CAAC;YACrC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,eAAe,EAAE,MAAM,CAAC,eAAe;SACxC,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACrC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,SAAS;YACnC,CAAC,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC;YACrC,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,KAAK,CAAC,KAAiB;QAC3B,4BAA4B;QAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnF,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC;QACpD,IAAI,QAAQ,GAAG,KAAK,CAAC,SAAS,IAAI,YAAY,CAAC,SAAS,CAAC;QAEzD,kDAAkD;QAClD,IAAI,YAAY,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACzD,OAAO,GAAG,SAAS,CAAC;YACpB,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC;QACpC,CAAC;QAED,6DAA6D;QAC7D,IACE,OAAO,KAAK,SAAS;YACrB,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,EACtD,CAAC;YACD,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,eAAe,CAC9D;gBACE,QAAQ,EAAE,IAAI,CAAC,OAAO;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;gBAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,iBAAiB,EAAE,IAAI;aACxB,EACD,KAAK,CAAC,eAAe,CACtB,CAAC;YAEF,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC;QACpC,CAAC;QAED,wBAAwB;QACxB,MAAM,UAAU,GAAoB;YAClC,QAAQ,EAAE,IAAI,CAAC,OAAO;YACtB,QAAQ,EAAE,IAAI,CAAC,OAAO;YACtB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO;YACP,SAAS,EAAE,QAAQ,IAAI,IAAI;YAC3B,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;SAC/B,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;CACF"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { AgentEvent } from '../events/schema.js';
2
+ import type { EventExporter } from './index.js';
3
+ export interface DatadogExporterConfig {
4
+ /** Datadog API key (DD-API-KEY). Required. */
5
+ apiKey: string;
6
+ /**
7
+ * Datadog site. Defaults to 'datadoghq.com'. Use 'datadoghq.eu' for EU,
8
+ * 'us3.datadoghq.com' / 'us5.datadoghq.com' / 'ap1.datadoghq.com' for
9
+ * other regions, or 'ddog-gov.com' for government.
10
+ */
11
+ site?: string;
12
+ /** Log service field — defaults to 'mandatez'. */
13
+ service?: string;
14
+ /** Log source field — defaults to 'mandatez-sdk'. */
15
+ source?: string;
16
+ /** Additional Datadog tags merged into every event. */
17
+ tags?: string[];
18
+ }
19
+ /**
20
+ * Ships MandateZ AgentEvents to Datadog Logs via the v2 HTTP intake.
21
+ *
22
+ * @see https://docs.datadoghq.com/api/latest/logs/#send-logs
23
+ */
24
+ export declare class DatadogExporter implements EventExporter {
25
+ readonly name = "datadog";
26
+ private readonly endpoint;
27
+ private readonly apiKey;
28
+ private readonly service;
29
+ private readonly source;
30
+ private readonly tags;
31
+ constructor(config: DatadogExporterConfig);
32
+ export(event: AgentEvent): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=datadog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datadog.d.ts","sourceRoot":"","sources":["../../src/exporters/datadog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,qBAAqB;IACpC,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,aAAa;IACnD,QAAQ,CAAC,IAAI,aAAa;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;gBAEpB,MAAM,EAAE,qBAAqB;IAYnC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CA+C/C"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Ships MandateZ AgentEvents to Datadog Logs via the v2 HTTP intake.
3
+ *
4
+ * @see https://docs.datadoghq.com/api/latest/logs/#send-logs
5
+ */
6
+ export class DatadogExporter {
7
+ name = 'datadog';
8
+ endpoint;
9
+ apiKey;
10
+ service;
11
+ source;
12
+ tags;
13
+ constructor(config) {
14
+ if (!config.apiKey) {
15
+ throw new Error('DatadogExporter: apiKey is required');
16
+ }
17
+ const site = (config.site ?? 'datadoghq.com').replace(/^https?:\/\//, '').replace(/\/+$/, '');
18
+ this.endpoint = `https://http-intake.logs.${site}/api/v2/logs`;
19
+ this.apiKey = config.apiKey;
20
+ this.service = config.service ?? 'mandatez';
21
+ this.source = config.source ?? 'mandatez-sdk';
22
+ this.tags = config.tags ?? [];
23
+ }
24
+ async export(event) {
25
+ const tags = [
26
+ `agent_id:${event.agent_id}`,
27
+ `owner_id:${event.owner_id}`,
28
+ `outcome:${event.outcome}`,
29
+ `action_type:${event.action_type}`,
30
+ ...this.tags,
31
+ ].join(',');
32
+ const payload = [
33
+ {
34
+ ddsource: this.source,
35
+ ddtags: tags,
36
+ hostname: 'mandatez-sdk',
37
+ service: this.service,
38
+ status: event.outcome === 'blocked' ? 'error' : event.outcome === 'flagged' ? 'warn' : 'info',
39
+ message: `[MandateZ] ${event.action_type} ${event.resource} → ${event.outcome}`,
40
+ timestamp: event.timestamp,
41
+ mandatez: {
42
+ event_id: event.event_id,
43
+ agent_id: event.agent_id,
44
+ owner_id: event.owner_id,
45
+ action_type: event.action_type,
46
+ resource: event.resource,
47
+ outcome: event.outcome,
48
+ policy_id: event.policy_id,
49
+ signature: event.signature,
50
+ public_key: event.public_key,
51
+ metadata: event.metadata,
52
+ },
53
+ },
54
+ ];
55
+ const res = await fetch(this.endpoint, {
56
+ method: 'POST',
57
+ headers: {
58
+ 'Content-Type': 'application/json',
59
+ 'DD-API-KEY': this.apiKey,
60
+ },
61
+ body: JSON.stringify(payload),
62
+ });
63
+ if (!res.ok) {
64
+ const body = await res.text().catch(() => '');
65
+ throw new Error(`DatadogExporter: HTTP ${res.status} ${body.slice(0, 200)}`);
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=datadog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datadog.js","sourceRoot":"","sources":["../../src/exporters/datadog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { AgentEvent } from '../events/schema.js';
2
+ /**
3
+ * Pluggable destination for signed AgentEvents beyond the MandateZ
4
+ * event stream itself. Implementations fan events out to SIEMs,
5
+ * observability platforms, or custom webhooks.
6
+ *
7
+ * Implementations must treat export() as fire-and-forget — the
8
+ * MandateZClient never awaits the result on the hot path, and any
9
+ * thrown error is swallowed and logged. Do not rely on exporters for
10
+ * ordering or delivery guarantees; they are best-effort fan-out.
11
+ */
12
+ export interface EventExporter {
13
+ /** Human-readable name used for error logging. */
14
+ name: string;
15
+ /** Ship a single signed event to the underlying destination. */
16
+ export(event: AgentEvent): Promise<void>;
17
+ }
18
+ export { DatadogExporter } from './datadog.js';
19
+ export type { DatadogExporterConfig } from './datadog.js';
20
+ export { SplunkExporter } from './splunk.js';
21
+ export type { SplunkExporterConfig } from './splunk.js';
22
+ export { WebhookExporter } from './webhook.js';
23
+ export type { WebhookExporterConfig } from './webhook.js';
24
+ export { OpenTelemetryExporter } from './otel.js';
25
+ export type { OpenTelemetryExporterConfig } from './otel.js';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exporters/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { DatadogExporter } from './datadog.js';
2
+ export { SplunkExporter } from './splunk.js';
3
+ export { WebhookExporter } from './webhook.js';
4
+ export { OpenTelemetryExporter } from './otel.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exporters/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { AgentEvent } from '../events/schema.js';
2
+ import type { EventExporter } from './index.js';
3
+ export interface OpenTelemetryExporterConfig {
4
+ /**
5
+ * OTLP/HTTP endpoint. The /v1/traces path is appended automatically
6
+ * if missing. Example: http://otel-collector:4318
7
+ */
8
+ endpoint: string;
9
+ /** OTel service.name resource attribute. Defaults to 'mandatez'. */
10
+ serviceName?: string;
11
+ /** Extra resource attributes merged into every export. */
12
+ resourceAttributes?: Record<string, string>;
13
+ /** Optional headers (Authorization, x-honeycomb-team, etc.). */
14
+ headers?: Record<string, string>;
15
+ }
16
+ /**
17
+ * Formats MandateZ AgentEvents as OTLP/HTTP spans and ships them to any
18
+ * OpenTelemetry Collector. This keeps the SDK dependency-free — we emit
19
+ * the wire-level JSON shape directly rather than pulling in the heavy
20
+ * @opentelemetry/sdk-node tree.
21
+ *
22
+ * Each event becomes a single zero-duration span whose name is
23
+ * `mandatez.<action_type>` with the full event serialized as span
24
+ * attributes. Status is mapped: blocked → ERROR, flagged → ERROR,
25
+ * everything else → OK.
26
+ *
27
+ * @see https://opentelemetry.io/docs/specs/otlp/#otlphttp
28
+ */
29
+ export declare class OpenTelemetryExporter implements EventExporter {
30
+ readonly name = "opentelemetry";
31
+ private readonly endpoint;
32
+ private readonly serviceName;
33
+ private readonly resourceAttributes;
34
+ private readonly headers;
35
+ constructor(config: OpenTelemetryExporterConfig);
36
+ export(event: AgentEvent): Promise<void>;
37
+ }
38
+ //# sourceMappingURL=otel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../src/exporters/otel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AA0BD;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,IAAI,mBAAmB;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAyB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;gBAErC,MAAM,EAAE,2BAA2B;IAWzC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CA2E/C"}
@@ -0,0 +1,115 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ function anyValue(v) {
3
+ if (typeof v === 'string')
4
+ return { stringValue: v };
5
+ if (typeof v === 'boolean')
6
+ return { boolValue: v };
7
+ if (typeof v === 'number') {
8
+ return Number.isInteger(v) ? { intValue: v } : { doubleValue: v };
9
+ }
10
+ return { stringValue: JSON.stringify(v) };
11
+ }
12
+ function toAttrs(obj) {
13
+ return Object.entries(obj).map(([key, value]) => ({ key, value: anyValue(value) }));
14
+ }
15
+ /**
16
+ * Formats MandateZ AgentEvents as OTLP/HTTP spans and ships them to any
17
+ * OpenTelemetry Collector. This keeps the SDK dependency-free — we emit
18
+ * the wire-level JSON shape directly rather than pulling in the heavy
19
+ * @opentelemetry/sdk-node tree.
20
+ *
21
+ * Each event becomes a single zero-duration span whose name is
22
+ * `mandatez.<action_type>` with the full event serialized as span
23
+ * attributes. Status is mapped: blocked → ERROR, flagged → ERROR,
24
+ * everything else → OK.
25
+ *
26
+ * @see https://opentelemetry.io/docs/specs/otlp/#otlphttp
27
+ */
28
+ export class OpenTelemetryExporter {
29
+ name = 'opentelemetry';
30
+ endpoint;
31
+ serviceName;
32
+ resourceAttributes;
33
+ headers;
34
+ constructor(config) {
35
+ if (!config.endpoint) {
36
+ throw new Error('OpenTelemetryExporter: endpoint is required');
37
+ }
38
+ const base = config.endpoint.replace(/\/+$/, '');
39
+ this.endpoint = /\/v1\/traces$/.test(base) ? base : `${base}/v1/traces`;
40
+ this.serviceName = config.serviceName ?? 'mandatez';
41
+ this.resourceAttributes = config.resourceAttributes ?? {};
42
+ this.headers = config.headers ?? {};
43
+ }
44
+ async export(event) {
45
+ const timestampNanos = BigInt(new Date(event.timestamp).getTime()) * 1000000n;
46
+ const ns = timestampNanos.toString();
47
+ // OTLP trace/span IDs: 16 and 8 random bytes, lowercase hex.
48
+ const traceId = randomBytes(16).toString('hex');
49
+ const spanId = randomBytes(8).toString('hex');
50
+ const blocked = event.outcome === 'blocked';
51
+ const flagged = event.outcome === 'flagged';
52
+ const statusCode = blocked || flagged ? 2 : 1; // 2 = ERROR, 1 = OK
53
+ const payload = {
54
+ resourceSpans: [
55
+ {
56
+ resource: {
57
+ attributes: toAttrs({
58
+ 'service.name': this.serviceName,
59
+ 'service.namespace': 'mandatez',
60
+ ...this.resourceAttributes,
61
+ }),
62
+ },
63
+ scopeSpans: [
64
+ {
65
+ scope: { name: '@mandatez/sdk', version: '0.1.6' },
66
+ spans: [
67
+ {
68
+ traceId,
69
+ spanId,
70
+ name: `mandatez.${event.action_type}`,
71
+ kind: 1, // SPAN_KIND_INTERNAL
72
+ startTimeUnixNano: ns,
73
+ endTimeUnixNano: ns,
74
+ attributes: toAttrs({
75
+ 'mandatez.event_id': event.event_id,
76
+ 'mandatez.agent_id': event.agent_id,
77
+ 'mandatez.owner_id': event.owner_id,
78
+ 'mandatez.action_type': event.action_type,
79
+ 'mandatez.resource': event.resource,
80
+ 'mandatez.outcome': event.outcome,
81
+ 'mandatez.policy_id': event.policy_id ?? '',
82
+ 'mandatez.public_key': event.public_key,
83
+ 'mandatez.signature': event.signature,
84
+ 'mandatez.metadata': JSON.stringify(event.metadata),
85
+ }),
86
+ status: {
87
+ code: statusCode,
88
+ message: blocked
89
+ ? 'Action blocked by MandateZ policy'
90
+ : flagged
91
+ ? 'Action flagged for review'
92
+ : '',
93
+ },
94
+ },
95
+ ],
96
+ },
97
+ ],
98
+ },
99
+ ],
100
+ };
101
+ const res = await fetch(this.endpoint, {
102
+ method: 'POST',
103
+ headers: {
104
+ 'Content-Type': 'application/json',
105
+ ...this.headers,
106
+ },
107
+ body: JSON.stringify(payload),
108
+ });
109
+ if (!res.ok) {
110
+ const body = await res.text().catch(() => '');
111
+ throw new Error(`OpenTelemetryExporter: HTTP ${res.status} ${body.slice(0, 200)}`);
112
+ }
113
+ }
114
+ }
115
+ //# sourceMappingURL=otel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/exporters/otel.ts"],"names":[],"mappings":"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"}