@auctra/sdk 0.6.0 → 0.6.2

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/src/index.ts CHANGED
@@ -1,1125 +1,10 @@
1
- import { createHash, createPublicKey, verify as cryptoVerify, type KeyObject } from "node:crypto";
2
-
3
- export const AUCTRA_SDK_VERSION = "0.6.0";
4
-
5
- export type AgentEnvironment = "dev" | "staging" | "production";
6
- export type AuthorityLevel = "low" | "medium" | "high" | "critical";
7
- export type Decision = "allowed" | "blocked" | "require_approval";
8
- export type PolicyType = "spending" | "data_access" | "communication" | "approval";
9
- export type ActorType = "human" | "agent" | "service" | "tool";
10
- export type RiskLevel = "low" | "medium" | "high" | "critical";
11
- export type IntentStatus = "active" | "expired" | "completed" | "revoked" | "suspended";
12
-
13
- export type EvaluateActionInput = {
14
- agentId: string;
15
- actionType: string;
16
- payload?: Record<string, unknown>;
17
- claimedIntentId?: string;
18
- intentAnchorToken?: string;
19
- parentActionId?: string;
20
- actor?: {
21
- id?: string;
22
- type?: ActorType;
23
- name?: string;
24
- };
25
- action?: {
26
- target?: string;
27
- description?: string;
28
- riskLevel?: RiskLevel;
29
- metadata?: Record<string, unknown>;
30
- };
31
- };
32
-
33
- export type EvaluateActionResponse = {
34
- decision: Decision;
35
- risk_score: number;
36
- reason: string;
37
- delegation_id: string | null;
38
- authority_id: string | null;
39
- delegator: string | null;
40
- sponsor: string;
41
- matched_policies: string[];
42
- action_request_id: string;
43
- evidence: DecisionEvidence;
44
- evidence_payload: DecisionEvidencePayload;
45
- protocol?: {
46
- version: string;
47
- action?: Record<string, unknown>;
48
- decision?: Record<string, unknown>;
49
- };
50
- intelligence?: {
51
- authority_valid: boolean;
52
- root_intent_valid: boolean;
53
- intent_status: string;
54
- trust_summary?: string;
55
- };
56
- };
57
-
58
- export type RequestOptions = {
59
- idempotencyKey?: string;
60
- signal?: AbortSignal;
61
- };
62
-
63
- export type AuctraClientOptions = {
64
- apiKey: string;
65
- baseUrl?: string;
66
- timeoutMs?: number;
67
- maxRetries?: number;
68
- fetch?: typeof fetch;
69
- };
70
-
71
- export type Agent = {
72
- id: string;
73
- identity_id: string;
74
- name: string;
75
- description: string | null;
76
- model_provider: "openai" | "anthropic" | "gemini" | "local";
77
- model_name: string;
78
- environment: AgentEnvironment;
79
- authority_level: AuthorityLevel;
80
- status: "active" | "suspended" | "restricted" | "compromised";
81
- trust_rating: number;
82
- sponsor: { id: string; full_name: string; email: string };
83
- created_at: string;
84
- };
85
-
86
- export type CreateAgentInput = {
87
- name: string;
88
- modelProvider: Agent["model_provider"];
89
- modelName: string;
90
- description?: string;
91
- environment?: AgentEnvironment;
92
- authorityLevel?: AuthorityLevel;
93
- sponsorUserId?: string;
94
- };
95
-
96
- export type Delegation = {
97
- id: string;
98
- agent: { id: string; name: string };
99
- delegator: { id: string; full_name: string; email: string };
100
- scope: { action_types: string[] };
101
- limits: {
102
- max_amount?: number;
103
- max_count?: number;
104
- currency?: string;
105
- environment?: AgentEnvironment;
106
- max_actions_per_window?: {
107
- count: number;
108
- window_seconds: number;
109
- action_type?: string;
110
- };
111
- max_amount_per_window?: {
112
- amount: number;
113
- window_seconds: number;
114
- };
115
- };
116
- valid_from: string;
117
- valid_until: string;
118
- status: "active" | "revoked" | "expired";
119
- is_active: boolean;
120
- mandate?: MandateEvidence | null;
121
- mandate_payload?: MandatePayload | null;
122
- evidence?: DecisionEvidence | null;
123
- evidence_payload?: DecisionEvidencePayload | null;
124
- created_at: string;
125
- };
126
-
127
- export type CreateDelegationInput = {
128
- agentId: string;
129
- actionTypes: string[];
130
- validUntil: string;
131
- maxAmount?: number;
132
- maxCount?: number;
133
- environment?: AgentEnvironment;
134
- currency?: string;
135
- delegatorUserId?: string;
136
- /** Parent authority/delegation id for subset-constrained delegation chains. */
137
- parentAuthorityId?: string;
138
- parentDelegationId?: string;
139
- maxDelegationDepth?: number;
140
- maxActionsPerWindow?: {
141
- count: number;
142
- windowSeconds: number;
143
- actionType?: string;
144
- };
145
- maxAmountPerWindow?: {
146
- amount: number;
147
- windowSeconds: number;
148
- };
149
- };
150
-
151
- export type AuthoritySummary = {
152
- id: string;
153
- protocol_version: string;
154
- status: string;
155
- payload_hash: string;
156
- signed: boolean;
157
- parent_authority_id: string | null;
158
- capabilities: unknown;
159
- };
160
-
161
- export type IssueAuthorityInput = {
162
- /** Subject agent id */
163
- subject: string;
164
- capabilities: string[];
165
- expiresAt: string;
166
- constraints?: {
167
- maxAmount?: number;
168
- currency?: string;
169
- maxCount?: number;
170
- environment?: AgentEnvironment;
171
- };
172
- delegation?: {
173
- allowed?: boolean;
174
- maxDepth?: number;
175
- };
176
- issuer?: string;
177
- delegatorUserId?: string;
178
- maxActionsPerWindow?: {
179
- count: number;
180
- windowSeconds: number;
181
- actionType?: string;
182
- };
183
- maxAmountPerWindow?: {
184
- amount: number;
185
- windowSeconds: number;
186
- };
187
- };
188
-
189
- export type DelegateAuthorityInput = IssueAuthorityInput & {
190
- /** Parent authority id — child must be a subset of parent */
191
- parent: string;
192
- };
193
-
194
- export type ActionRequest = {
195
- id: string;
196
- agent_name: string;
197
- action_type: string;
198
- action_summary: string;
199
- payload: Record<string, unknown>;
200
- decision: string;
201
- decision_reason: string | null;
202
- risk_score: number;
203
- delegation_id: string | null;
204
- policy_ids: string[];
205
- claimed_intent_id: string | null;
206
- parent_action_id: string | null;
207
- actor_id: string | null;
208
- actor_type: ActorType;
209
- action_target: string | null;
210
- action_description: string | null;
211
- action_risk_level: RiskLevel | null;
212
- action_metadata: Record<string, unknown>;
213
- pending_approval_id: string | null;
214
- created_at: string;
215
- decided_at: string | null;
216
- };
217
-
218
- export type Intent = {
219
- id: string;
220
- title: string;
221
- description: string | null;
222
- intent_type: string | null;
223
- status: IntentStatus;
224
- risk_level: RiskLevel;
225
- max_risk_level: RiskLevel;
226
- expires_at: string | null;
227
- created_at: string;
228
- owner: { id: string; full_name: string; email: string } | null;
229
- linked_actions: number;
230
- };
231
-
232
- export type IntentDetail = Omit<Intent, "linked_actions"> & {
233
- linked_actions: Array<{
234
- action_request_id: string;
235
- action_type: string;
236
- summary: string;
237
- decision: string;
238
- alignment_status: string;
239
- alignment_score: number | null;
240
- }>;
241
- };
242
-
243
- export type CreateAuthorityEdgeInput = {
244
- fromActorId: string;
245
- fromActorType: ActorType;
246
- toActorId: string;
247
- toActorType: ActorType;
248
- authorityScope: string;
249
- conditions?: Record<string, unknown>;
250
- maxRiskLevel?: RiskLevel;
251
- expiresAt?: string;
252
- };
253
-
254
- export type CreateIntentInput = {
255
- title: string;
256
- description?: string;
257
- intentType?: string;
258
- riskLevel?: RiskLevel;
259
- maxRiskLevel?: RiskLevel;
260
- expiresAt?: string;
261
- allowedActionTypes?: string[];
262
- targetPattern?: string;
263
- resourceAllowlist?: string[];
264
- };
265
-
266
- export type UpdateIntentInput = {
267
- status?: Exclude<IntentStatus, "expired">;
268
- title?: string;
269
- description?: string | null;
270
- intentType?: string | null;
271
- riskLevel?: RiskLevel;
272
- maxRiskLevel?: RiskLevel;
273
- expiresAt?: string | null;
274
- };
275
-
276
- export type UpdateAgentStatusInput = {
277
- status: Agent["status"];
278
- reason?: string;
279
- /** Permanently revoke instead of quarantine (default: quarantine on restrict/suspend). */
280
- revokeDelegations?: boolean;
281
- /** Restore quarantined delegations when reactivating (default: true). */
282
- restoreDelegations?: boolean;
283
- };
284
-
285
- export type AuthorityGraph = {
286
- nodes: Array<{ id: string; type: ActorType; label: string }>;
287
- edges: Array<{
288
- id: string;
289
- from: string;
290
- to: string;
291
- fromType: ActorType;
292
- toType: ActorType;
293
- scope: string;
294
- status: string;
295
- edgeType: string;
296
- }>;
297
- };
298
-
299
- export type ActionEvaluation = {
300
- id: string;
301
- action_request_id: string;
302
- intent_id: string | null;
303
- decision: "allowed" | "requires_approval" | "blocked";
304
- risk_score: number;
305
- authority_valid: boolean;
306
- intent_valid: boolean;
307
- root_intent_valid: boolean;
308
- reasons: string[];
309
- created_at: string;
310
- };
311
-
312
- export type RootIntentChain = {
313
- valid: boolean;
314
- root_human_id: string | null;
315
- root_intent_id: string | null;
316
- reason: string | null;
317
- chain: Array<{
318
- actionId?: string;
319
- actorId: string;
320
- actorType: ActorType;
321
- intentId?: string;
322
- parentActionId?: string;
323
- label?: string;
324
- }>;
325
- };
326
-
327
- export type Policy = {
328
- id: string;
329
- name: string;
330
- description: string | null;
331
- policy_type: PolicyType;
332
- status: "active" | "draft" | "archived";
333
- priority: number;
334
- conditions: Record<string, unknown>;
335
- actions: Record<string, unknown>;
336
- created_at: string;
337
- };
338
-
339
- export type CreatePolicyInput = {
340
- name: string;
341
- description?: string;
342
- policyType: PolicyType;
343
- status?: "active" | "draft";
344
- priority?: number;
345
- actionType?: string;
346
- amountGreaterThan?: number;
347
- resourceSensitivity?: "public" | "internal" | "confidential" | "pii";
348
- externalRecipient?: boolean;
349
- environment?: AgentEnvironment;
350
- decision: "block" | "require_approval";
351
- approverRole?: "owner" | "admin" | "reviewer";
352
- maxActionsPerWindow?: {
353
- count: number;
354
- windowSeconds: number;
355
- actionType?: string;
356
- };
357
- maxAmountPerWindow?: {
358
- amount: number;
359
- windowSeconds: number;
360
- };
361
- };
362
-
363
- export type CustomActionType = {
364
- id: string;
365
- label: string;
366
- description: string | null;
367
- category: string;
368
- policy_type: PolicyType;
369
- payload_schema: Record<string, unknown>;
370
- source: "builtin" | "custom";
371
- template?: boolean;
372
- created_at?: string | null;
373
- };
374
-
375
- export type CreateCustomActionTypeInput = {
376
- id: string;
377
- label: string;
378
- description?: string;
379
- category?: string;
380
- policyType: PolicyType;
381
- payloadSchema?: Record<string, unknown>;
382
- };
383
-
384
- export type PolicySimulation = {
385
- policy_id: string;
386
- policy_name: string;
387
- policy_status: string;
388
- sample_size: number;
389
- changed_count: number;
390
- unchanged_count: number;
391
- would_block_count: number;
392
- replay_source?: "audit_events" | "action_requests" | "mixed";
393
- deltas: Array<{
394
- action_request_id: string;
395
- action_type: string;
396
- current_decision: string;
397
- simulated_decision: string;
398
- changed: boolean;
399
- }>;
400
- };
401
-
402
- export type MandateEvidence =
403
- | {
404
- format: "auctra-mandate.v0.1";
405
- payload_hash: string;
406
- signed: false;
407
- }
408
- | {
409
- format: "auctra-mandate.v0.1";
410
- signed: true;
411
- payload_hash: string;
412
- payload: Record<string, unknown>;
413
- signature: { alg: "Ed25519"; key_id: string; value: string };
414
- };
415
-
416
- export type MandatePayload = Record<string, unknown>;
417
-
418
- export type DecisionEvidencePayload = Record<string, unknown>;
419
-
420
- export type DecisionEvidence =
421
- | {
422
- format: "auctra-evidence.v0.1";
423
- payload_hash: string;
424
- signed: false;
425
- }
426
- | {
427
- format: "auctra-evidence.v0.1";
428
- signed: true;
429
- payload_hash: string;
430
- payload: Record<string, unknown>;
431
- signature: { alg: "Ed25519"; key_id: string; value: string };
432
- };
433
-
434
- export type AuditChainVerification = {
435
- valid: boolean;
436
- total: number;
437
- sealed_total: number;
438
- legacy_unsealed_total: number;
439
- events: Array<{
440
- id: string;
441
- hashValid: boolean;
442
- linkValid: boolean;
443
- sequenceValid: boolean;
444
- valid: boolean;
445
- legacy: boolean;
446
- }>;
447
- };
448
-
449
- export type ArtifactVerification = {
450
- valid: boolean;
451
- hashValid: boolean;
452
- signatureValid: boolean;
453
- };
454
-
455
- export type AuditEvent = {
456
- id: string;
457
- event_type: string;
458
- event_summary: string;
459
- decision: string | null;
460
- decision_reason: string | null;
461
- authority_valid_at_action: boolean | null;
462
- actor_name: string;
463
- approver_name: string | null;
464
- policy_applied: string | null;
465
- delegation_id: string | null;
466
- hash: string | null;
467
- previous_hash: string | null;
468
- chain_index?: number;
469
- mandate?: MandateEvidence | null;
470
- evidence?: DecisionEvidence | null;
471
- payload?: Record<string, unknown>;
472
- created_at: string;
473
- };
474
-
475
- export type ApiKeySummary = {
476
- id: string;
477
- name: string;
478
- key_prefix: string;
479
- environment: "development" | "production";
480
- permissions: string[];
481
- status: "active" | "revoked";
482
- last_used_at: string | null;
483
- created_at: string;
484
- };
485
-
486
- export class AuctraApiError extends Error {
487
- readonly status: number;
488
- readonly code?: string;
489
- readonly details?: unknown;
490
- readonly requestId?: string;
491
-
492
- constructor(
493
- message: string,
494
- options: { status: number; code?: string; details?: unknown; requestId?: string },
495
- ) {
496
- super(message);
497
- this.name = "AuctraApiError";
498
- this.status = options.status;
499
- this.code = options.code;
500
- this.details = options.details;
501
- this.requestId = options.requestId;
502
- }
503
- }
504
-
505
- function retryDelay(response: Response | undefined, attempt: number) {
506
- const retryAfter = response?.headers.get("retry-after");
507
- if (retryAfter) {
508
- const seconds = Number(retryAfter);
509
- if (Number.isFinite(seconds)) return Math.min(30_000, Math.max(0, seconds * 1_000));
510
- const dateDelay = Date.parse(retryAfter) - Date.now();
511
- if (Number.isFinite(dateDelay)) return Math.min(30_000, Math.max(0, dateDelay));
512
- }
513
- return Math.min(5_000, 150 * 2 ** attempt);
514
- }
515
-
516
- function wait(ms: number, signal?: AbortSignal) {
517
- if (signal?.aborted) return Promise.reject(signal.reason);
518
- return new Promise<void>((resolve, reject) => {
519
- const timeout = setTimeout(resolve, ms);
520
- signal?.addEventListener(
521
- "abort",
522
- () => {
523
- clearTimeout(timeout);
524
- reject(signal.reason);
525
- },
526
- { once: true },
527
- );
528
- });
529
- }
530
-
531
- function canonicalizeJson(value: unknown): unknown {
532
- if (Array.isArray(value)) return value.map(canonicalizeJson);
533
- if (value && typeof value === "object" && !(value instanceof Date)) {
534
- return Object.fromEntries(
535
- Object.entries(value as Record<string, unknown>)
536
- .filter(([, child]) => child !== undefined)
537
- .sort(([left], [right]) => left.localeCompare(right))
538
- .map(([key, child]) => [key, canonicalizeJson(child)]),
539
- );
540
- }
541
- if (value instanceof Date) return value.toISOString();
542
- return value;
543
- }
544
-
545
- function hashJson(value: unknown) {
546
- return createHash("sha256")
547
- .update(JSON.stringify(canonicalizeJson(value)))
548
- .digest("hex");
549
- }
550
-
551
- function verifyEd25519(input: {
552
- payload: unknown;
553
- signature: { alg: "Ed25519"; value: string };
554
- publicKeyPem?: string | KeyObject;
555
- }) {
556
- if (!input.publicKeyPem) return false;
557
- if (input.signature.alg !== "Ed25519") return false;
558
- return cryptoVerify(
559
- null,
560
- Buffer.from(JSON.stringify(canonicalizeJson(input.payload))),
561
- typeof input.publicKeyPem === "string"
562
- ? createPublicKey(input.publicKeyPem)
563
- : input.publicKeyPem,
564
- Buffer.from(input.signature.value, "base64url"),
565
- );
566
- }
567
-
568
- export function verifyMandateArtifact(input: {
569
- payload: MandatePayload;
570
- evidence: MandateEvidence;
571
- publicKeyPem?: string | KeyObject;
572
- }): ArtifactVerification {
573
- const expectedHash = hashJson(input.payload);
574
- if (input.evidence.format !== "auctra-mandate.v0.1") {
575
- return { valid: false, hashValid: false, signatureValid: false };
576
- }
577
- if (!input.evidence.signed) {
578
- const hashValid = input.evidence.payload_hash === expectedHash;
579
- return { valid: hashValid, hashValid, signatureValid: false };
580
- }
581
- const hashValid = input.evidence.payload_hash === expectedHash;
582
- const signatureValid =
583
- hashValid &&
584
- verifyEd25519({
585
- payload: input.payload,
586
- signature: input.evidence.signature,
587
- publicKeyPem: input.publicKeyPem,
588
- });
589
- return { valid: hashValid && signatureValid, hashValid, signatureValid };
590
- }
591
-
592
- export function verifyDecisionArtifact(input: {
593
- payload: DecisionEvidencePayload;
594
- evidence: DecisionEvidence;
595
- publicKeyPem?: string | KeyObject;
596
- }): ArtifactVerification {
597
- const expectedHash = hashJson(input.payload);
598
- if (input.evidence.format !== "auctra-evidence.v0.1") {
599
- return { valid: false, hashValid: false, signatureValid: false };
600
- }
601
- if (!input.evidence.signed) {
602
- const hashValid = input.evidence.payload_hash === expectedHash;
603
- return { valid: hashValid, hashValid, signatureValid: false };
604
- }
605
- const hashValid = input.evidence.payload_hash === expectedHash;
606
- const signatureValid =
607
- hashValid &&
608
- verifyEd25519({
609
- payload: input.payload,
610
- signature: input.evidence.signature,
611
- publicKeyPem: input.publicKeyPem,
612
- });
613
- return { valid: hashValid && signatureValid, hashValid, signatureValid };
614
- }
615
-
616
- export class Auctra {
617
- private readonly apiKey: string;
618
- private readonly baseUrl: string;
619
- private readonly timeoutMs: number;
620
- private readonly maxRetries: number;
621
- private readonly fetchImpl: typeof fetch;
622
-
623
- constructor(options: AuctraClientOptions) {
624
- if (!options.apiKey.trim()) throw new Error("apiKey is required");
625
- if (options.timeoutMs !== undefined && options.timeoutMs <= 0) {
626
- throw new Error("timeoutMs must be greater than zero");
627
- }
628
- if (
629
- options.maxRetries !== undefined &&
630
- (!Number.isInteger(options.maxRetries) || options.maxRetries < 0)
631
- ) {
632
- throw new Error("maxRetries must be a non-negative integer");
633
- }
634
- this.apiKey = options.apiKey;
635
- this.baseUrl = (options.baseUrl ?? "https://console.auctra.tech").replace(/\/$/, "");
636
- this.timeoutMs = options.timeoutMs ?? 10_000;
637
- this.maxRetries = options.maxRetries ?? 2;
638
- this.fetchImpl = options.fetch ?? globalThis.fetch;
639
- if (!this.fetchImpl) throw new Error("A fetch implementation is required");
640
- }
641
-
642
- private async request<T>(
643
- method: string,
644
- path: string,
645
- body?: unknown,
646
- options: RequestOptions = {},
647
- ): Promise<T> {
648
- const retryableRequest = method === "GET" || Boolean(options.idempotencyKey);
649
- let lastError: unknown;
650
-
651
- for (let attempt = 0; attempt <= this.maxRetries; attempt += 1) {
652
- if (options.signal?.aborted) throw options.signal.reason;
653
- const timeoutSignal = AbortSignal.timeout(this.timeoutMs);
654
- const signal = options.signal
655
- ? AbortSignal.any([options.signal, timeoutSignal])
656
- : timeoutSignal;
657
- let response: Response | undefined;
658
-
659
- try {
660
- response = await this.fetchImpl(`${this.baseUrl}${path}`, {
661
- method,
662
- signal,
663
- headers: {
664
- ...(body !== undefined ? { "content-type": "application/json" } : {}),
665
- ...(options.idempotencyKey ? { "idempotency-key": options.idempotencyKey } : {}),
666
- authorization: `Bearer ${this.apiKey}`,
667
- "x-auctra-sdk-version": AUCTRA_SDK_VERSION,
668
- },
669
- ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
670
- });
671
-
672
- const data = (await response.json().catch(() => ({}))) as Record<string, unknown>;
673
- if (response.ok) return data as T;
674
-
675
- if (
676
- retryableRequest &&
677
- (response.status === 429 || response.status >= 500) &&
678
- attempt < this.maxRetries
679
- ) {
680
- await wait(retryDelay(response, attempt), options.signal);
681
- continue;
682
- }
683
-
684
- throw new AuctraApiError(
685
- typeof data.error === "string" ? data.error : `Auctra API error (${response.status})`,
686
- {
687
- status: response.status,
688
- code: typeof data.code === "string" ? data.code : undefined,
689
- details: data.details,
690
- requestId: response.headers.get("x-request-id") ?? undefined,
691
- },
692
- );
693
- } catch (error) {
694
- lastError = error;
695
- if (options.signal?.aborted) throw options.signal.reason;
696
- if (error instanceof AuctraApiError || !retryableRequest || attempt >= this.maxRetries) {
697
- throw error;
698
- }
699
- await wait(retryDelay(response, attempt), options.signal);
700
- }
701
- }
702
-
703
- throw lastError;
704
- }
705
-
706
- private async executeOrEvaluateAction(
707
- input: EvaluateActionInput,
708
- options: RequestOptions,
709
- mode: "execute" | "evaluate",
710
- ): Promise<EvaluateActionResponse> {
711
- const idempotencyKey =
712
- mode === "execute" ? (options.idempotencyKey ?? crypto.randomUUID()) : options.idempotencyKey;
713
- const path = mode === "execute" ? "/v1/actions/execute" : "/v1/actions/evaluate";
714
- return this.request(
715
- "POST",
716
- path,
717
- {
718
- agent_id: input.agentId,
719
- action_type: input.actionType,
720
- payload: input.payload ?? {},
721
- claimed_intent_id: input.claimedIntentId,
722
- intent_anchor_token: input.intentAnchorToken,
723
- parent_action_id: input.parentActionId,
724
- dry_run: mode === "evaluate",
725
- actor: input.actor
726
- ? {
727
- id: input.actor.id,
728
- type: input.actor.type,
729
- name: input.actor.name,
730
- }
731
- : undefined,
732
- action: input.action
733
- ? {
734
- target: input.action.target,
735
- description: input.action.description,
736
- risk_level: input.action.riskLevel,
737
- metadata: input.action.metadata,
738
- }
739
- : undefined,
740
- },
741
- mode === "execute" ? { ...options, idempotencyKey } : options,
742
- );
743
- }
744
-
745
- private async issueAuthorityRequest(
746
- input: IssueAuthorityInput & { parentAuthorityId?: string },
747
- ): Promise<{
748
- authority: AuthoritySummary;
749
- authority_id: string;
750
- delegation: Delegation;
751
- }> {
752
- const response = await this.request<{
753
- delegation: Delegation;
754
- authority_id?: string;
755
- authority?: AuthoritySummary;
756
- }>("POST", "/v1/authorities", {
757
- agent_id: input.subject,
758
- action_types: input.capabilities,
759
- valid_until: input.expiresAt,
760
- max_amount: input.constraints?.maxAmount,
761
- max_count: input.constraints?.maxCount,
762
- environment: input.constraints?.environment,
763
- currency: input.constraints?.currency,
764
- delegator_user_id: input.delegatorUserId ?? input.issuer,
765
- parent_authority_id: input.parentAuthorityId,
766
- max_delegation_depth: input.delegation?.maxDepth,
767
- max_actions_per_window: input.maxActionsPerWindow
768
- ? {
769
- count: input.maxActionsPerWindow.count,
770
- window_seconds: input.maxActionsPerWindow.windowSeconds,
771
- action_type: input.maxActionsPerWindow.actionType,
772
- }
773
- : undefined,
774
- max_amount_per_window: input.maxAmountPerWindow
775
- ? {
776
- amount: input.maxAmountPerWindow.amount,
777
- window_seconds: input.maxAmountPerWindow.windowSeconds,
778
- }
779
- : undefined,
780
- });
781
-
782
- const authorityId = response.authority_id ?? response.delegation.id;
783
- const authority: AuthoritySummary = response.authority ?? {
784
- id: authorityId,
785
- protocol_version: "0.1",
786
- status: response.delegation.status,
787
- payload_hash: "",
788
- signed: false,
789
- parent_authority_id: input.parentAuthorityId ?? null,
790
- capabilities: input.capabilities,
791
- };
792
-
793
- return {
794
- authority,
795
- authority_id: authorityId,
796
- delegation: response.delegation,
797
- };
798
- }
799
-
800
- /**
801
- * Authority Protocol — issue, verify, delegate (subset), revoke.
802
- * There is no legacy createDelegation() surface.
803
- */
804
- get authority() {
805
- return {
806
- issue: (input: IssueAuthorityInput) => this.issueAuthorityRequest(input),
807
- verify: (
808
- payload: Record<string, unknown>,
809
- artifact: Record<string, unknown>,
810
- ): Promise<{
811
- valid: boolean;
812
- hashValid: boolean;
813
- signatureValid: boolean;
814
- expired: boolean;
815
- status: string;
816
- issuer: string;
817
- subject: string;
818
- capabilities: string[];
819
- constraints: Record<string, unknown>;
820
- expiresAt: string;
821
- protocolVersion: string;
822
- }> => this.request("POST", "/v1/authorities/verify", { payload, artifact }),
823
- delegate: (input: DelegateAuthorityInput) =>
824
- this.issueAuthorityRequest({
825
- ...input,
826
- parentAuthorityId: input.parent,
827
- }),
828
- revoke: (authorityId: string): Promise<{ ok: true }> =>
829
- this.request("POST", `/v1/authorities/${encodeURIComponent(authorityId)}/revoke`, {}),
830
- };
831
- }
832
-
833
- /**
834
- * Action Protocol — evaluate (dry-run) vs execute (enforce + evidence).
835
- * There is no legacy evaluateAction() surface.
836
- */
837
- get action() {
838
- return {
839
- evaluate: (input: EvaluateActionInput, options: RequestOptions = {}) =>
840
- this.executeOrEvaluateAction(input, options, "evaluate"),
841
- execute: (input: EvaluateActionInput, options: RequestOptions = {}) =>
842
- this.executeOrEvaluateAction(input, options, "execute"),
843
- };
844
- }
845
-
846
- get evidence() {
847
- return {
848
- verify: (
849
- payload: DecisionEvidencePayload,
850
- evidence: DecisionEvidence,
851
- ): Promise<ArtifactVerification> =>
852
- this.request("POST", "/v1/evidence/verify", { payload, evidence }),
853
- };
854
- }
855
-
856
- async verifyMandate(
857
- payload: MandatePayload,
858
- evidence: MandateEvidence,
859
- ): Promise<ArtifactVerification> {
860
- return this.request("POST", "/v1/mandates/verify", { payload, evidence });
861
- }
862
-
863
- async listIntents(): Promise<{ intents: Intent[] }> {
864
- return this.request("GET", "/v1/intents");
865
- }
866
-
867
- async createIntent(
868
- input: CreateIntentInput,
869
- ): Promise<{ intent: { id: string; title: string; status: string } }> {
870
- return this.request("POST", "/v1/intents", {
871
- title: input.title,
872
- description: input.description,
873
- intent_type: input.intentType,
874
- risk_level: input.riskLevel,
875
- max_risk_level: input.maxRiskLevel,
876
- expires_at: input.expiresAt,
877
- allowed_action_types: input.allowedActionTypes,
878
- target_pattern: input.targetPattern,
879
- resource_allowlist: input.resourceAllowlist,
880
- });
881
- }
882
-
883
- async getIntent(intentId: string): Promise<{ intent: IntentDetail }> {
884
- return this.request("GET", `/v1/intents/${encodeURIComponent(intentId)}`);
885
- }
886
-
887
- async updateIntentStatus(
888
- intentId: string,
889
- status: Exclude<IntentStatus, "expired">,
890
- ): Promise<{ intent: { id: string; title: string; status: IntentStatus } }> {
891
- return this.updateIntent(intentId, { status });
892
- }
893
-
894
- async updateIntent(
895
- intentId: string,
896
- input: UpdateIntentInput,
897
- ): Promise<{
898
- intent: {
899
- id: string;
900
- title: string;
901
- status: IntentStatus;
902
- description?: string | null;
903
- intent_type?: string | null;
904
- risk_level?: RiskLevel;
905
- max_risk_level?: RiskLevel;
906
- expires_at?: string | null;
907
- };
908
- }> {
909
- return this.request("PATCH", `/v1/intents/${encodeURIComponent(intentId)}`, {
910
- status: input.status,
911
- title: input.title,
912
- description: input.description,
913
- intent_type: input.intentType,
914
- risk_level: input.riskLevel,
915
- max_risk_level: input.maxRiskLevel,
916
- expires_at: input.expiresAt,
917
- });
918
- }
919
-
920
- async getAuthorityGraph(): Promise<{ authority_graph: AuthorityGraph }> {
921
- return this.request("GET", "/v1/authority/graph");
922
- }
923
-
924
- async createAuthorityEdge(input: CreateAuthorityEdgeInput): Promise<{ edge: { id: string } }> {
925
- return this.request("POST", "/v1/authority/edges", {
926
- from_actor_id: input.fromActorId,
927
- from_actor_type: input.fromActorType,
928
- to_actor_id: input.toActorId,
929
- to_actor_type: input.toActorType,
930
- authority_scope: input.authorityScope,
931
- conditions: input.conditions,
932
- max_risk_level: input.maxRiskLevel,
933
- expires_at: input.expiresAt,
934
- });
935
- }
936
-
937
- async getActionEvaluation(actionRequestId: string): Promise<{ evaluation: ActionEvaluation }> {
938
- return this.request(
939
- "GET",
940
- `/v1/action-requests/${encodeURIComponent(actionRequestId)}/evaluation`,
941
- );
942
- }
943
-
944
- async getRootIntentChain(
945
- actionRequestId: string,
946
- ): Promise<{ root_intent_chain: RootIntentChain }> {
947
- return this.request(
948
- "GET",
949
- `/v1/action-requests/${encodeURIComponent(actionRequestId)}/root-intent`,
950
- );
951
- }
952
-
953
- async listAgents(): Promise<{ agents: Agent[] }> {
954
- return this.request("GET", "/v1/agents");
955
- }
956
-
957
- async getAgent(agentId: string): Promise<{ agent: Agent }> {
958
- return this.request("GET", `/v1/agents/${encodeURIComponent(agentId)}`);
959
- }
960
-
961
- async createAgent(input: CreateAgentInput): Promise<{ agent: Agent }> {
962
- return this.request("POST", "/v1/agents", {
963
- name: input.name,
964
- model_provider: input.modelProvider,
965
- model_name: input.modelName,
966
- description: input.description,
967
- environment: input.environment,
968
- authority_level: input.authorityLevel,
969
- sponsor_user_id: input.sponsorUserId,
970
- });
971
- }
972
-
973
- async updateAgentStatus(
974
- agentId: string,
975
- input: UpdateAgentStatusInput,
976
- ): Promise<{ agent: { id: string; name: string; status: Agent["status"] } }> {
977
- return this.request("PATCH", `/v1/agents/${encodeURIComponent(agentId)}`, {
978
- status: input.status,
979
- reason: input.reason,
980
- revoke_delegations: input.revokeDelegations,
981
- restore_delegations: input.restoreDelegations,
982
- });
983
- }
984
-
985
- async deleteAgent(agentId: string): Promise<{ ok: true }> {
986
- return this.request("DELETE", `/v1/agents/${encodeURIComponent(agentId)}`);
987
- }
988
-
989
- async listAuthorities(): Promise<{ delegations: Delegation[]; authorities?: AuthoritySummary[] }> {
990
- return this.request("GET", "/v1/authorities");
991
- }
992
-
993
- async getAuthority(authorityId: string): Promise<{ delegation: Delegation }> {
994
- return this.request("GET", `/v1/authorities/${encodeURIComponent(authorityId)}`);
995
- }
996
-
997
- async listActionRequests(): Promise<{ action_requests: ActionRequest[] }> {
998
- return this.request("GET", "/v1/action-requests");
999
- }
1000
-
1001
- async approveActionRequest(actionRequestId: string, approverUserId: string, reason?: string) {
1002
- return this.resolveActionRequest(actionRequestId, "approve", approverUserId, reason);
1003
- }
1004
-
1005
- async rejectActionRequest(actionRequestId: string, approverUserId: string, reason?: string) {
1006
- return this.resolveActionRequest(actionRequestId, "reject", approverUserId, reason);
1007
- }
1008
-
1009
- async escalateActionRequest(actionRequestId: string, approverUserId: string, reason?: string) {
1010
- return this.resolveActionRequest(actionRequestId, "escalate", approverUserId, reason);
1011
- }
1012
-
1013
- private async resolveActionRequest(
1014
- actionRequestId: string,
1015
- action: "approve" | "reject" | "escalate",
1016
- approverUserId: string,
1017
- reason?: string,
1018
- ): Promise<{
1019
- ok: true;
1020
- decision: "approved" | "rejected" | "escalated";
1021
- action_decision: "allowed" | "blocked" | "require_approval";
1022
- reason: string;
1023
- }> {
1024
- return this.request(
1025
- "POST",
1026
- `/v1/action-requests/${encodeURIComponent(actionRequestId)}/${action}`,
1027
- { reason, approver_user_id: approverUserId },
1028
- );
1029
- }
1030
-
1031
- async listPolicies(): Promise<{ policies: Policy[] }> {
1032
- return this.request("GET", "/v1/policies");
1033
- }
1034
-
1035
- async createPolicy(
1036
- input: CreatePolicyInput,
1037
- ): Promise<{ policy: Pick<Policy, "id" | "name" | "status" | "created_at"> }> {
1038
- return this.request("POST", "/v1/policies", {
1039
- name: input.name,
1040
- description: input.description,
1041
- policy_type: input.policyType,
1042
- status: input.status,
1043
- priority: input.priority,
1044
- action_type: input.actionType,
1045
- amount_greater_than: input.amountGreaterThan,
1046
- resource_sensitivity: input.resourceSensitivity,
1047
- external_recipient: input.externalRecipient,
1048
- environment: input.environment,
1049
- decision: input.decision,
1050
- approver_role: input.approverRole,
1051
- max_actions_per_window: input.maxActionsPerWindow
1052
- ? {
1053
- count: input.maxActionsPerWindow.count,
1054
- window_seconds: input.maxActionsPerWindow.windowSeconds,
1055
- action_type: input.maxActionsPerWindow.actionType,
1056
- }
1057
- : undefined,
1058
- max_amount_per_window: input.maxAmountPerWindow
1059
- ? {
1060
- amount: input.maxAmountPerWindow.amount,
1061
- window_seconds: input.maxAmountPerWindow.windowSeconds,
1062
- }
1063
- : undefined,
1064
- });
1065
- }
1066
-
1067
- async simulatePolicy(
1068
- policyId: string,
1069
- input: { limit?: number; since?: string } = {},
1070
- ): Promise<{
1071
- simulation: PolicySimulation;
1072
- meta: {
1073
- simulated_at: string;
1074
- sample_size: number;
1075
- changed_count: number;
1076
- unchanged_count: number;
1077
- };
1078
- }> {
1079
- return this.request("POST", `/v1/policies/${encodeURIComponent(policyId)}/simulate`, input);
1080
- }
1081
-
1082
- async publishPolicy(
1083
- policyId: string,
1084
- input: { force?: boolean } = {},
1085
- ): Promise<{ ok: true; policyId: string; simulation: Record<string, unknown> }> {
1086
- return this.request("POST", `/v1/policies/${encodeURIComponent(policyId)}/publish`, input);
1087
- }
1088
-
1089
- async listActionTypes(): Promise<{ action_types: CustomActionType[] }> {
1090
- return this.listCustomActionTypes();
1091
- }
1092
-
1093
- async listCustomActionTypes(): Promise<{ action_types: CustomActionType[] }> {
1094
- return this.request("GET", "/v1/action-types");
1095
- }
1096
-
1097
- async createCustomActionType(input: CreateCustomActionTypeInput): Promise<{
1098
- action_type: Pick<CustomActionType, "id" | "label" | "policy_type" | "source" | "created_at">;
1099
- }> {
1100
- return this.request("POST", "/v1/action-types", {
1101
- id: input.id,
1102
- label: input.label,
1103
- description: input.description,
1104
- category: input.category,
1105
- policy_type: input.policyType,
1106
- payload_schema: input.payloadSchema ?? {},
1107
- });
1108
- }
1109
-
1110
- async listAuditEvents(): Promise<{ audit_events: AuditEvent[] }> {
1111
- return this.request("GET", "/v1/audit-events");
1112
- }
1113
-
1114
- async getAuditEvent(auditEventId: string): Promise<{ audit_event: AuditEvent }> {
1115
- return this.request("GET", `/v1/audit-events/${encodeURIComponent(auditEventId)}`);
1116
- }
1117
-
1118
- async verifyAuditChain(): Promise<AuditChainVerification> {
1119
- return this.request("GET", "/v1/audit-events/verify");
1120
- }
1121
-
1122
- async listApiKeys(): Promise<{ api_keys: ApiKeySummary[] }> {
1123
- return this.request("GET", "/v1/api-keys");
1124
- }
1125
- }
1
+ /**
2
+ * @auctra/sdk — Stage 1.0 public surface.
3
+ *
4
+ * Modular layout under src/{types,artifacts,client,authority,action,evidence}.ts.
5
+ * Canonical API: authority.* / action.* / evidence.* — no createDelegation / evaluateAction.
6
+ */
7
+ export { AUCTRA_SDK_VERSION, DEFAULT_BASE_URL } from "./types.js";
8
+ export type * from "./types.js";
9
+ export { AuctraApiError, verifyMandateArtifact, verifyDecisionArtifact } from "./artifacts.js";
10
+ export { Auctra } from "./client.js";