verdifax 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -881,6 +881,173 @@ interface ApproverRevocation {
881
881
  id: number;
882
882
  revoked: boolean;
883
883
  }
884
+ /** The kind of a control signal. Each is also a CloudEvents type,
885
+ * `com.verdifax.` and the kind. */
886
+ type SignalKind = "run.refused" | "run.halted" | "run.failed" | "policy.changed" | "signoff.recorded" | "approver.registered" | "approver.revoked" | "key.created" | "key.revoked";
887
+ /** The Verdifax event inside a {@link SignalEvent}, verdifax.signal.v1. */
888
+ interface SignalEventData {
889
+ /** `verdifax.signal.v1`. */
890
+ form: string;
891
+ kind: SignalKind | (string & {});
892
+ /** The account, `account-N`. */
893
+ account: string;
894
+ /** The event's place in the account's feed, from 1. */
895
+ sequence: number;
896
+ /** The previous event's `event_hash`, or 64 zeros for the account's
897
+ * first event. */
898
+ previous_signal_hash: Hex64;
899
+ /** {@link signalEventHash} of the kind, the entry's hash and the place. */
900
+ event_hash: Hex64;
901
+ run_id?: number;
902
+ api_key_id?: number;
903
+ /** A short reason a reader can route on, for a refused, halted or
904
+ * failed run. */
905
+ reason?: string;
906
+ /** The sealed entry the event names, in the exact form
907
+ * `verdifax-verify` reads. */
908
+ entry: Record<string, unknown>;
909
+ }
910
+ /** One control signal, as a CloudEvents 1.0 envelope. */
911
+ interface SignalEvent {
912
+ specversion: string;
913
+ /** `account-N/SEQUENCE`. */
914
+ id: string;
915
+ source: string;
916
+ /** `com.verdifax.` and the kind. */
917
+ type: string;
918
+ time: string;
919
+ datacontenttype: string;
920
+ data: SignalEventData;
921
+ }
922
+ /** One page of the feed. Returned by {@link VerdifaxClient.getSignals}. */
923
+ interface SignalPage {
924
+ /** The events after the place asked for, oldest first. */
925
+ events: SignalEvent[];
926
+ /** The place to read from next: the last event's sequence, or the
927
+ * place asked for when the page is empty. */
928
+ next_after: number;
929
+ /** The newest sequence in the account's feed, 0 when it is empty. */
930
+ newest: number;
931
+ }
932
+ /** Options for {@link VerdifaxClient.getSignals}. */
933
+ interface GetSignalsOptions {
934
+ /** The last sequence already read. 0, the default, reads from the start. */
935
+ after?: number;
936
+ /** 1 to 500 events. The server's default is 100. */
937
+ limit?: number;
938
+ /** 0 to 25 seconds to hold the request open when there is no event yet.
939
+ * Defaults to 0. */
940
+ wait?: number;
941
+ /** Read GET /account/signals with the owner key instead of GET /signals
942
+ * with a feed key. */
943
+ asOwner?: boolean;
944
+ }
945
+ /** Options for {@link VerdifaxClient.followSignals}. */
946
+ interface FollowSignalsOptions {
947
+ /** The last sequence already read. 0, the default, reads from the start. */
948
+ after?: number;
949
+ /** 0 to 25 seconds each read waits for the next event. Defaults to 25. */
950
+ wait?: number;
951
+ /** Read GET /account/signals with the owner key instead of GET /signals
952
+ * with a feed key. */
953
+ asOwner?: boolean;
954
+ }
955
+ /** Options for {@link VerdifaxClient.createFeedKey}. */
956
+ interface CreateFeedKeyOptions {
957
+ /** RFC 3339 or YYYY-MM-DD. */
958
+ expiresAt?: string;
959
+ }
960
+ /** A new feed key with its secret, which is shown this once. A feed key
961
+ * reads the account's signal feed and nothing else. Returned by
962
+ * {@link VerdifaxClient.createFeedKey}. */
963
+ type CreatedFeedKey = CreatedAccountKey;
964
+ /** Returned by {@link VerdifaxClient.revokeFeedKey}. */
965
+ interface FeedKeyRevocation {
966
+ ok: boolean;
967
+ id: number;
968
+ revoked: boolean;
969
+ }
970
+ /** Options for {@link VerdifaxClient.createWebhook}. */
971
+ interface CreateWebhookOptions {
972
+ /** The kinds to deliver, each once. Empty or left out takes every kind. */
973
+ types?: SignalKind[];
974
+ }
975
+ /** A webhook subscription, without its secret. */
976
+ interface Webhook {
977
+ id: number;
978
+ url: string;
979
+ /** The kinds it delivers. Empty means every kind. */
980
+ types: SignalKind[];
981
+ created_at: string;
982
+ }
983
+ /** A new webhook subscription with its secret, `whsec_` and base64,
984
+ * which is shown this once. Check each delivery with it using
985
+ * {@link verifyWebhook}. Returned by {@link VerdifaxClient.createWebhook}. */
986
+ interface CreatedWebhook extends Webhook {
987
+ ok: boolean;
988
+ secret: string;
989
+ hint: string;
990
+ }
991
+ /** Returned by {@link VerdifaxClient.listWebhooks}. */
992
+ interface WebhookList {
993
+ ok: boolean;
994
+ webhooks: Webhook[];
995
+ }
996
+ /** Returned by {@link VerdifaxClient.deleteWebhook}. */
997
+ interface WebhookDeletion {
998
+ ok: boolean;
999
+ id: number;
1000
+ deleted: boolean;
1001
+ }
1002
+ /** Options for {@link VerdifaxClient.listWebhookDeliveries}. */
1003
+ interface ListWebhookDeliveriesOptions {
1004
+ /** 1 to 500 deliveries. The server's default is 50. */
1005
+ limit?: number;
1006
+ }
1007
+ /** One delivery of one event to a webhook. A delivery is a copy: the pull
1008
+ * feed and the public log are the record. */
1009
+ interface WebhookDelivery {
1010
+ /** The event's place in the account's feed. */
1011
+ sequence: number;
1012
+ /** `pending`, `delivered` or `failed`. */
1013
+ status: string;
1014
+ attempts: number;
1015
+ last_status_code: number;
1016
+ last_error: string;
1017
+ created_at: string;
1018
+ delivered_at?: string;
1019
+ next_attempt_at?: string;
1020
+ }
1021
+ /** Returned by {@link VerdifaxClient.listWebhookDeliveries}: the newest
1022
+ * deliveries first. */
1023
+ interface WebhookDeliveryList {
1024
+ ok: boolean;
1025
+ webhook_id: number;
1026
+ deliveries: WebhookDelivery[];
1027
+ }
1028
+ /** The headers of a webhook delivery: a fetch `Headers`, or an object such
1029
+ * as Node's `req.headers`. Names are read without regard to case. */
1030
+ type WebhookHeaders = {
1031
+ get(name: string): string | null;
1032
+ } | Record<string, string | string[] | undefined>;
1033
+ /** Options for {@link verifyWebhook}. */
1034
+ interface VerifyWebhookOptions {
1035
+ /** How far, in seconds, `webhook-timestamp` may be from `now` in either
1036
+ * direction. Defaults to 300. */
1037
+ toleranceSeconds?: number;
1038
+ /** The time to check the timestamp against. Defaults to the current
1039
+ * time. */
1040
+ now?: Date;
1041
+ }
1042
+ /** An event's place in its account's feed, for {@link signalEventHash}. */
1043
+ interface SignalEventHashFields {
1044
+ /** The account, `account-N`. */
1045
+ account: string;
1046
+ /** The event's sequence, a whole number. */
1047
+ sequence: number;
1048
+ /** The previous event's hash, or 64 zeros for the account's first. */
1049
+ previousSignalHash: string;
1050
+ }
884
1051
 
885
1052
  /**
886
1053
  * The job helper: runs the steps of one job and keeps the map of step ids
@@ -1002,6 +1169,15 @@ declare const MAX_BATCH_ROWS = 1000;
1002
1169
  * | `getNewestSignOff(options)` | GET /signoffs/newest, or GET /account/signoffs/newest with asOwner | required |
1003
1170
  * | `getSignOffs(runId, options)` | GET /runs/{id}/signoffs, or GET /account/runs/{id}/signoffs with asOwner | required |
1004
1171
  * | `getSignOffHistory()` | GET /account/signoffs/history | owner key |
1172
+ * | `getSignals(options)` | GET /signals, or GET /account/signals with asOwner | feed key, or owner key |
1173
+ * | `followSignals(options)` | GET /signals page after page, or GET /account/signals with asOwner | feed key, or owner key |
1174
+ * | `createFeedKey(name, options)` | POST /account/feed-keys | owner key |
1175
+ * | `revokeFeedKey(id)` | DELETE /account/feed-keys/{id} | owner key |
1176
+ * | `createWebhook(url, options)` | POST /account/webhooks | owner key |
1177
+ * | `listWebhooks()` | GET /account/webhooks | owner key |
1178
+ * | `deleteWebhook(id)` | DELETE /account/webhooks/{id} | owner key |
1179
+ * | `listWebhookDeliveries(id, options)` | GET /account/webhooks/{id}/deliveries | owner key |
1180
+ * | `getFailureReceipt(id)` | GET /runs/{id}/failure-receipt | required |
1005
1181
  * | `job(jobId)` | none, returns a {@link VerdifaxJob} | none |
1006
1182
  *
1007
1183
  * With the `signingKey` option set, every path to POST /execute carries
@@ -1220,6 +1396,44 @@ declare class VerdifaxClient {
1220
1396
  /** The account's whole chain of sign-offs, oldest first, in the form
1221
1397
  * `verdifax-verify --signoff-history FILE` reads. Needs the owner key. */
1222
1398
  getSignOffHistory(): Promise<SignOffRecord[]>;
1399
+ /** One page of the account's feed: the events after `after`, oldest
1400
+ * first, with `next_after` to read from next. With `wait` the server
1401
+ * holds the request open up to that many seconds for the next event, and
1402
+ * this call's timeout is at least the wait plus 30 seconds. With
1403
+ * `asOwner` it reads GET /account/signals with the owner key. Bad
1404
+ * options are refused before sending. Save the events and check them
1405
+ * with `verdifax-verify --signals`. */
1406
+ getSignals(options?: GetSignalsOptions): Promise<SignalPage>;
1407
+ /** Follows the feed from `after`, yielding each event once, in order,
1408
+ * until you stop with `break` or `return`. Each read starts at the page
1409
+ * before's `next_after`, waits up to `wait` seconds (default 25) when
1410
+ * there is no event, and is retried like any GET. A read that still
1411
+ * fails throws {@link SignalFeedError}, whose `lastSequence` is the last
1412
+ * sequence yielded: follow again from there and nothing is lost. Bad
1413
+ * options are refused here, before anything is sent. */
1414
+ followSignals(options?: FollowSignalsOptions): AsyncGenerator<SignalEvent, void, undefined>;
1415
+ /** Creates a feed key in the owner's account. A feed key reads the
1416
+ * account's signal feed, with {@link getSignals} and
1417
+ * {@link followSignals}, and nothing else. The secret is in the result
1418
+ * this once. */
1419
+ createFeedKey(name: string, options?: CreateFeedKeyOptions): Promise<CreatedFeedKey>;
1420
+ /** Revokes one of the account's feed keys. An id that is not a feed key
1421
+ * of the account throws {@link NotFoundError}. */
1422
+ revokeFeedKey(id: number): Promise<FeedKeyRevocation>;
1423
+ /** Subscribes an https address to the account's signals. `types` are the
1424
+ * kinds to deliver, each once; empty or left out takes every kind. The
1425
+ * secret, `whsec_` and base64, is in the result this once: check each
1426
+ * delivery with {@link verifyWebhook}. A delivery is a copy: the pull
1427
+ * feed and the public log are the record. The server checks the address
1428
+ * too, and refuses an eleventh subscription with HTTP 409. */
1429
+ createWebhook(url: string, options?: CreateWebhookOptions): Promise<CreatedWebhook>;
1430
+ /** The account's webhook subscriptions, without their secrets. */
1431
+ listWebhooks(): Promise<WebhookList>;
1432
+ /** Ends a webhook subscription. Its events stay in the pull feed. */
1433
+ deleteWebhook(id: number): Promise<WebhookDeletion>;
1434
+ /** A webhook's newest deliveries first, up to `limit` (1 to 500; the
1435
+ * server's default is 50). */
1436
+ listWebhookDeliveries(id: number, options?: ListWebhookDeliveriesOptions): Promise<WebhookDeliveryList>;
1223
1437
  getRun(runId: number): Promise<Run>;
1224
1438
  verifyRun(runId: number): Promise<VerifyResponse>;
1225
1439
  listRuns(params?: ListRunsParams): Promise<{
@@ -1256,6 +1470,10 @@ declare class VerdifaxClient {
1256
1470
  getAivpT4HaltReceipt(runId: number): Promise<Record<string, unknown>>;
1257
1471
  getAttestationGapReceipt(runId: number): Promise<Record<string, unknown>>;
1258
1472
  getCESAuditRecord(runId: number): Promise<Record<string, unknown>>;
1473
+ /** A failed run's sealed failure receipt, in the form `verdifax-verify`
1474
+ * reads. A run that failed before failure receipts were sealed has none
1475
+ * and throws {@link NotFoundError}. */
1476
+ getFailureReceipt(runId: number): Promise<Record<string, unknown>>;
1259
1477
  /** The audit report for a run, as JSON. */
1260
1478
  getRunReport(runId: number): Promise<Record<string, unknown>>;
1261
1479
  /** The run's sealed audit bundle as the exact JSON text the server
@@ -1556,6 +1774,48 @@ declare function signOffPreimage(fields: {
1556
1774
  * never holds the approver's private key. */
1557
1775
  declare function approverKeyProof(approverKey: Uint8Array | KeyObject): ApproverKeyProof;
1558
1776
 
1777
+ /**
1778
+ * The signal feed: every control signal Verdifax recorded for an account,
1779
+ * in order, each with its sealed entry. The feed cannot show a signal
1780
+ * Verdifax never recorded.
1781
+ *
1782
+ * A feed key reads the feed and nothing else. The owner key reads the same
1783
+ * feed on its /account route and manages feed keys and webhooks. A webhook
1784
+ * delivery is a copy: the pull feed and the public log are the record.
1785
+ *
1786
+ * The request building, the checks made before sending, the follow loop,
1787
+ * webhook verification and the event hash live here; the client's methods
1788
+ * are thin wrappers over them.
1789
+ */
1790
+
1791
+ /**
1792
+ * Checks one webhook delivery under the Standard Webhooks scheme and
1793
+ * returns its CloudEvent. Pass the headers as received, the body as the
1794
+ * exact bytes received (a Buffer, a Uint8Array or a string, never parsed
1795
+ * JSON) and the subscription's `whsec_` secret.
1796
+ *
1797
+ * The signed content is `webhook-id`, a dot, `webhook-timestamp`, a dot and
1798
+ * the body. `webhook-signature` is a space-separated list of `v1,<base64>`
1799
+ * entries, and any one may match; each is compared in constant time. A
1800
+ * timestamp more than `toleranceSeconds` (default 300) from `now` in either
1801
+ * direction is refused. Header names are read without regard to case. The
1802
+ * body must be a JSON object whose top-level `id` is a string equal to
1803
+ * `webhook-id`.
1804
+ *
1805
+ * Throws {@link VerdifaxError} naming the check that failed. The secret is
1806
+ * never placed in an error message. A delivery is a copy: the pull feed and
1807
+ * the public log are the record.
1808
+ */
1809
+ declare function verifyWebhook(headers: WebhookHeaders, body: Uint8Array | string, secret: string, options?: VerifyWebhookOptions): SignalEvent;
1810
+ /**
1811
+ * The hash the next event in an account's feed names, matching the
1812
+ * orchestrator's SignalEventHash: hex SHA-256 of `verdifax.signal.v1`, the
1813
+ * kind, the hash of the event's entry, the account, the decimal sequence
1814
+ * and the previous event's hash, joined by single zero bytes. It makes no
1815
+ * request.
1816
+ */
1817
+ declare function signalEventHash(kind: string, entryHash: string, fields: SignalEventHashFields): string;
1818
+
1559
1819
  /**
1560
1820
  * Input-validation helpers, mirrors the Python SDK's
1561
1821
  * `_validation.py` and the Go SDK's `validation.go` for
@@ -1639,5 +1899,17 @@ declare class APIKeyRequiredError extends VerdifaxError {
1639
1899
  readonly name: string;
1640
1900
  constructor();
1641
1901
  }
1902
+ /** Thrown by {@link VerdifaxClient.followSignals} when a read fails or a
1903
+ * page does not follow on from the last one. `lastSequence` is the last
1904
+ * sequence the generator handed out, so the feed is never lost: follow
1905
+ * again with `after: lastSequence`. The error the read threw, after the
1906
+ * client's normal retries, is `cause`. */
1907
+ declare class SignalFeedError extends VerdifaxError {
1908
+ readonly lastSequence: number;
1909
+ readonly name: string;
1910
+ constructor(lastSequence: number, reason: string, options?: {
1911
+ cause?: unknown;
1912
+ });
1913
+ }
1642
1914
 
1643
- export { APIError, APIKeyRequiredError, type Account, type AccountInfo, type AccountKey, type AccountKeyList, type AccountKeyRevocation, type AccountRunsExport, type AdminAPIKey, type AdminCreateAccountOptions, type AdminCreateAccountResponse, type AdminCreateKeyOptions, type AdminCreateKeyResponse, type AdminEraseRequest, type Approver, type ApproverKeyProof, type ApproverList, type ApproverRegistration, type ApproverRevocation, type AsOwnerOptions, type AttestRequest, type AttestationList, AuthError, CRES_ENGINE_VERSION, CRES_PREIMAGE_VERSION, type ClientConfig, type CreateAccountKeyOptions, type CreatedAccountKey, type DCAEProofBundle, type DCAEVerdict, DCAE_PREIMAGE_VERSION, DSE_FORMULA_VERSION, type DeletionReceipt, type DeterminismDiff, type DeterminismRun, EXECUTE_FIELDS, type ExecuteBatchResponse, type ExecuteBatchResult, type ExecuteRequest, type ExecuteResponse, type ExecutionManifest, type ExportRow, type ExportRunsParams, type FormulaEra, type Health, type Hex64, type JobLink, type JobStepOptions, type KeyTier, type ListAttestationsParams, type ListRunsParams, MAX_BATCH_ROWS, type NewestSignOff, NotFoundError, type PDFFormat, type Policy, type PolicyActivation, type PolicyActivationSignature, type PolicyActorType, type PolicyClassification, type PolicyContext, type PolicyList, type PolicyObjectType, type PolicyTestRequest, type PolicyTestResult, type PolicyWithDocument, RUN_STATUSES, type ReproducibilityContext, type RequestKeyChange, type RequestKeyPair, type RequestKeyRegistration, type RequestKeyRegistrationBody, type RequestSignature, type RequestSignatureV2, type Run, type RunStats, type RunStatus, type RunSummary, type RunsExport, type RunsExportCSV, type SearchRunsParams, type SignOffDecision, type SignOffOptions, type SignOffRecord, type SignOffSignature, type SignOffTarget, type SignOffTargetKind, type SignedRequestBody, VerdifaxClient, VerdifaxError, VerdifaxJob, type VerdifaxVersion, type VerifyDeterminismResponse, type VerifyResponse, approverKeyProof, captureEnvironment, cresReceiptHash, dcaeClosureHash, dseDispatchHash, formatProviderPayload, fromEnv, generateRequestKeyPair, policyActivationApproval, policyActivationPreimage, requestKeyChangeApproval, requestKeyChangePreimage, requestKeyRegistrationBody, requestSignaturePreimage, requestSignaturePreimageV2, signOffPreimage, signRequest, signRequestV2, validateHex64, validateJobName, validateRouteId };
1915
+ export { APIError, APIKeyRequiredError, type Account, type AccountInfo, type AccountKey, type AccountKeyList, type AccountKeyRevocation, type AccountRunsExport, type AdminAPIKey, type AdminCreateAccountOptions, type AdminCreateAccountResponse, type AdminCreateKeyOptions, type AdminCreateKeyResponse, type AdminEraseRequest, type Approver, type ApproverKeyProof, type ApproverList, type ApproverRegistration, type ApproverRevocation, type AsOwnerOptions, type AttestRequest, type AttestationList, AuthError, CRES_ENGINE_VERSION, CRES_PREIMAGE_VERSION, type ClientConfig, type CreateAccountKeyOptions, type CreateFeedKeyOptions, type CreateWebhookOptions, type CreatedAccountKey, type CreatedFeedKey, type CreatedWebhook, type DCAEProofBundle, type DCAEVerdict, DCAE_PREIMAGE_VERSION, DSE_FORMULA_VERSION, type DeletionReceipt, type DeterminismDiff, type DeterminismRun, EXECUTE_FIELDS, type ExecuteBatchResponse, type ExecuteBatchResult, type ExecuteRequest, type ExecuteResponse, type ExecutionManifest, type ExportRow, type ExportRunsParams, type FeedKeyRevocation, type FollowSignalsOptions, type FormulaEra, type GetSignalsOptions, type Health, type Hex64, type JobLink, type JobStepOptions, type KeyTier, type ListAttestationsParams, type ListRunsParams, type ListWebhookDeliveriesOptions, MAX_BATCH_ROWS, type NewestSignOff, NotFoundError, type PDFFormat, type Policy, type PolicyActivation, type PolicyActivationSignature, type PolicyActorType, type PolicyClassification, type PolicyContext, type PolicyList, type PolicyObjectType, type PolicyTestRequest, type PolicyTestResult, type PolicyWithDocument, RUN_STATUSES, type ReproducibilityContext, type RequestKeyChange, type RequestKeyPair, type RequestKeyRegistration, type RequestKeyRegistrationBody, type RequestSignature, type RequestSignatureV2, type Run, type RunStats, type RunStatus, type RunSummary, type RunsExport, type RunsExportCSV, type SearchRunsParams, type SignOffDecision, type SignOffOptions, type SignOffRecord, type SignOffSignature, type SignOffTarget, type SignOffTargetKind, type SignalEvent, type SignalEventData, type SignalEventHashFields, SignalFeedError, type SignalKind, type SignalPage, type SignedRequestBody, VerdifaxClient, VerdifaxError, VerdifaxJob, type VerdifaxVersion, type VerifyDeterminismResponse, type VerifyResponse, type VerifyWebhookOptions, type Webhook, type WebhookDeletion, type WebhookDelivery, type WebhookDeliveryList, type WebhookHeaders, type WebhookList, approverKeyProof, captureEnvironment, cresReceiptHash, dcaeClosureHash, dseDispatchHash, formatProviderPayload, fromEnv, generateRequestKeyPair, policyActivationApproval, policyActivationPreimage, requestKeyChangeApproval, requestKeyChangePreimage, requestKeyRegistrationBody, requestSignaturePreimage, requestSignaturePreimageV2, signOffPreimage, signRequest, signRequestV2, signalEventHash, validateHex64, validateJobName, validateRouteId, verifyWebhook };