@dnsid-ai/sdk 0.20.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,657 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ ArgumentError: () => import_protocol5.ArgumentError,
35
+ DEFAULT_REGISTRY_URL: () => import_registry.DEFAULT_REGISTRY_URL,
36
+ DNSID_VERSION: () => import_protocol5.DNSID_VERSION,
37
+ DNSSECMode: () => import_protocol5.DNSSECMode,
38
+ DNSSECState: () => import_protocol5.DNSSECState,
39
+ DnsIdTxtRecord: () => import_protocol5.DnsIdTxtRecord,
40
+ DomainLog: () => import_protocol5.DomainLog,
41
+ DomainSnapshot: () => import_protocol5.DomainSnapshot,
42
+ HttpSignaturesProfile: () => import_http_signatures.HttpSignaturesProfile,
43
+ IdentityManager: () => import_protocol5.IdentityManager,
44
+ InMemoryIdentityCache: () => import_protocol5.InMemoryIdentityCache,
45
+ JWKS: () => import_protocol5.JWKS,
46
+ JWKS_MAX_RESPONSE_BYTES: () => import_protocol5.JWKS_MAX_RESPONSE_BYTES,
47
+ JoseProfile: () => import_jose.JoseProfile,
48
+ LogRegistry: () => import_protocol5.LogRegistry,
49
+ ManagedIssuanceActivationError: () => ManagedIssuanceActivationError,
50
+ ManagedIssuanceSubmissionError: () => ManagedIssuanceSubmissionError,
51
+ ManagedKeyRotationActivationError: () => ManagedKeyRotationActivationError,
52
+ ManagedKeyRotationSubmissionError: () => ManagedKeyRotationSubmissionError,
53
+ NoopLogReader: () => import_protocol5.NoopLogReader,
54
+ ParseError: () => import_protocol5.ParseError,
55
+ PreparedEventSubmissionError: () => import_registry.PreparedEventSubmissionError,
56
+ RegistryClient: () => import_registry.RegistryClient,
57
+ RegistryWorkflowError: () => import_registry.RegistryWorkflowError,
58
+ SDK_CONFORMANCE: () => SDK_CONFORMANCE,
59
+ SIGNING_ALGS: () => import_protocol5.SIGNING_ALGS,
60
+ STATUS_MAX_RESPONSE_BYTES: () => import_protocol5.STATUS_MAX_RESPONSE_BYTES,
61
+ ValidationError: () => import_protocol5.ValidationError,
62
+ VerificationCode: () => import_protocol5.VerificationCode,
63
+ VerificationError: () => import_protocol5.VerificationError,
64
+ VerifiedDomain: () => import_protocol5.VerifiedDomain,
65
+ WebBotAuthProfile: () => import_web_bot_auth.WebBotAuthProfile,
66
+ activeStatusDocument: () => import_protocol5.activeStatusDocument,
67
+ awaitRegistryManagedPublication: () => import_registry.awaitRegistryManagedPublication,
68
+ createHttpSignaturesProfile: () => import_http_signatures.createHttpSignaturesProfile,
69
+ createIdentityManager: () => createIdentityManager,
70
+ createIdentityVerifier: () => createIdentityVerifier,
71
+ createJoseProfile: () => import_jose.createJoseProfile,
72
+ createWebBotAuthProfile: () => import_web_bot_auth.createWebBotAuthProfile,
73
+ fromBase64Url: () => import_protocol5.fromBase64Url,
74
+ httpSignatures: () => httpSignatures,
75
+ isDomainName: () => import_protocol5.isDomainName,
76
+ isTransientVerificationError: () => import_protocol5.isTransientVerificationError,
77
+ issueManagedIdentity: () => issueManagedIdentity,
78
+ jose: () => jose,
79
+ jwkSignatureAlg: () => import_protocol5.jwkSignatureAlg,
80
+ jwkThumbprint: () => import_protocol5.jwkThumbprint,
81
+ normalizeFQDN: () => import_protocol5.normalizeFQDN,
82
+ parseKaDuration: () => import_protocol5.parseKaDuration,
83
+ parseKeyId: () => import_protocol5.parseKeyId,
84
+ publishClientControlledRecord: () => import_registry.publishClientControlledRecord,
85
+ publishToRegistry: () => import_registry.publishToRegistry,
86
+ registry: () => registry,
87
+ resumeManagedIssuance: () => resumeManagedIssuance,
88
+ resumeManagedOperationalKeyRotation: () => resumeManagedOperationalKeyRotation,
89
+ retryTransientVerification: () => import_protocol5.retryTransientVerification,
90
+ rotateManagedOperationalKey: () => rotateManagedOperationalKey,
91
+ toArrayBuffer: () => import_protocol5.toArrayBuffer,
92
+ toBase64Url: () => import_protocol5.toBase64Url,
93
+ validateAgentStatus: () => import_protocol5.validateAgentStatus,
94
+ verifyWithKey: () => import_protocol5.verifyWithKey,
95
+ webBotAuth: () => webBotAuth
96
+ });
97
+ module.exports = __toCommonJS(index_exports);
98
+ var import_protocol4 = require("@dnsid-ai/protocol");
99
+ __reExport(index_exports, require("@dnsid-ai/protocol"), module.exports);
100
+ var import_protocol5 = require("@dnsid-ai/protocol");
101
+ var jose = __toESM(require("@dnsid-ai/jose"), 1);
102
+ var httpSignatures = __toESM(require("@dnsid-ai/http-signatures"), 1);
103
+ var registry = __toESM(require("@dnsid-ai/registry"), 1);
104
+ var webBotAuth = __toESM(require("@dnsid-ai/web-bot-auth"), 1);
105
+ var import_jose = require("@dnsid-ai/jose");
106
+ var import_http_signatures = require("@dnsid-ai/http-signatures");
107
+ var import_registry = require("@dnsid-ai/registry");
108
+
109
+ // src/managed-key-rotation.ts
110
+ var import_protocol = require("@dnsid-ai/protocol");
111
+ var import_writer = require("@dnsid-ai/log-c2sp-tlog/writer");
112
+ var ManagedKeyRotationSubmissionError = class extends import_protocol.VerificationError {
113
+ rotation;
114
+ retryWithSameBytes;
115
+ constructor(message, rotation, retryWithSameBytes2, cause) {
116
+ super(message, { code: import_protocol.VerificationCode.LogError, transient: retryWithSameBytes2, cause });
117
+ this.name = "ManagedKeyRotationSubmissionError";
118
+ this.rotation = rotation;
119
+ this.retryWithSameBytes = retryWithSameBytes2;
120
+ }
121
+ };
122
+ var ManagedKeyRotationActivationError = class extends import_protocol.VerificationError {
123
+ rotation;
124
+ constructor(message, rotation, cause) {
125
+ super(message, { code: import_protocol.VerificationCode.LogError, transient: true, cause });
126
+ this.name = "ManagedKeyRotationActivationError";
127
+ this.rotation = rotation;
128
+ }
129
+ };
130
+ async function rotateManagedOperationalKey(options) {
131
+ const previousKey = await options.keyProvider.signingKey();
132
+ new import_protocol.JWKS([previousKey]).validateOperational();
133
+ const previousThumbprint = await (0, import_protocol.jwkThumbprint)(previousKey);
134
+ const newKid = await options.keyProvider.generateKey();
135
+ const newKey = await options.keyProvider.jwk(newKid);
136
+ new import_protocol.JWKS([newKey]).validateOperational();
137
+ if (await (0, import_protocol.jwkThumbprint)(newKey) === previousThumbprint) {
138
+ throw permanentRotationError("managed KEY_ROTATION requires a distinct pending operational key");
139
+ }
140
+ let raw;
141
+ try {
142
+ raw = await options.registryClient.prepareKeyRotation(options.domain, {
143
+ previousKeyId: previousThumbprint,
144
+ publicKey: newKey
145
+ }, options.idempotencyKey);
146
+ } catch (cause) {
147
+ throw new import_protocol.VerificationError("managed key rotation preparation is unavailable", {
148
+ code: import_protocol.VerificationCode.LogError,
149
+ transient: true,
150
+ cause
151
+ });
152
+ }
153
+ if (raw.logReference !== options.logReference) {
154
+ throw permanentRotationError(`registry preparation returned unexpected log reference ${raw.logReference}`);
155
+ }
156
+ const context = { expectedFqdn: options.domain, previousOperationalKey: previousKey };
157
+ let prepared = await (0, import_writer.parsePreparedC2spTlogEvent)(raw.entryBytes, raw.logReference, context);
158
+ if (prepared.envelope.type !== "KEY_ROTATION") {
159
+ throw permanentRotationError(`registry preparation returned ${String(prepared.envelope.type)} instead of KEY_ROTATION`);
160
+ }
161
+ if (prepared.envelope.fqdn !== options.domain) {
162
+ throw permanentRotationError("registry KEY_ROTATION fqdn does not match the expected identity");
163
+ }
164
+ if (prepared.envelope.prev_thumb !== previousThumbprint) {
165
+ throw permanentRotationError("registry KEY_ROTATION previous thumbprint does not match the active operational key");
166
+ }
167
+ await assertPreparedRotationKey(prepared.envelope.new_ku, prepared.envelope.new_thumb, newKey);
168
+ prepared = await (0, import_writer.signPreparedC2spTlogEvent)(prepared, "PreviousOperational", options.keyProvider, context);
169
+ prepared = await (0, import_writer.signPreparedC2spTlogEvent)(prepared, "NewOperational", options.keyProvider, context);
170
+ const entryBytes = await (0, import_writer.c2spTlogEntryBytes)(prepared, context);
171
+ const rotation = {
172
+ domain: options.domain,
173
+ logReference: options.logReference,
174
+ previousKid: previousKey.kid,
175
+ newKid,
176
+ entryBytes: entryBytes.slice(),
177
+ idempotencyKey: options.idempotencyKey,
178
+ activated: false,
179
+ applicationSigningPaused: true
180
+ };
181
+ await options.persistRotation(rotation);
182
+ await options.setApplicationSigningPaused(true);
183
+ return submitManagedRotation(options.keyProvider, options.registryClient, rotation, options.persistRotation, options.setApplicationSigningPaused);
184
+ }
185
+ async function resumeManagedOperationalKeyRotation(options) {
186
+ if (options.rotation.activated) {
187
+ if (!options.rotation.applicationSigningPaused) return options.rotation;
188
+ await options.setApplicationSigningPaused(false);
189
+ const completed = { ...options.rotation, applicationSigningPaused: false };
190
+ await options.persistRotation(completed);
191
+ return completed;
192
+ }
193
+ if (options.rotation.submission?.state === "rejected") {
194
+ throw permanentRotationError("cannot resume a rejected managed key rotation");
195
+ }
196
+ await options.setApplicationSigningPaused(true);
197
+ return submitManagedRotation(options.keyProvider, options.registryClient, options.rotation, options.persistRotation, options.setApplicationSigningPaused);
198
+ }
199
+ async function submitManagedRotation(keyProvider, registryClient, rotation, persistRotation, setApplicationSigningPaused) {
200
+ let submission;
201
+ try {
202
+ submission = await registryClient.submitPreparedEvent(rotation.domain, rotation.entryBytes, rotation.idempotencyKey);
203
+ } catch (cause) {
204
+ const retryWithSameBytes2 = structuredRetryWithSameBytes(cause);
205
+ throw new ManagedKeyRotationSubmissionError(
206
+ retryWithSameBytes2 ? "managed key rotation submission is unresolved; retry the same bytes and idempotency key" : "managed key rotation submission failed terminally",
207
+ rotation,
208
+ retryWithSameBytes2,
209
+ cause
210
+ );
211
+ }
212
+ await assertSubmissionMatchesRotation(rotation, submission);
213
+ const next = { ...rotation, submission };
214
+ await persistRotation(next);
215
+ if (submission.state === "rejected") {
216
+ throw new ManagedKeyRotationSubmissionError(
217
+ `registry rejected the prepared KEY_ROTATION: ${submission.errorCode ?? "unknown error"}`,
218
+ next,
219
+ false
220
+ );
221
+ }
222
+ if (submission.state !== "accepted") return next;
223
+ let recoverable = next;
224
+ try {
225
+ await reconcileAcceptedRotation(keyProvider, rotation);
226
+ const activated = { ...next, activated: true };
227
+ await persistRotation(activated);
228
+ recoverable = activated;
229
+ await setApplicationSigningPaused(false);
230
+ const completed = { ...activated, applicationSigningPaused: false };
231
+ await persistRotation(completed);
232
+ return completed;
233
+ } catch (cause) {
234
+ throw new ManagedKeyRotationActivationError(
235
+ "managed key rotation was accepted, but local key activation is incomplete; resume with this rotation state",
236
+ recoverable,
237
+ cause
238
+ );
239
+ }
240
+ }
241
+ async function reconcileAcceptedRotation(keyProvider, rotation) {
242
+ const activeKid = (await keyProvider.signingKey()).kid;
243
+ if (activeKid === rotation.previousKid) {
244
+ await keyProvider.activate(rotation.newKid);
245
+ } else if (activeKid !== rotation.newKid) {
246
+ throw permanentRotationError(`unexpected active key ${activeKid} while reconciling managed key rotation`);
247
+ }
248
+ if ((await keyProvider.listKeyIds()).includes(rotation.previousKid)) {
249
+ await keyProvider.supersede(rotation.previousKid);
250
+ }
251
+ }
252
+ async function assertPreparedRotationKey(value, thumbprint, expected) {
253
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw permanentRotationError("registry KEY_ROTATION is missing new_ku");
254
+ const actual = value;
255
+ const actualThumbprint = await (0, import_protocol.jwkThumbprint)(actual);
256
+ const expectedThumbprint = await (0, import_protocol.jwkThumbprint)(expected);
257
+ if (actual.kid !== expected.kid || actual.alg !== expected.alg || actualThumbprint !== expectedThumbprint) {
258
+ throw permanentRotationError("registry KEY_ROTATION new key does not match the generated pending key");
259
+ }
260
+ if (thumbprint !== expectedThumbprint) throw permanentRotationError("registry KEY_ROTATION new thumbprint does not match the generated pending key");
261
+ }
262
+ async function assertSubmissionMatchesRotation(rotation, submission) {
263
+ if (rotation.submission?.entryHash && submission.entryHash && rotation.submission.entryHash !== submission.entryHash) {
264
+ throw permanentRotationError("registry reconciled a different entry hash for this managed key rotation");
265
+ }
266
+ if (submission.state !== "accepted") return;
267
+ const expectedHash = await sha256Hex(rotation.entryBytes);
268
+ if (submission.entryHash !== expectedHash) {
269
+ throw permanentRotationError("accepted submission entry hash does not match the exact managed key rotation bytes");
270
+ }
271
+ if (submission.keyId !== void 0 && submission.keyId !== rotation.newKid) {
272
+ throw permanentRotationError("accepted submission key_id does not match the generated pending key");
273
+ }
274
+ }
275
+ function structuredRetryWithSameBytes(cause) {
276
+ if (cause && typeof cause === "object" && "retryWithSameBytes" in cause && typeof cause.retryWithSameBytes === "boolean") {
277
+ return cause.retryWithSameBytes;
278
+ }
279
+ return true;
280
+ }
281
+ function permanentRotationError(message, cause) {
282
+ return new import_protocol.VerificationError(message, { code: import_protocol.VerificationCode.LogError, transient: false, cause });
283
+ }
284
+ async function sha256Hex(value) {
285
+ const bytes = value.slice();
286
+ const digest = await crypto.subtle.digest("SHA-256", bytes.buffer);
287
+ return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
288
+ }
289
+
290
+ // src/managed-issuance.ts
291
+ var import_protocol2 = require("@dnsid-ai/protocol");
292
+ var import_writer2 = require("@dnsid-ai/log-c2sp-tlog/writer");
293
+ var ManagedIssuanceSubmissionError = class extends import_protocol2.VerificationError {
294
+ issuance;
295
+ retryWithSameBytes;
296
+ constructor(message, issuance, retryWithSameBytes2, transient, cause) {
297
+ super(message, { code: import_protocol2.VerificationCode.LogError, transient, cause });
298
+ this.name = "ManagedIssuanceSubmissionError";
299
+ this.issuance = issuance;
300
+ this.retryWithSameBytes = retryWithSameBytes2;
301
+ }
302
+ };
303
+ var ManagedIssuanceActivationError = class extends import_protocol2.VerificationError {
304
+ issuance;
305
+ constructor(issuance, cause) {
306
+ super("managed ISSUANCE was accepted, but publication or activation is incomplete; resume this issuance", {
307
+ code: import_protocol2.VerificationCode.LogError,
308
+ transient: true,
309
+ cause
310
+ });
311
+ this.name = "ManagedIssuanceActivationError";
312
+ this.issuance = issuance;
313
+ }
314
+ };
315
+ async function issueManagedIdentity(options) {
316
+ const domain = (0, import_protocol2.normalizeFQDN)(options.domain, true);
317
+ const governanceId = (0, import_protocol2.normalizeFQDN)(options.governanceId, true);
318
+ if (!options.idempotencyKey || options.idempotencyKey.trim() !== options.idempotencyKey || options.idempotencyKey.length > 200) {
319
+ throw permanentLogError("managed ISSUANCE idempotencyKey must contain 1 to 200 characters without surrounding whitespace");
320
+ }
321
+ const existing = await options.loadIssuance();
322
+ const { entityKey, operationalKey } = await trustedKeys(options.entityKey, options.operationalKeyProvider);
323
+ if (existing) {
324
+ assertSameOperation(existing, { ...options, domain, governanceId });
325
+ return resumeManagedIssuanceState(options, existing, entityKey, operationalKey);
326
+ }
327
+ const intent = {
328
+ domain,
329
+ governanceId,
330
+ idempotencyKey: options.idempotencyKey,
331
+ entityKid: entityKey.kid,
332
+ entityThumbprint: await (0, import_protocol2.jwkThumbprint)(entityKey),
333
+ operationalKid: operationalKey.kid,
334
+ operationalThumbprint: await (0, import_protocol2.jwkThumbprint)(operationalKey),
335
+ activated: false
336
+ };
337
+ const raced = await options.createIssuance(intent);
338
+ if (raced) {
339
+ assertSameOperation(raced, { ...options, domain, governanceId });
340
+ return resumeManagedIssuanceState(options, raced, entityKey, operationalKey);
341
+ }
342
+ return prepareAndSubmit(options, intent, entityKey, operationalKey);
343
+ }
344
+ async function resumeManagedIssuance(options) {
345
+ const issuance = await options.loadIssuance();
346
+ if (!issuance) throw permanentLogError("no durable managed ISSUANCE operation exists");
347
+ const { entityKey, operationalKey } = await trustedKeys(options.entityKey, options.operationalKeyProvider);
348
+ return resumeManagedIssuanceState(options, issuance, entityKey, operationalKey);
349
+ }
350
+ async function resumeManagedIssuanceState(options, issuance, entityKey, operationalKey) {
351
+ await assertPersistedKeys(issuance, entityKey, operationalKey);
352
+ if (issuance.activated) return issuance;
353
+ if (issuance.terminalFailure || issuance.submission?.state === "rejected") {
354
+ throw permanentLogError("cannot resume a terminally failed managed ISSUANCE");
355
+ }
356
+ if (issuance.submission?.state === "accepted") {
357
+ await verifyPersistedCompletedIssuance(issuance, entityKey, operationalKey);
358
+ await assertAcceptedBinding(issuance, issuance.submission);
359
+ return activate(options, issuance);
360
+ }
361
+ if (!issuance.entryBytes || !issuance.logReference) {
362
+ return prepareAndSubmit(options, issuance, entityKey, operationalKey);
363
+ }
364
+ return submit(options, issuance);
365
+ }
366
+ async function prepareAndSubmit(options, intent, entityKey, operationalKey) {
367
+ let raw;
368
+ try {
369
+ raw = await options.registryClient.prepareIssuance(intent.domain, intent.idempotencyKey);
370
+ } catch (cause) {
371
+ if (isTerminalFailure(cause)) {
372
+ const terminal = {
373
+ ...intent,
374
+ terminalFailure: { stage: "preparation", errorCode: structuredErrorCode(cause) }
375
+ };
376
+ await options.persistIssuance(terminal);
377
+ throw new ManagedIssuanceSubmissionError("managed ISSUANCE preparation failed terminally", terminal, false, false, cause);
378
+ }
379
+ throw new ManagedIssuanceSubmissionError("managed ISSUANCE preparation is unavailable; resume the durable intent", intent, false, true, cause);
380
+ }
381
+ const context = {
382
+ expectedFqdn: intent.domain,
383
+ expectedGovernanceId: intent.governanceId,
384
+ entityKey,
385
+ operationalKey
386
+ };
387
+ let prepared;
388
+ try {
389
+ if (options.logReference && raw.logReference !== options.logReference) {
390
+ throw permanentLogError(`registry preparation returned unexpected log reference ${raw.logReference}`);
391
+ }
392
+ prepared = await (0, import_writer2.parsePreparedC2spTlogEvent)(raw.entryBytes, raw.logReference, context);
393
+ if (prepared.envelope.type !== "ISSUANCE") {
394
+ throw permanentLogError(`registry preparation returned ${String(prepared.envelope.type)} instead of ISSUANCE`);
395
+ }
396
+ const existingSignatures = prepared.envelope.sigs;
397
+ if (!existingSignatures?.ae) throw permanentLogError("registry ISSUANCE preparation is missing the accountable-entity signature");
398
+ } catch (cause) {
399
+ const terminal = {
400
+ ...intent,
401
+ terminalFailure: { stage: "preparation", errorCode: structuredErrorCode(cause) }
402
+ };
403
+ await options.persistIssuance(terminal);
404
+ throw new ManagedIssuanceSubmissionError("managed ISSUANCE preparation failed trusted validation", terminal, false, false, cause);
405
+ }
406
+ prepared = await (0, import_writer2.signPreparedC2spTlogEvent)(prepared, "OperationalCountersignature", options.operationalKeyProvider, context);
407
+ const entryBytes = await (0, import_writer2.c2spTlogEntryBytes)(prepared, context);
408
+ const completed = {
409
+ ...intent,
410
+ logReference: raw.logReference,
411
+ entryBytes: entryBytes.slice(),
412
+ entryHash: await sha256Hex2(entryBytes)
413
+ };
414
+ await options.persistIssuance(completed);
415
+ return submit(options, completed);
416
+ }
417
+ async function submit(options, issuance) {
418
+ if (!issuance.entryBytes || !issuance.logReference) throw permanentLogError("managed ISSUANCE exact bytes are not persisted");
419
+ const { entityKey, operationalKey } = await trustedKeys(options.entityKey, options.operationalKeyProvider);
420
+ await verifyPersistedCompletedIssuance(issuance, entityKey, operationalKey);
421
+ let submission;
422
+ try {
423
+ submission = await options.registryClient.submitPreparedEvent(
424
+ issuance.domain,
425
+ issuance.entryBytes.slice(),
426
+ issuance.idempotencyKey
427
+ );
428
+ } catch (cause) {
429
+ const sameBytes = retryWithSameBytes(cause);
430
+ let recoverable = issuance;
431
+ if (sameBytes) {
432
+ recoverable = {
433
+ ...issuance,
434
+ submission: {
435
+ state: "indeterminate",
436
+ entryHash: issuance.entryHash,
437
+ errorCode: structuredErrorCode(cause)
438
+ }
439
+ };
440
+ await options.persistIssuance(recoverable);
441
+ } else {
442
+ recoverable = {
443
+ ...issuance,
444
+ submission: {
445
+ state: "rejected",
446
+ entryHash: issuance.entryHash,
447
+ errorCode: structuredErrorCode(cause)
448
+ },
449
+ terminalFailure: { stage: "submission", errorCode: structuredErrorCode(cause) }
450
+ };
451
+ await options.persistIssuance(recoverable);
452
+ }
453
+ throw new ManagedIssuanceSubmissionError(
454
+ sameBytes ? "managed ISSUANCE submission is indeterminate; retry the same bytes and idempotency key" : "managed ISSUANCE submission failed terminally",
455
+ recoverable,
456
+ sameBytes,
457
+ sameBytes,
458
+ cause
459
+ );
460
+ }
461
+ await assertAcceptedBinding(issuance, submission);
462
+ const reconciled = { ...issuance, submission };
463
+ await options.persistIssuance(reconciled);
464
+ if (submission.state === "rejected") {
465
+ throw new ManagedIssuanceSubmissionError(
466
+ `registry rejected the prepared ISSUANCE: ${submission.errorCode ?? "unknown error"}`,
467
+ reconciled,
468
+ false,
469
+ false
470
+ );
471
+ }
472
+ if (submission.state !== "accepted") return reconciled;
473
+ return activate(options, reconciled);
474
+ }
475
+ async function activate(options, issuance) {
476
+ try {
477
+ await options.activateAcceptedIssuance(issuance);
478
+ const activated = { ...issuance, activated: true };
479
+ await options.persistIssuance(activated);
480
+ return activated;
481
+ } catch (cause) {
482
+ throw new ManagedIssuanceActivationError(issuance, cause);
483
+ }
484
+ }
485
+ async function trustedKeys(entityKey, operationalProvider) {
486
+ const operationalKey = await operationalProvider.signingKey();
487
+ new import_protocol2.JWKS([entityKey]).validateRecordSigning();
488
+ new import_protocol2.JWKS([operationalKey]).validateOperational();
489
+ if (await (0, import_protocol2.jwkThumbprint)(entityKey) === await (0, import_protocol2.jwkThumbprint)(operationalKey)) {
490
+ throw permanentLogError("managed ISSUANCE requires distinct entity and operational keys");
491
+ }
492
+ return { entityKey, operationalKey };
493
+ }
494
+ async function assertPersistedKeys(state, entityKey, operationalKey) {
495
+ if (state.entityKid !== entityKey.kid || state.entityThumbprint !== await (0, import_protocol2.jwkThumbprint)(entityKey)) {
496
+ throw permanentLogError("durable managed ISSUANCE entity key does not match the trusted provider");
497
+ }
498
+ if (state.operationalKid !== operationalKey.kid || state.operationalThumbprint !== await (0, import_protocol2.jwkThumbprint)(operationalKey)) {
499
+ throw permanentLogError("durable managed ISSUANCE operational key does not match the trusted provider");
500
+ }
501
+ }
502
+ async function verifyPersistedCompletedIssuance(state, entityKey, operationalKey) {
503
+ if (!state.entryBytes || !state.entryHash || !state.logReference) {
504
+ throw permanentLogError("durable managed ISSUANCE is missing exact bytes, hash, or log reference");
505
+ }
506
+ const actualHash = await sha256Hex2(state.entryBytes);
507
+ if (actualHash !== state.entryHash) throw permanentLogError("durable managed ISSUANCE bytes do not match their persisted hash");
508
+ const context = {
509
+ expectedFqdn: state.domain,
510
+ expectedGovernanceId: state.governanceId,
511
+ entityKey,
512
+ operationalKey
513
+ };
514
+ const prepared = await (0, import_writer2.parsePreparedC2spTlogEvent)(state.entryBytes, state.logReference, context);
515
+ const canonical = await (0, import_writer2.c2spTlogEntryBytes)(prepared, context);
516
+ if (!bytesEqual(canonical, state.entryBytes)) throw permanentLogError("durable managed ISSUANCE bytes are not the canonical completed entry");
517
+ }
518
+ function assertSameOperation(state, options) {
519
+ if (state.domain !== options.domain || state.governanceId !== options.governanceId || state.idempotencyKey !== options.idempotencyKey) {
520
+ throw permanentLogError("a different durable managed ISSUANCE operation already exists");
521
+ }
522
+ }
523
+ async function assertAcceptedBinding(issuance, submission) {
524
+ if (issuance.submission?.entryHash && submission.entryHash !== issuance.submission.entryHash) {
525
+ throw permanentLogError("registry reconciled a different entry hash for this managed ISSUANCE");
526
+ }
527
+ if (submission.state !== "accepted") return;
528
+ const expectedHash = await sha256Hex2(issuance.entryBytes);
529
+ if (submission.entryHash !== expectedHash) throw permanentLogError("accepted entry hash does not match the exact managed ISSUANCE bytes");
530
+ if (!Number.isSafeInteger(submission.index) || submission.index < 0) throw permanentLogError("accepted managed ISSUANCE is missing a valid index");
531
+ const expectedReference = `${issuance.logReference}@${submission.index}`;
532
+ if (submission.logRef !== expectedReference) throw permanentLogError("accepted managed ISSUANCE final log reference does not match its prepared binding");
533
+ }
534
+ function retryWithSameBytes(cause) {
535
+ return !(cause && typeof cause === "object" && "retryWithSameBytes" in cause && cause.retryWithSameBytes === false);
536
+ }
537
+ function isTerminalFailure(cause) {
538
+ if (!cause || typeof cause !== "object") return false;
539
+ if ("retryable" in cause && cause.retryable === false) return true;
540
+ if ("state" in cause && cause.state === "rejected") return true;
541
+ return "retryWithSameBytes" in cause && cause.retryWithSameBytes === false;
542
+ }
543
+ function structuredErrorCode(cause) {
544
+ if (cause && typeof cause === "object" && "code" in cause && typeof cause.code === "string") {
545
+ return cause.code;
546
+ }
547
+ return void 0;
548
+ }
549
+ function bytesEqual(left, right) {
550
+ return left.length === right.length && left.every((byte, index) => byte === right[index]);
551
+ }
552
+ function permanentLogError(message, cause) {
553
+ return new import_protocol2.VerificationError(message, { code: import_protocol2.VerificationCode.LogError, transient: false, cause });
554
+ }
555
+ async function sha256Hex2(bytes) {
556
+ const copy = bytes.slice();
557
+ const digest = await crypto.subtle.digest("SHA-256", copy.buffer);
558
+ return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
559
+ }
560
+
561
+ // src/index.ts
562
+ var import_web_bot_auth = require("@dnsid-ai/web-bot-auth");
563
+
564
+ // src/conformance.ts
565
+ var import_protocol3 = require("@dnsid-ai/protocol");
566
+ var import_version = require("@dnsid-ai/log-c2sp-tlog/version");
567
+ var c2spTlogConformance = [
568
+ `profile=${import_version.C2SP_TLOG_PROFILE_VERSION}`,
569
+ ...Object.entries(import_version.C2SP_TLOG_SPECIFICATIONS).map(([name, revision]) => `${name}=${revision}`),
570
+ `dnsid-method=${import_version.DNSID_C2SP_METHOD_REVISION}`
571
+ ].join(";");
572
+ var SDK_CONFORMANCE = Object.freeze({
573
+ publishProfile: import_protocol3.DEFAULT_PUBLISH_PROFILE,
574
+ verificationProfiles: Object.freeze({
575
+ [import_protocol3.DNSID_DRAFT01_VERSION]: import_protocol3.DNSID_DRAFT01_VERSION,
576
+ [import_protocol3.DNSID_VERSION]: import_protocol3.DNSID_DRAFT01_VERSION
577
+ }),
578
+ specificationStatus: "internet-draft",
579
+ logBindings: Object.freeze({
580
+ "c2sp-tlog": c2spTlogConformance
581
+ }),
582
+ knownDeviations: Object.freeze([])
583
+ });
584
+
585
+ // src/index.ts
586
+ function createIdentityManager(config, deps) {
587
+ return new import_protocol4.IdentityManager(config, deps);
588
+ }
589
+ function createIdentityVerifier(config, deps) {
590
+ return new import_protocol4.IdentityManager(config, deps);
591
+ }
592
+ // Annotate the CommonJS export names for ESM import in node:
593
+ 0 && (module.exports = {
594
+ ArgumentError,
595
+ DEFAULT_REGISTRY_URL,
596
+ DNSID_VERSION,
597
+ DNSSECMode,
598
+ DNSSECState,
599
+ DnsIdTxtRecord,
600
+ DomainLog,
601
+ DomainSnapshot,
602
+ HttpSignaturesProfile,
603
+ IdentityManager,
604
+ InMemoryIdentityCache,
605
+ JWKS,
606
+ JWKS_MAX_RESPONSE_BYTES,
607
+ JoseProfile,
608
+ LogRegistry,
609
+ ManagedIssuanceActivationError,
610
+ ManagedIssuanceSubmissionError,
611
+ ManagedKeyRotationActivationError,
612
+ ManagedKeyRotationSubmissionError,
613
+ NoopLogReader,
614
+ ParseError,
615
+ PreparedEventSubmissionError,
616
+ RegistryClient,
617
+ RegistryWorkflowError,
618
+ SDK_CONFORMANCE,
619
+ SIGNING_ALGS,
620
+ STATUS_MAX_RESPONSE_BYTES,
621
+ ValidationError,
622
+ VerificationCode,
623
+ VerificationError,
624
+ VerifiedDomain,
625
+ WebBotAuthProfile,
626
+ activeStatusDocument,
627
+ awaitRegistryManagedPublication,
628
+ createHttpSignaturesProfile,
629
+ createIdentityManager,
630
+ createIdentityVerifier,
631
+ createJoseProfile,
632
+ createWebBotAuthProfile,
633
+ fromBase64Url,
634
+ httpSignatures,
635
+ isDomainName,
636
+ isTransientVerificationError,
637
+ issueManagedIdentity,
638
+ jose,
639
+ jwkSignatureAlg,
640
+ jwkThumbprint,
641
+ normalizeFQDN,
642
+ parseKaDuration,
643
+ parseKeyId,
644
+ publishClientControlledRecord,
645
+ publishToRegistry,
646
+ registry,
647
+ resumeManagedIssuance,
648
+ resumeManagedOperationalKeyRotation,
649
+ retryTransientVerification,
650
+ rotateManagedOperationalKey,
651
+ toArrayBuffer,
652
+ toBase64Url,
653
+ validateAgentStatus,
654
+ verifyWithKey,
655
+ webBotAuth,
656
+ ...require("@dnsid-ai/protocol")
657
+ });