@humanagencyp/hap-core 0.12.0 → 0.13.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/README.md +3 -3
- package/dist/index.d.mts +591 -123
- package/dist/index.d.ts +591 -123
- package/dist/index.js +887 -23
- package/dist/index.mjs +845 -22
- package/package.json +2 -1
- package/src/canonicalize.ts +9 -0
- package/src/commitment-modes.ts +21 -9
- package/src/content-binding.ts +26 -1
- package/src/errors.ts +24 -8
- package/src/gatekeeper.ts +52 -8
- package/src/index.ts +5 -1
- package/src/issuance.ts +250 -0
- package/src/mandate.ts +52 -14
- package/src/owner-signature.ts +86 -39
- package/src/profile.ts +45 -0
- package/src/proposal-content.ts +219 -0
- package/src/ticket-projection.ts +167 -0
- package/src/ticket.ts +254 -20
- package/src/types.ts +50 -5
- package/src/verifier-policy.ts +178 -0
- package/src/versions.ts +50 -19
package/dist/index.d.mts
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Canonical v0.
|
|
2
|
+
* Canonical v0.8 error codes — protocol.md → *Error Codes*.
|
|
3
3
|
*
|
|
4
4
|
* "Error codes are canonical across the protocol. Implementations MUST emit
|
|
5
5
|
* exactly these codes and MUST NOT alias them under different names." This
|
|
6
6
|
* module is the single list both the Gatekeeper (local checks) and any AS
|
|
7
7
|
* client built on this library read from, so the two cannot drift.
|
|
8
8
|
*
|
|
9
|
-
* v0.
|
|
10
|
-
* context → scope, receipt → ticket) — see protocol.md → *Migration from
|
|
11
|
-
* v0.6* → "Error-code renames" for the old→new map. There is no alias: a v0.6
|
|
12
|
-
* code name is simply gone from this list, by design (no backward
|
|
13
|
-
* compatibility — CLAUDE.md "Decided by the owner").
|
|
9
|
+
* v0.8 adds codes and retires none; every v0.7 code keeps its name.
|
|
14
10
|
*/
|
|
15
11
|
/** Codes an Authority Server (or a local Gatekeeper check) emits refusing a mandate request. */
|
|
16
|
-
declare const MANDATE_ERROR_CODES: readonly ["BOUNDS_HASH_MISMATCH", "SCOPE_HASH_MISMATCH", "INVALID_SIGNATURE", "OWNER_NOT_COVERED", "TTL_EXPIRED", "PROFILE_NOT_FOUND", "PROFILE_INVALID", "PROFILE_HASH_MISMATCH", "COVERAGE_INSUFFICIENT", "MALFORMED_MANDATE", "VERSION_UNSUPPORTED", "OWNER_NOT_APPROVER", "BOUNDS_INVALID_VALUE", "SCOPE_INVALID_VALUE", "ABOVE_CAP_CONFIG_INVALID", "OWNER_SIGNATURE_REQUIRED", "OWNER_SIGNATURE_INVALID"];
|
|
17
|
-
/** Codes an Authority Server emits refusing a ticket request
|
|
18
|
-
|
|
12
|
+
declare const MANDATE_ERROR_CODES: readonly ["BOUNDS_HASH_MISMATCH", "SCOPE_HASH_MISMATCH", "INVALID_SIGNATURE", "OWNER_NOT_COVERED", "TTL_EXPIRED", "PROFILE_NOT_FOUND", "PROFILE_INVALID", "PROFILE_HASH_MISMATCH", "COVERAGE_INSUFFICIENT", "MALFORMED_MANDATE", "VERSION_UNSUPPORTED", "OWNER_NOT_APPROVER", "BOUNDS_INVALID_VALUE", "SCOPE_INVALID_VALUE", "ABOVE_CAP_CONFIG_INVALID", "COMMITMENT_MODE_NOT_ALLOWED", "GROUP_CAP_EXCEEDED", "OWNER_SIGNATURE_REQUIRED", "OWNER_SIGNATURE_INVALID"];
|
|
13
|
+
/** Codes an Authority Server emits refusing a ticket request, plus the
|
|
14
|
+
* Gatekeeper-local and verifier codes of the same table. */
|
|
15
|
+
declare const TICKET_ERROR_CODES: readonly ["MANDATE_NOT_FOUND", "MANDATE_EXPIRED", "MANDATE_REVOKED", "BOUND_EXCEEDED", "CUMULATIVE_LIMIT_EXCEEDED", "COVERAGE_INSUFFICIENT", "PROFILE_NOT_FOUND", "INVALID_ACTION_TYPE", "APPROVAL_REQUIRED", "APPROVAL_IMPOSSIBLE", "PROPOSAL_CONTENT_MISMATCH", "PROPOSAL_REQUIRED", "PROPOSAL_NOT_FOUND", "PROPOSAL_NOT_APPROVED", "PROPOSAL_EXPIRED", "PROPOSAL_REJECTED", "PROPOSAL_MISMATCH", "PROPOSAL_MANDATE_MISMATCH", "PROPOSAL_ALREADY_EXECUTED", "PROPOSAL_WITHDRAWN", "MALFORMED_TICKET_REQUEST", "CONTENT_BINDING_INCOMPLETE", "IDEMPOTENCY_KEY_REQUIRED", "IDEMPOTENCY_MISMATCH", "APPROVAL_SIGNATURE_REQUIRED", "APPROVAL_SIGNATURE_INVALID", "TICKET_REQUEST_MISMATCH", "POLICY_UNMET"];
|
|
16
|
+
/** Codes an Authority Server emits refusing a proposal submission or a decision (v0.8). */
|
|
17
|
+
declare const PROPOSAL_ERROR_CODES: readonly ["PROPOSAL_NOT_ENCRYPTED", "DECIDER_INVALID", "PROPOSAL_ALREADY_DECIDED", "PROPOSAL_APPROVERS_INVALID"];
|
|
19
18
|
/** The full canonical surface — every code a conformant implementation may emit. */
|
|
20
|
-
type HapErrorCode = (typeof MANDATE_ERROR_CODES)[number] | (typeof TICKET_ERROR_CODES)[number];
|
|
19
|
+
type HapErrorCode = (typeof MANDATE_ERROR_CODES)[number] | (typeof TICKET_ERROR_CODES)[number] | (typeof PROPOSAL_ERROR_CODES)[number];
|
|
21
20
|
/**
|
|
22
21
|
* A refusal carrying one of the canonical codes above. Thrown by local
|
|
23
22
|
* (Gatekeeper-side, no-wire-round-trip) checks in this library; an AS client
|
|
@@ -108,10 +107,14 @@ interface Subject {
|
|
|
108
107
|
/** When the underlying verification was performed (unix seconds). */
|
|
109
108
|
verified_at?: number;
|
|
110
109
|
}
|
|
111
|
-
/** protocol
|
|
110
|
+
/** The protocol version an artifact was issued under. This package verifies
|
|
111
|
+
* each under its own rules (protocol.md → *Version negotiation*, rule 4). */
|
|
112
|
+
type ProtocolVersion = '0.8' | '0.7';
|
|
113
|
+
/** protocol.md → *Mandate Payload (v0.8)*; a `"0.7"` payload is the same shape
|
|
114
|
+
* without `above_cap_approvals` and without the v0.8 owner-signed fields. */
|
|
112
115
|
interface MandatePayload {
|
|
113
116
|
mandate_id: string;
|
|
114
|
-
version:
|
|
117
|
+
version: ProtocolVersion;
|
|
115
118
|
profile_id: string;
|
|
116
119
|
/** Hash of the canonical bounds string. */
|
|
117
120
|
bounds_hash: string;
|
|
@@ -128,10 +131,16 @@ interface MandatePayload {
|
|
|
128
131
|
/** Exactly one entry in v0.7 (Mandate rule 7). */
|
|
129
132
|
mandate_owners: MandateOwnerEntry[];
|
|
130
133
|
gate_content_hashes: Record<string, string>;
|
|
131
|
-
commitment_mode:
|
|
132
|
-
/**
|
|
134
|
+
commitment_mode: CommitmentMode;
|
|
135
|
+
/** Present together with `above_cap_approvers` and (v0.8) `above_cap_approvals`:
|
|
136
|
+
* under `review_above_cap`, or `review` in a group with approval-kind caps
|
|
137
|
+
* the owner's mandate can reach (protocol.md → *Group roles*, rule 7). */
|
|
133
138
|
above_cap_caps?: Record<string, number>;
|
|
134
139
|
above_cap_approvers?: string[];
|
|
140
|
+
/** v0.8 — how many distinct `above_cap_approvers`, other than the Mandate
|
|
141
|
+
* Owner, must approve. Integer ≥ 1. Present exactly when
|
|
142
|
+
* `above_cap_approvers` is (Mandate rule 10). A v0.7 mandate carries none. */
|
|
143
|
+
above_cap_approvals?: number;
|
|
135
144
|
/**
|
|
136
145
|
* Present iff the mandate carries an encrypted-intent disclosure object
|
|
137
146
|
* (companion spec `intent-disclosure@0.1`) — `sha256:`-prefixed hash
|
|
@@ -317,6 +326,15 @@ interface ProfileBoundsField {
|
|
|
317
326
|
* min(value, maximum). Absent → no ceiling.
|
|
318
327
|
*/
|
|
319
328
|
maximum?: number;
|
|
329
|
+
/**
|
|
330
|
+
* v0.8 (Bounds Schema rule 11) — a bound only the Gatekeeper enforces, such
|
|
331
|
+
* as a read window whose actions produce no ticket. The Authority Server
|
|
332
|
+
* still verifies the value at issuance (`maximum`, enum membership, any
|
|
333
|
+
* group ceiling) and never reads it at ticket time. A group cap on such a
|
|
334
|
+
* bound is always hard, and the signed value is the ceiling (*Group
|
|
335
|
+
* ceilings*).
|
|
336
|
+
*/
|
|
337
|
+
enforcedBy?: 'gatekeeper';
|
|
320
338
|
}
|
|
321
339
|
/**
|
|
322
340
|
* v0.5 Content Provenance — how a profile's action content is hashed into a
|
|
@@ -384,7 +402,23 @@ interface ContentBinding {
|
|
|
384
402
|
* Absent → the binding applies to every gated action under the profile.
|
|
385
403
|
*/
|
|
386
404
|
appliesTo?: string[];
|
|
405
|
+
/**
|
|
406
|
+
* v2 only — what kind of value each bound field holds, so a verifier (or any
|
|
407
|
+
* view) can collect and show it without guessing from the field's name:
|
|
408
|
+
* - `text` — one string (an email body);
|
|
409
|
+
* - `list` — an array of strings (recipients);
|
|
410
|
+
* - `files` — the sealed fingerprints of documents sent by reference:
|
|
411
|
+
* `[{ filename, sha256 }]` — never the bytes. A verifier asks for the
|
|
412
|
+
* files themselves and computes each SHA-256 locally.
|
|
413
|
+
*
|
|
414
|
+
* A hint only: it never changes what is hashed. Keys MUST be a subset of
|
|
415
|
+
* {@link fields}; a field without an entry is unspecified (a verifier may
|
|
416
|
+
* offer a choice, as before).
|
|
417
|
+
*/
|
|
418
|
+
field_kinds?: Record<string, ContentFieldKind>;
|
|
387
419
|
}
|
|
420
|
+
/** See {@link ContentBinding.field_kinds}. */
|
|
421
|
+
type ContentFieldKind = 'text' | 'list' | 'files';
|
|
388
422
|
/**
|
|
389
423
|
* Scope field definition within a profile (renamed from `ProfileContextField`
|
|
390
424
|
* in v0.7 — protocol.md → *Migration from v0.6*, `contextSchema` → `scopeSchema`).
|
|
@@ -447,6 +481,8 @@ type ExecutionContextFieldDef = DeclaredFieldDef | CumulativeFieldDef;
|
|
|
447
481
|
* is not chosen by the signer — it follows from team caps.)
|
|
448
482
|
*/
|
|
449
483
|
type SignableCommitmentMode = 'automatic' | 'review';
|
|
484
|
+
/** Every commitment mode a signed mandate can carry. */
|
|
485
|
+
type CommitmentMode = SignableCommitmentMode | 'review_above_cap';
|
|
450
486
|
/** protocol.md → *Owner Signatures* → "Where the requirement lives" — the
|
|
451
487
|
* profile-floor tier: `minBinding` names the weakest `OwnerSignatureBinding`
|
|
452
488
|
* this profile accepts for a co-signing owner. */
|
|
@@ -501,8 +537,13 @@ interface AgentProfile {
|
|
|
501
537
|
* a mandate screen offers only the listed modes. Fail-closed: a declared
|
|
502
538
|
* list with no valid entry allows nothing — a malformed declaration never
|
|
503
539
|
* widens what a profile allows. See {@link allowedCommitmentModes}.
|
|
540
|
+
*
|
|
541
|
+
* v0.8 (Commitment Modes, rule 8): `review_above_cap` is admitted if and
|
|
542
|
+
* only if `automatic` is listed; an entry `review_above_cap` in the list is
|
|
543
|
+
* ignored, and a list whose only entry is it admits nothing and is
|
|
544
|
+
* malformed (`PROFILE_INVALID`).
|
|
504
545
|
*/
|
|
505
|
-
commitment_modes?: readonly
|
|
546
|
+
commitment_modes?: readonly CommitmentMode[];
|
|
506
547
|
/**
|
|
507
548
|
* The bounds schema — the enforceable parameters (protocol.md → *Bounds
|
|
508
549
|
* Schema*).
|
|
@@ -652,39 +693,6 @@ type GatekeeperResult = {
|
|
|
652
693
|
errors: GatekeeperError[];
|
|
653
694
|
};
|
|
654
695
|
|
|
655
|
-
/**
|
|
656
|
-
* JCS — JSON Canonicalization (RFC 8785) for signing.
|
|
657
|
-
*
|
|
658
|
-
* Both attestation and receipt signatures are computed over a canonical byte
|
|
659
|
-
* serialization of the payload, so that two independent implementations (an AS,
|
|
660
|
-
* a gateway, an external verifier — in any language) agree on exactly which
|
|
661
|
-
* bytes were signed regardless of how they happened to construct the object.
|
|
662
|
-
*
|
|
663
|
-
* `JSON.stringify` is NOT sufficient: it preserves key *insertion* order, so the
|
|
664
|
-
* same logical payload built with keys in a different order serializes to
|
|
665
|
-
* different bytes and the signature fails to verify. Canonicalization removes
|
|
666
|
-
* that dependency by sorting keys.
|
|
667
|
-
*
|
|
668
|
-
* This is RFC 8785-compatible and matches the v0.5 spec's normative signing
|
|
669
|
-
* canonicalization (core.md "Signing Canonicalization"):
|
|
670
|
-
* 1. UTF-8.
|
|
671
|
-
* 2. Object keys sorted (RFC 8785 sorts by UTF-16 code units — exactly what
|
|
672
|
-
* JavaScript's default String comparison does, so `Object.keys().sort()` is
|
|
673
|
-
* correct here).
|
|
674
|
-
* 3. No insignificant whitespace.
|
|
675
|
-
* 4. Numbers in the shortest round-trippable form — the ECMAScript
|
|
676
|
-
* Number-to-String algorithm, which `JSON.stringify(number)` produces and
|
|
677
|
-
* RFC 8785 adopts verbatim.
|
|
678
|
-
* 5. Strings escaped per RFC 8259; non-ASCII passed through as UTF-8 (this is
|
|
679
|
-
* `JSON.stringify`'s behaviour for strings).
|
|
680
|
-
* 6. Array order preserved.
|
|
681
|
-
*
|
|
682
|
-
* Because it relies only on `JSON.stringify` for leaves plus `Object.keys`,
|
|
683
|
-
* `Array`, and `String` sort — all of which are environment-independent in
|
|
684
|
-
* JavaScript — Node and the browser produce byte-identical output. The
|
|
685
|
-
* conformance test pins a (payload → canonical bytes) vector that any other
|
|
686
|
-
* implementation can check against.
|
|
687
|
-
*/
|
|
688
696
|
declare function canonicalize(value: unknown): string;
|
|
689
697
|
|
|
690
698
|
/**
|
|
@@ -712,20 +720,31 @@ declare function toBase64Url(bytes: Uint8Array): string;
|
|
|
712
720
|
*/
|
|
713
721
|
declare function fromBase64Url(s: string): Uint8Array;
|
|
714
722
|
|
|
715
|
-
/** The protocol version this package issues
|
|
716
|
-
declare const PROTOCOL_VERSION = "0.
|
|
717
|
-
/**
|
|
723
|
+
/** The protocol version this package issues. */
|
|
724
|
+
declare const PROTOCOL_VERSION = "0.8";
|
|
725
|
+
/** Every version this package verifies and enforces, newest first. */
|
|
718
726
|
declare const SUPPORTED_VERSIONS: readonly string[];
|
|
727
|
+
/** The versions an Authority Server built on this package issues. */
|
|
728
|
+
declare const ISSUABLE_VERSIONS: readonly string[];
|
|
729
|
+
/** A protocol version this package knows the rules of. */
|
|
730
|
+
type SupportedVersion = '0.8' | '0.7';
|
|
731
|
+
declare function isSupportedVersion(v: unknown): v is SupportedVersion;
|
|
719
732
|
/**
|
|
720
|
-
* The highest version both the requester and
|
|
733
|
+
* The highest version both the requester and the issuer support.
|
|
721
734
|
*
|
|
722
735
|
* @param requested `supported_versions` from the mandate request. Absent →
|
|
723
|
-
* read as `["0.6"]` (protocol.md rule 1)
|
|
724
|
-
*
|
|
725
|
-
*
|
|
736
|
+
* read as `["0.6"]` (protocol.md rule 1), which no issuer here supports, so
|
|
737
|
+
* the refusal is honest rather than a silent assumption.
|
|
738
|
+
* @param supported What the issuer is willing to issue. Default: v0.8 only.
|
|
726
739
|
* @throws HapError `VERSION_UNSUPPORTED` when no version is common to both.
|
|
727
740
|
*/
|
|
728
741
|
declare function negotiateVersion(requested: readonly string[] | undefined, supported?: readonly string[]): string;
|
|
742
|
+
/**
|
|
743
|
+
* Refuse an artifact of a version this package cannot verify (rule 4: an
|
|
744
|
+
* artifact is read under its own version, never re-interpreted).
|
|
745
|
+
* @throws HapError `VERSION_UNSUPPORTED`
|
|
746
|
+
*/
|
|
747
|
+
declare function assertSupportedVersion(version: unknown, what: string): asserts version is SupportedVersion;
|
|
729
748
|
|
|
730
749
|
/**
|
|
731
750
|
* Content binding — Level 2 content proof (HAP v0.5 Content Provenance).
|
|
@@ -831,6 +850,14 @@ declare function selectBoundFields(binding: ContentBinding, args: Record<string,
|
|
|
831
850
|
* {@link selectBoundFields} + {@link computeContentHash} for the common path.
|
|
832
851
|
*/
|
|
833
852
|
declare function computeFieldsContentHash(binding: ContentBinding, args: Record<string, unknown>): string;
|
|
853
|
+
/**
|
|
854
|
+
* Why a binding's `field_kinds` is malformed, or null when it is fine (or
|
|
855
|
+
* absent). For profile validation — a malformed hint is a profile error, not
|
|
856
|
+
* a call-time refusal, because it never changes what is hashed.
|
|
857
|
+
*/
|
|
858
|
+
declare function invalidFieldKindsReason(binding: ContentBinding): string | null;
|
|
859
|
+
/** The bound fields declared as `files` — sealed document fingerprints. */
|
|
860
|
+
declare function filesFields(binding: ContentBinding): string[];
|
|
834
861
|
|
|
835
862
|
/**
|
|
836
863
|
* Intent hashing + intent-disclosure binding (HAP v0.5).
|
|
@@ -1019,20 +1046,29 @@ declare function computeScopeHash(params: AgentScopeParams, profile: AgentProfil
|
|
|
1019
1046
|
|
|
1020
1047
|
/**
|
|
1021
1048
|
* Which commitment modes a profile allows its mandates to be signed with
|
|
1022
|
-
* (`AgentProfile.commitment_modes
|
|
1023
|
-
*
|
|
1049
|
+
* (`AgentProfile.commitment_modes`; protocol.md → *Commitment Modes*, rule
|
|
1050
|
+
* 8). One source for the Authority Server's refusal and the mandate screen's
|
|
1051
|
+
* choice, so the two cannot disagree.
|
|
1024
1052
|
*/
|
|
1025
1053
|
|
|
1026
1054
|
/** Every mode a signer can choose, in the order a mandate screen shows them. */
|
|
1027
1055
|
declare const SIGNABLE_COMMITMENT_MODES: readonly SignableCommitmentMode[];
|
|
1056
|
+
/** Every mode a signed mandate can carry. */
|
|
1057
|
+
declare const COMMITMENT_MODES: readonly CommitmentMode[];
|
|
1028
1058
|
/**
|
|
1029
|
-
* The modes a mandate under this profile may carry, in display
|
|
1030
|
-
* No declaration → all of them. A declaration is read fail-closed:
|
|
1031
|
-
* that are not a signable mode are dropped
|
|
1032
|
-
*
|
|
1059
|
+
* The signable modes a mandate under this profile may carry, in display
|
|
1060
|
+
* order. No declaration → all of them. A declaration is read fail-closed:
|
|
1061
|
+
* entries that are not a signable mode are dropped (`review_above_cap` is
|
|
1062
|
+
* ignored by rule 8 — it follows from `automatic`), so a malformed list can
|
|
1063
|
+
* only narrow — `[]`, `"review"` (not a list) or `["reveiw"]` allow nothing.
|
|
1033
1064
|
*/
|
|
1034
1065
|
declare function allowedCommitmentModes(profile: AgentProfile): readonly SignableCommitmentMode[];
|
|
1035
|
-
/**
|
|
1066
|
+
/**
|
|
1067
|
+
* Whether a mandate under this profile may be SIGNED with `mode` (rule 8):
|
|
1068
|
+
* `automatic` and `review` where listed; `review_above_cap` if and only if
|
|
1069
|
+
* `automatic` is admitted. The Authority Server refuses any other with
|
|
1070
|
+
* `COMMITMENT_MODE_NOT_ALLOWED`.
|
|
1071
|
+
*/
|
|
1036
1072
|
declare function isCommitmentModeAllowed(profile: AgentProfile, mode: string): boolean;
|
|
1037
1073
|
|
|
1038
1074
|
/** One authoring-time finding. `code` is always a canonical v0.7 code — in
|
|
@@ -1073,9 +1109,10 @@ declare function checkDiscloseSubset(mandateDiscloseFields: readonly string[] |
|
|
|
1073
1109
|
* Renamed from `attestation.ts` (protocol.md → *Migration from v0.6*:
|
|
1074
1110
|
* `header.typ: "HAP-attestation"` → `"HAP-mandate"`, `attestation_id` →
|
|
1075
1111
|
* `mandate_id`). v0.3's frame-hash path and v0.4's dual frame/bounds
|
|
1076
|
-
* verification are retired with the rest of pre-v0.5
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1112
|
+
* verification are retired with the rest of pre-v0.5. This module issues
|
|
1113
|
+
* `version: "0.8"` mandates and verifies `"0.8"` and `"0.7"` ones, each
|
|
1114
|
+
* under its own rules (protocol.md → *Version negotiation*, rule 4): v0.8
|
|
1115
|
+
* is a re-grant release, and a v0.7 artifact stays verifiable as evidence.
|
|
1079
1116
|
*/
|
|
1080
1117
|
|
|
1081
1118
|
/**
|
|
@@ -1135,15 +1172,25 @@ declare function checkMandateExpiry(payload: MandatePayload, now?: number): void
|
|
|
1135
1172
|
* violation; `OWNER_SIGNATURE_INVALID` when a co-signing DID is not key-bearing.
|
|
1136
1173
|
*/
|
|
1137
1174
|
declare function validateMandateOwners(payload: MandatePayload): void;
|
|
1175
|
+
/**
|
|
1176
|
+
* The above-cap fields travel together (Mandate rule 10; *Group roles*,
|
|
1177
|
+
* rule 7). Under v0.8 `above_cap_approvals` is present exactly when
|
|
1178
|
+
* `above_cap_approvers` is, an integer ≥ 1; under v0.7 there is no count and
|
|
1179
|
+
* caps + approvers are present exactly under `review_above_cap`.
|
|
1180
|
+
*
|
|
1181
|
+
* @throws HapError `MALFORMED_MANDATE`
|
|
1182
|
+
*/
|
|
1183
|
+
declare function validateAboveCapFields(payload: MandatePayload): void;
|
|
1138
1184
|
/**
|
|
1139
1185
|
* Full mandate verification: decode, check `version`, verify the AS
|
|
1140
|
-
* signature, check expiry, validate `mandate_owners` shape
|
|
1186
|
+
* signature, check expiry, validate `mandate_owners` shape and the above-cap
|
|
1187
|
+
* fields.
|
|
1141
1188
|
*
|
|
1142
1189
|
* Deliberately does NOT verify any `mandate_owners` co-signature — that is
|
|
1143
1190
|
* `verifyOwnerSignature` in `owner-signature.ts`, a separate trust axis the
|
|
1144
1191
|
* caller opts into.
|
|
1145
1192
|
*
|
|
1146
|
-
* @throws HapError `VERSION_UNSUPPORTED` for
|
|
1193
|
+
* @throws HapError `VERSION_UNSUPPORTED` for a version outside {@link SUPPORTED_VERSIONS}.
|
|
1147
1194
|
* @throws Error (`INVALID_SIGNATURE:` / `TTL_EXPIRED:` / `MALFORMED_MANDATE:`
|
|
1148
1195
|
* prefixed, or `OWNER_SIGNATURE_INVALID` as a HapError) on any other failure.
|
|
1149
1196
|
*/
|
|
@@ -1153,13 +1200,9 @@ declare function verifyMandate(blob: string, opts?: {
|
|
|
1153
1200
|
}): Promise<MandatePayload>;
|
|
1154
1201
|
|
|
1155
1202
|
/**
|
|
1156
|
-
* Owner Signatures
|
|
1157
|
-
* `HAP-approval` object, and their verification.
|
|
1158
|
-
*
|
|
1159
|
-
* Renamed from `mandate.ts` (protocol.md → *Migration from v0.6*: the
|
|
1160
|
-
* owner-signed projection's `typ` moves from `"HAP-mandate"` to
|
|
1161
|
-
* `"HAP-mandate-projection"`, disambiguating it from the AS-signed mandate
|
|
1162
|
-
* itself, which now legitimately owns the name `"HAP-mandate"`).
|
|
1203
|
+
* Owner Signatures — the `HAP-mandate-projection` object, the
|
|
1204
|
+
* `HAP-approval` object, and their verification (v0.8; v0.7 artifacts
|
|
1205
|
+
* verified under their own field lists).
|
|
1163
1206
|
*
|
|
1164
1207
|
* The human signs BEFORE the AS does, so they cannot sign the finished
|
|
1165
1208
|
* mandate (`mandate_id`/`issued_at` do not exist yet). They sign a mandate
|
|
@@ -1169,6 +1212,13 @@ declare function verifyMandate(blob: string, opts?: {
|
|
|
1169
1212
|
* with the key carried in the owner's DID. No side channel, no second
|
|
1170
1213
|
* fetch, no key directory. See protocol.md → "Owner Signatures".
|
|
1171
1214
|
*
|
|
1215
|
+
* v0.8 adds to the projection what a compromised AS could otherwise restate:
|
|
1216
|
+
* `binding` and `signing_surface` (how the owner signed), `subjects_disclosed`
|
|
1217
|
+
* (whether the name is attached), and `above_cap_approvals` (how many
|
|
1218
|
+
* approvers). The approval gains `approver_did` (who decided) and the
|
|
1219
|
+
* operation it is for (`action`, `action_type`), and always signs the
|
|
1220
|
+
* proposal's content fingerprint beside the bound subset.
|
|
1221
|
+
*
|
|
1172
1222
|
* Verification here requires NO trust in the AS. What it cannot do is tell
|
|
1173
1223
|
* the verifier WHOSE key signed — confirming the DID belongs to the
|
|
1174
1224
|
* expected person is the out-of-band step (protocol.md → "Verification
|
|
@@ -1182,7 +1232,7 @@ declare function verifyMandate(blob: string, opts?: {
|
|
|
1182
1232
|
interface MandateProjection {
|
|
1183
1233
|
typ: 'HAP-mandate-projection';
|
|
1184
1234
|
/** Projection/canonicalization version. A verifier MUST pin it. */
|
|
1185
|
-
version:
|
|
1235
|
+
version: ProtocolVersion;
|
|
1186
1236
|
profile_id: string;
|
|
1187
1237
|
/** Covered deliberately: the owner signs the profile's BYTES, not only its id. */
|
|
1188
1238
|
profile_hash: string;
|
|
@@ -1195,29 +1245,46 @@ interface MandateProjection {
|
|
|
1195
1245
|
/** Included iff the mandate carries one — binds ciphertext AND the
|
|
1196
1246
|
* frozen approver set, the swap this mechanism exists to stop. */
|
|
1197
1247
|
intent_disclosure_hash?: string;
|
|
1198
|
-
commitment_mode:
|
|
1199
|
-
/** Included together, iff
|
|
1248
|
+
commitment_mode: CommitmentMode;
|
|
1249
|
+
/** Included together, iff the mandate carries them (v0.8: under
|
|
1250
|
+
* `review_above_cap`, or `review` in a group with approval-kind caps;
|
|
1251
|
+
* v0.7: under `review_above_cap`). */
|
|
1200
1252
|
above_cap_caps?: Record<string, number>;
|
|
1201
1253
|
above_cap_approvers?: string[];
|
|
1254
|
+
/** v0.8 only, with the other two. */
|
|
1255
|
+
above_cap_approvals?: number;
|
|
1202
1256
|
/** Included iff the mandate narrows the profile's disclose_fields. */
|
|
1203
1257
|
disclose_fields?: string[];
|
|
1204
1258
|
/** The replay defence: the human signs how long the authority lives. */
|
|
1205
1259
|
expires_at: number;
|
|
1206
1260
|
nonce: string;
|
|
1261
|
+
/** v0.8, always present: MUST equal the `mandate_owners` entry's values. */
|
|
1262
|
+
binding?: OwnerSignatureBinding | string;
|
|
1263
|
+
signing_surface?: SigningSurface | string;
|
|
1264
|
+
/** v0.8, always present: `true` exactly when the mandate carries a
|
|
1265
|
+
* `subjects` entry for the owner. */
|
|
1266
|
+
subjects_disclosed?: boolean;
|
|
1207
1267
|
}
|
|
1208
|
-
/** Per-action approval, signed by the
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1268
|
+
/** Per-action approval, signed by the decider. Signing a `reject` matters as
|
|
1269
|
+
* much as a `commit`: a rejection the AS can discard is a rejection that
|
|
1270
|
+
* never happened. */
|
|
1211
1271
|
interface ApprovalObject {
|
|
1212
1272
|
typ: 'HAP-approval';
|
|
1213
|
-
version:
|
|
1273
|
+
version: ProtocolVersion;
|
|
1274
|
+
/** v0.8 — who decided: the Mandate Owner in `review`, or an above-cap approver. */
|
|
1275
|
+
approver_did?: string;
|
|
1214
1276
|
proposal_id: string;
|
|
1215
|
-
/** Renamed from `attestation_id` in v0.7. */
|
|
1216
1277
|
mandate_id: string;
|
|
1278
|
+
/** v0.8 — the operation the arguments are for, exactly as the ticket carries them. */
|
|
1279
|
+
action?: string;
|
|
1280
|
+
action_type?: string;
|
|
1217
1281
|
decision: 'commit' | 'reject';
|
|
1218
|
-
/**
|
|
1219
|
-
*
|
|
1282
|
+
/** The ticket's contentHash where a content binding applies to the action;
|
|
1283
|
+
* otherwise equal to `proposal_content_hash` (v0.8) / the JCS hash of the
|
|
1284
|
+
* proposal's arguments (v0.7). */
|
|
1220
1285
|
content_hash: string;
|
|
1286
|
+
/** v0.8, always present — the proposal's content fingerprint. */
|
|
1287
|
+
proposal_content_hash?: string;
|
|
1221
1288
|
decided_at: number;
|
|
1222
1289
|
nonce: string;
|
|
1223
1290
|
}
|
|
@@ -1228,15 +1295,13 @@ declare class OwnerSignatureError extends Error {
|
|
|
1228
1295
|
}
|
|
1229
1296
|
/**
|
|
1230
1297
|
* Rebuild the projection a given `mandate_owners` entry signed, from the
|
|
1231
|
-
* mandate's own signed fields
|
|
1232
|
-
*
|
|
1233
|
-
* `disclose_fields` are included iff the mandate carries them.
|
|
1298
|
+
* mandate's own signed fields, under the mandate's own `version`. Field
|
|
1299
|
+
* absence is defined, not incidental.
|
|
1234
1300
|
*/
|
|
1235
|
-
declare function buildMandateProjection(payload: MandatePayload, entry: Pick<MandateOwnerEntry, 'did' | 'nonce'>): MandateProjection;
|
|
1236
|
-
/** The exact bytes an owner signs: RFC 8785 (JCS) canonical UTF-8.
|
|
1237
|
-
* from `mandateSigningBytes` in v0.7. */
|
|
1301
|
+
declare function buildMandateProjection(payload: MandatePayload, entry: Pick<MandateOwnerEntry, 'did' | 'nonce' | 'binding' | 'signing_surface'>): MandateProjection;
|
|
1302
|
+
/** The exact bytes an owner signs: RFC 8785 (JCS) canonical UTF-8. */
|
|
1238
1303
|
declare function projectionSigningBytes(projection: MandateProjection): Uint8Array;
|
|
1239
|
-
/** The exact bytes
|
|
1304
|
+
/** The exact bytes a decider signs for a per-action approval. */
|
|
1240
1305
|
declare function approvalSigningBytes(approval: ApprovalObject): Uint8Array;
|
|
1241
1306
|
/**
|
|
1242
1307
|
* Sign a mandate projection with a raw Ed25519 private key — the `raw`
|
|
@@ -1267,35 +1332,45 @@ declare function verifyOwnerSignature(mandate: Mandate, entry: MandateOwnerEntry
|
|
|
1267
1332
|
declare function verifyOwnerSignatures(mandate: Mandate): Promise<MandateOwnerEntry[]>;
|
|
1268
1333
|
/** Verify an approval signature against a signer's key-bearing DID. */
|
|
1269
1334
|
declare function verifyApproval(approval: ApprovalObject, signature: string, signerDid: string): Promise<void>;
|
|
1335
|
+
/** Signature-assurance ranking for `OwnerSignatureBinding`, weakest first —
|
|
1336
|
+
* protocol.md → *Owner Signatures* → "binding" table ordering (raw < webauthn < eudi).
|
|
1337
|
+
* A binding the verifier does not know ranks as `raw` (satisfies no minimum
|
|
1338
|
+
* above it). */
|
|
1339
|
+
declare const BINDING_RANK: Record<OwnerSignatureBinding, number>;
|
|
1340
|
+
declare function bindingRank(binding: string | undefined): number;
|
|
1270
1341
|
/**
|
|
1271
1342
|
* Enforce a profile's `ownerSignature` floor (protocol.md → *Owner
|
|
1272
1343
|
* Signatures* → "Where the requirement lives" — the profile-floor tier,
|
|
1273
1344
|
* checkable without trusting the AS: `profile_id`/`profile_hash` are in the
|
|
1274
1345
|
* signed payload AND in the owner-signed projection).
|
|
1275
1346
|
*
|
|
1276
|
-
* An unknown `binding` value is treated as rank 0 (weakest) rather than
|
|
1277
|
-
* rejected outright — "an AS MUST NOT reject a mandate_owners entry solely
|
|
1278
|
-
* because it does not recognize its binding value" extends naturally to a
|
|
1279
|
-
* verifier ranking it, since crediting an unrecognized binding with
|
|
1280
|
-
* unearned strength would be the more dangerous failure mode.
|
|
1281
|
-
*
|
|
1282
1347
|
* @throws OwnerSignatureError `OWNER_SIGNATURE_REQUIRED` when the floor is
|
|
1283
1348
|
* unmet — "MUST fail, not warn" (protocol.md, same section).
|
|
1284
1349
|
*/
|
|
1285
1350
|
declare function checkOwnerSignatureRequirement(payload: MandatePayload, floor: ProfileOwnerSignatureFloor | undefined): void;
|
|
1286
1351
|
|
|
1287
1352
|
/**
|
|
1288
|
-
* Mandate tickets
|
|
1289
|
-
*
|
|
1290
|
-
* "v0.4 introduced the object under the name execution receipt; v0.7 renames
|
|
1291
|
-
* it because the tense was wrong — a receipt follows payment, and the ticket
|
|
1292
|
-
* must come first").
|
|
1353
|
+
* Mandate tickets — the wire type, signing, holder-side verification, and
|
|
1354
|
+
* (v0.8) the Gatekeeper's check that a ticket answers the request it sent.
|
|
1293
1355
|
*
|
|
1294
1356
|
* Ticket payloads are camelCase on the wire (unlike the snake_case mandate
|
|
1295
1357
|
* payload) — a shipped inconsistency the spec documents rather than breaks
|
|
1296
1358
|
* (protocol.md → *Migration from v0.6*, "Unchanged on purpose").
|
|
1297
1359
|
*/
|
|
1298
1360
|
|
|
1361
|
+
/** Clock-skew tolerance and freshness window (Mandate rule 9; Ticket rule 4). */
|
|
1362
|
+
declare const TICKET_FRESHNESS_SECONDS = 300;
|
|
1363
|
+
/** One verified approval carried by a ticket. */
|
|
1364
|
+
interface ApprovalSignatureEntry {
|
|
1365
|
+
alg: 'EdDSA' | 'ES256';
|
|
1366
|
+
signature: string;
|
|
1367
|
+
nonce: string;
|
|
1368
|
+
decided_at: number;
|
|
1369
|
+
}
|
|
1370
|
+
/** v0.8 — an above-cap approver's entry in `approvalSignatures`. */
|
|
1371
|
+
interface ApproverSignatureEntry extends ApprovalSignatureEntry {
|
|
1372
|
+
approver_did: string;
|
|
1373
|
+
}
|
|
1299
1374
|
/** Signed mandate ticket — protocol.md → *Ticket Payload Schema*. */
|
|
1300
1375
|
interface TicketPayload {
|
|
1301
1376
|
id: string;
|
|
@@ -1321,6 +1396,10 @@ interface TicketPayload {
|
|
|
1321
1396
|
/** The AS DID, as in the mandate (new in v0.7). */
|
|
1322
1397
|
issuer: string;
|
|
1323
1398
|
timestamp: number;
|
|
1399
|
+
/** v0.8 — copied verbatim from the request, so the ticket names the single
|
|
1400
|
+
* request it answers. Present exactly when the request carried one
|
|
1401
|
+
* (synchronous path). */
|
|
1402
|
+
idempotencyKey?: string;
|
|
1324
1403
|
/** Hash of the bound content, computed by the Gatekeeper, copied
|
|
1325
1404
|
* verbatim by the AS. The AS never sees the content. */
|
|
1326
1405
|
contentHash?: string;
|
|
@@ -1331,15 +1410,15 @@ interface TicketPayload {
|
|
|
1331
1410
|
subjects?: Subject[];
|
|
1332
1411
|
/** Review path: the proposal this ticket executed. */
|
|
1333
1412
|
proposalId?: string;
|
|
1413
|
+
/** v0.8, review path: the proposal's content fingerprint, copied verbatim
|
|
1414
|
+
* from the proposal the AS compared it against. */
|
|
1415
|
+
proposalContentHash?: string;
|
|
1334
1416
|
/** Review path: the owner's HAP-approval signature for the executed
|
|
1335
1417
|
* proposal, as the object itself — never a hash of it, which a holder
|
|
1336
1418
|
* could check only by asking the AS. */
|
|
1337
|
-
approvalSignature?:
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
nonce: string;
|
|
1341
|
-
decided_at: number;
|
|
1342
|
-
};
|
|
1419
|
+
approvalSignature?: ApprovalSignatureEntry;
|
|
1420
|
+
/** v0.8, above-cap path: one entry per approver signature the AS verified. */
|
|
1421
|
+
approvalSignatures?: ApproverSignatureEntry[];
|
|
1343
1422
|
/** Ed25519 over the JCS-canonical payload (this field excluded), base64url. */
|
|
1344
1423
|
signature: string;
|
|
1345
1424
|
}
|
|
@@ -1348,42 +1427,431 @@ interface TicketPayload {
|
|
|
1348
1427
|
* the same key used for mandates.
|
|
1349
1428
|
*/
|
|
1350
1429
|
declare function signTicket(payload: Omit<TicketPayload, 'signature'>, privateKey: Uint8Array): Promise<TicketPayload>;
|
|
1430
|
+
/**
|
|
1431
|
+
* The structural rules that keep a ticket, a projection and a mandate
|
|
1432
|
+
* payload apart (protocol.md → *Ticket Payload Schema*, "Signature"): a
|
|
1433
|
+
* ticket verifier MUST require `id`, `mandateId`, `actionType`, `timestamp`
|
|
1434
|
+
* and `issuer`, MUST reject an object carrying `typ` (a projection can never
|
|
1435
|
+
* be accepted as a ticket), and MUST reject `mandate_id` or `issued_at`.
|
|
1436
|
+
* @throws HapError `INVALID_SIGNATURE`
|
|
1437
|
+
*/
|
|
1438
|
+
declare function assertTicketShape(ticket: Record<string, unknown>): void;
|
|
1351
1439
|
/**
|
|
1352
1440
|
* Verify a ticket's AS signature: strip `signature`, JCS-canonicalize the
|
|
1353
1441
|
* rest, Ed25519-verify against the key resolved from `issuer` — never
|
|
1354
1442
|
* against a key offered alongside the ticket (protocol.md → *Ticket
|
|
1355
1443
|
* Verification* step 1). This is holder-side verification — it needs the
|
|
1356
1444
|
* COMPLETE ticket; a redacted public view cannot be re-verified this way
|
|
1357
|
-
* (see
|
|
1445
|
+
* (see `ticket-projection.ts` for the view that can).
|
|
1358
1446
|
*
|
|
1359
1447
|
* Content is checked separately: where `contentHash` is present, recompute
|
|
1360
1448
|
* it from the held artifact via the content-binding module and compare.
|
|
1361
1449
|
*
|
|
1362
1450
|
* @param opts.trustedIssuers When supplied, an `issuer` not in this list is
|
|
1363
1451
|
* rejected before any cryptography runs.
|
|
1364
|
-
* @throws
|
|
1452
|
+
* @throws HapError `INVALID_SIGNATURE` when verification fails;
|
|
1453
|
+
* `VERSION_UNSUPPORTED` for a version this package cannot read.
|
|
1365
1454
|
*/
|
|
1366
1455
|
declare function verifyTicketSignature(ticket: TicketPayload, opts?: {
|
|
1367
1456
|
trustedIssuers?: readonly string[];
|
|
1368
1457
|
}): Promise<void>;
|
|
1458
|
+
/** The fields of a ticket request a Gatekeeper compares with the ticket it
|
|
1459
|
+
* receives (protocol.md → *Ticket Payload Schema*, rule 4). */
|
|
1460
|
+
interface TicketRequestEcho {
|
|
1461
|
+
profileId: string;
|
|
1462
|
+
actionType: string;
|
|
1463
|
+
boundsHash: string;
|
|
1464
|
+
executionContext: Record<string, unknown>;
|
|
1465
|
+
mandateId?: string;
|
|
1466
|
+
idempotencyKey?: string;
|
|
1467
|
+
contentHash?: string;
|
|
1468
|
+
contentBinding?: TicketPayload['contentBinding'];
|
|
1469
|
+
proposalId?: string;
|
|
1470
|
+
proposalContentHash?: string;
|
|
1471
|
+
}
|
|
1369
1472
|
/**
|
|
1370
|
-
*
|
|
1371
|
-
*
|
|
1372
|
-
* `
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1473
|
+
* v0.8 — the Gatekeeper's half of "a ticket names the request it answers":
|
|
1474
|
+
* every echoed field equals what was sent, the `idempotencyKey` it sent is
|
|
1475
|
+
* the one the ticket carries, `mandateId` and `version` are the verified
|
|
1476
|
+
* mandate's, and a fresh ticket's `timestamp` lies within
|
|
1477
|
+
* {@link TICKET_FRESHNESS_SECONDS}. A replay (`idempotent: true`, unsigned)
|
|
1478
|
+
* is exempt from freshness only; the caller passes `replay: true` and then
|
|
1479
|
+
* applies *One execution per ticket*, rule 2.
|
|
1375
1480
|
*
|
|
1376
|
-
*
|
|
1377
|
-
*
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1481
|
+
* Does NOT verify the signature — call {@link verifyTicketSignature} first.
|
|
1482
|
+
* @throws HapError `TICKET_REQUEST_MISMATCH`
|
|
1483
|
+
*/
|
|
1484
|
+
declare function verifyTicketAgainstRequest(ticket: TicketPayload, request: TicketRequestEcho, opts?: {
|
|
1485
|
+
mandate?: Mandate;
|
|
1486
|
+
now?: number;
|
|
1487
|
+
replay?: boolean;
|
|
1488
|
+
}): void;
|
|
1489
|
+
/**
|
|
1490
|
+
* Rebuild the `HAP-approval` a decider signed, from the ticket and the
|
|
1491
|
+
* mandate it names (protocol.md → *Ticket Payload Schema*, `approvalSignature`):
|
|
1492
|
+
* `typ` and `version`; `proposal_id` and `mandate_id` from `proposalId` and
|
|
1493
|
+
* `mandateId`; `action` and `action_type` (v0.8) from `action` and
|
|
1494
|
+
* `actionType`; `proposal_content_hash` from `proposalContentHash`;
|
|
1495
|
+
* `content_hash` from `contentHash` where a binding applies to this action
|
|
1496
|
+
* (the AS copies one only then), else `proposalContentHash`; `decision`
|
|
1497
|
+
* `"commit"`; `approver_did` as given; `decided_at` and `nonce` from the
|
|
1498
|
+
* entry.
|
|
1499
|
+
*/
|
|
1500
|
+
declare function reconstructApproval(ticket: TicketPayload, entry: ApprovalSignatureEntry, approverDid: string): ApprovalObject;
|
|
1501
|
+
/** What a ticket's approvals, once verified, establish. */
|
|
1502
|
+
interface VerifiedApprovals {
|
|
1503
|
+
/** The Mandate Owner's DID, when `approvalSignature` verified. */
|
|
1504
|
+
owner?: string;
|
|
1505
|
+
/** Distinct above-cap approver DIDs whose `approvalSignatures` entries verified. */
|
|
1506
|
+
approvers: string[];
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Verify every approval a ticket carries against the mandate it names
|
|
1510
|
+
* (protocol.md → *Ticket Payload Schema*, rule 4): `approvalSignature`
|
|
1511
|
+
* under the Mandate Owner's DID; each `approvalSignatures` entry under its
|
|
1512
|
+
* `approver_did`, which MUST be in the signed `above_cap_approvers` and
|
|
1513
|
+
* MUST NOT be the Mandate Owner (the proposer never counts). Whether the
|
|
1514
|
+
* verified set is ENOUGH is {@link approvalsSufficient}, so a verifier can
|
|
1515
|
+
* report what it found and a policy can decide.
|
|
1516
|
+
*
|
|
1517
|
+
* @throws HapError `APPROVAL_SIGNATURE_INVALID`
|
|
1518
|
+
*/
|
|
1519
|
+
declare function verifyTicketApprovals(ticket: TicketPayload, mandate: Mandate): Promise<VerifiedApprovals>;
|
|
1520
|
+
/**
|
|
1521
|
+
* Whether the verified approvals satisfy what the mandate requires for a
|
|
1522
|
+
* decision above a cap: at least `above_cap_approvals` distinct approvers
|
|
1523
|
+
* (v0.7: every signed approver), plus the owner's own approval in `review`.
|
|
1524
|
+
*/
|
|
1525
|
+
declare function approvalsSufficient(mandate: Mandate, verified: VerifiedApprovals, aboveCap: boolean): boolean;
|
|
1526
|
+
/**
|
|
1527
|
+
* A redacted public view of a ticket (protocol.md → *Ticket Disclosure Is
|
|
1528
|
+
* Declared*). Hides `userId`, `cumulativeState`, and `limits`, and narrows
|
|
1529
|
+
* `executionContext` to the governing `disclose_fields`. NOT independently
|
|
1530
|
+
* re-verifiable — since v0.8 a verifiable public view is the separately
|
|
1531
|
+
* signed `HAP-ticket-projection` (`ticket-projection.ts`); a view that is
|
|
1532
|
+
* not one MUST NOT be presented as independently verified.
|
|
1382
1533
|
*/
|
|
1383
1534
|
declare function publicTicketView(ticket: TicketPayload, governingDiscloseFields?: readonly string[]): Omit<TicketPayload, 'userId' | 'cumulativeState' | 'limits'>;
|
|
1384
1535
|
|
|
1385
1536
|
/**
|
|
1386
|
-
*
|
|
1537
|
+
* Public ticket projection — `HAP-ticket-projection` (protocol.md → *Public
|
|
1538
|
+
* ticket projection*, new in v0.8, specification-led).
|
|
1539
|
+
*
|
|
1540
|
+
* A ticket is one signature over every field, so a redacted view cannot be
|
|
1541
|
+
* re-verified. Where a ticket is shown to parties other than its holder —
|
|
1542
|
+
* a public page, a machine verifier at an effector, an auditor — the AS
|
|
1543
|
+
* serves a public-only subset, separately signed by the same key, so the
|
|
1544
|
+
* public view verifies on its own. It never widens what the ticket
|
|
1545
|
+
* discloses: `executionContext` carries only the governing
|
|
1546
|
+
* `disclose_fields`, and `userId`, `cumulativeState`, `limits` and `action`
|
|
1547
|
+
* never appear.
|
|
1548
|
+
*/
|
|
1549
|
+
|
|
1550
|
+
/** The AS may not let a projection be accepted as authorization later than
|
|
1551
|
+
* this after the ticket's timestamp (rule 3). */
|
|
1552
|
+
declare const PROJECTION_MAX_VALIDITY_SECONDS = 86400;
|
|
1553
|
+
interface TicketProjection {
|
|
1554
|
+
typ: 'HAP-ticket-projection';
|
|
1555
|
+
version: string;
|
|
1556
|
+
id: string;
|
|
1557
|
+
mandateId: string;
|
|
1558
|
+
issuer: string;
|
|
1559
|
+
timestamp: number;
|
|
1560
|
+
/** Set by the AS at projection time; governs acceptance as authorization, not evidence. */
|
|
1561
|
+
valid_until: number;
|
|
1562
|
+
profileId: string;
|
|
1563
|
+
actionType: string;
|
|
1564
|
+
boundsHash: string;
|
|
1565
|
+
contentHash?: string;
|
|
1566
|
+
contentBinding?: TicketPayload['contentBinding'];
|
|
1567
|
+
subjects?: Subject[];
|
|
1568
|
+
/** Exactly the governing `disclose_fields` the ticket carries; absent when none. */
|
|
1569
|
+
executionContext?: Record<string, unknown>;
|
|
1570
|
+
/** The mandate's `mandate_owners` entry, present exactly when it carries a signature. */
|
|
1571
|
+
owner?: MandateOwnerEntry;
|
|
1572
|
+
signature: string;
|
|
1573
|
+
}
|
|
1574
|
+
/**
|
|
1575
|
+
* Build the projection of a ticket (rule 1). `discloseFields` is the
|
|
1576
|
+
* governing list — the mandate's `disclose_fields` where present, else the
|
|
1577
|
+
* profile's; nothing when neither declares one.
|
|
1578
|
+
*/
|
|
1579
|
+
declare function buildTicketProjection(ticket: TicketPayload, mandate: Mandate, opts: {
|
|
1580
|
+
validUntil: number;
|
|
1581
|
+
discloseFields?: readonly string[];
|
|
1582
|
+
}): Omit<TicketProjection, 'signature'>;
|
|
1583
|
+
/** Sign a projection with the key that signed its ticket (rule 2). */
|
|
1584
|
+
declare function signTicketProjection(projection: Omit<TicketProjection, 'signature'>, privateKey: Uint8Array): Promise<TicketProjection>;
|
|
1585
|
+
/**
|
|
1586
|
+
* Verify a projection on its own: `typ` required, signature under the key
|
|
1587
|
+
* `issuer` names. With `asAuthorization`, a projection past `valid_until`
|
|
1588
|
+
* is refused (rule 3); as evidence it is not.
|
|
1589
|
+
* @throws HapError `INVALID_SIGNATURE`, `POLICY_UNMET` (validity window)
|
|
1590
|
+
*/
|
|
1591
|
+
declare function verifyTicketProjection(projection: TicketProjection, opts?: {
|
|
1592
|
+
trustedIssuers?: readonly string[];
|
|
1593
|
+
now?: number;
|
|
1594
|
+
asAuthorization?: boolean;
|
|
1595
|
+
}): Promise<void>;
|
|
1596
|
+
/**
|
|
1597
|
+
* Verify the projection's `owner` entry against the mandate obtained through
|
|
1598
|
+
* the third-party verification API (rule 4): the entry is the mandate's
|
|
1599
|
+
* own, and its signature verifies over the projection rebuilt from the
|
|
1600
|
+
* mandate. The projection alone cannot establish this.
|
|
1601
|
+
* @throws HapError `OWNER_SIGNATURE_INVALID`
|
|
1602
|
+
*/
|
|
1603
|
+
declare function verifyProjectionOwner(projection: TicketProjection, mandate: Mandate): Promise<void>;
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* Verifier policy — `HAP-verifier-policy` (protocol.md → *Owner Signatures*
|
|
1607
|
+
* → *Verifier policy*, new in v0.8, specification-led).
|
|
1608
|
+
*
|
|
1609
|
+
* The relying party's own, declarative statement of what it demands of a
|
|
1610
|
+
* ticket (or projection) before acting on or trusting it. Every present
|
|
1611
|
+
* line is a conjunct; an unmet line is a refusal naming the line and its
|
|
1612
|
+
* code; absent lines impose nothing. The policy is never sent to the
|
|
1613
|
+
* Authority Server.
|
|
1614
|
+
*/
|
|
1615
|
+
|
|
1616
|
+
interface VerifierPolicy {
|
|
1617
|
+
typ: 'HAP-verifier-policy';
|
|
1618
|
+
version: string;
|
|
1619
|
+
trusted_issuers?: string[];
|
|
1620
|
+
min_binding?: OwnerSignatureBinding | string;
|
|
1621
|
+
required_owners?: string[];
|
|
1622
|
+
profile_hashes?: Record<string, string>;
|
|
1623
|
+
action_types?: string[];
|
|
1624
|
+
freshness_seconds?: number;
|
|
1625
|
+
required_fields?: string[];
|
|
1626
|
+
require_approval_signature?: boolean;
|
|
1627
|
+
}
|
|
1628
|
+
/** A refusal naming the policy line that failed. */
|
|
1629
|
+
declare class PolicyError extends HapError {
|
|
1630
|
+
readonly line: keyof VerifierPolicy;
|
|
1631
|
+
constructor(line: keyof VerifierPolicy, code: HapErrorCode, message: string);
|
|
1632
|
+
}
|
|
1633
|
+
interface PolicyInput {
|
|
1634
|
+
/** The complete ticket, where the relying party holds it. */
|
|
1635
|
+
ticket?: TicketPayload;
|
|
1636
|
+
/** Or the projection, where only the public view was served. */
|
|
1637
|
+
projection?: TicketProjection;
|
|
1638
|
+
/** The mandate the artifact chains to, where the policy needs it
|
|
1639
|
+
* (`min_binding`, `required_owners`, `profile_hashes`, `require_approval_signature`). */
|
|
1640
|
+
mandate?: Mandate;
|
|
1641
|
+
now?: number;
|
|
1642
|
+
/** The relying party acts on the artifact (freshness applies to `valid_until`). */
|
|
1643
|
+
asAuthorization?: boolean;
|
|
1644
|
+
/** Whether the ticket's action exceeded an approval-kind cap — known to a
|
|
1645
|
+
* party that holds the mandate's caps and the execution context. */
|
|
1646
|
+
aboveCap?: boolean;
|
|
1647
|
+
}
|
|
1648
|
+
/**
|
|
1649
|
+
* Evaluate a policy (protocol.md → *Verifier policy*, "Evaluation"). The
|
|
1650
|
+
* artifact's own signature is verified first under `trusted_issuers` where
|
|
1651
|
+
* present, else under any resolvable issuer.
|
|
1652
|
+
* @throws PolicyError with the line and the code the table assigns.
|
|
1653
|
+
*/
|
|
1654
|
+
declare function evaluateVerifierPolicy(policy: VerifierPolicy, input: PolicyInput): Promise<void>;
|
|
1655
|
+
|
|
1656
|
+
/**
|
|
1657
|
+
* Proposal content — what the Authority Server receives of a proposal
|
|
1658
|
+
* (protocol.md → *Proposals — what the Authority Server receives*, v0.8).
|
|
1659
|
+
*
|
|
1660
|
+
* The content is the action's argument object, serialized as RFC 8785 JCS.
|
|
1661
|
+
* Its fingerprint, `proposalContentHash`, is what the AS compares, what the
|
|
1662
|
+
* ticket carries and what every `HAP-approval` signs. The content itself is
|
|
1663
|
+
* encrypted to its readers — the Mandate Owner and every signed decider —
|
|
1664
|
+
* with exactly the construction rule 3 pins byte for byte:
|
|
1665
|
+
*
|
|
1666
|
+
* - a fresh 32-byte content key (CEK) per proposal;
|
|
1667
|
+
* - AES-256-GCM under the CEK, random 12-byte IV, no associated data,
|
|
1668
|
+
* 16-byte tag; `ciphertext` = IV ‖ GCM ciphertext ‖ tag;
|
|
1669
|
+
* - per reader, HPKE (RFC 9180) base mode, DHKEM(X25519, HKDF-SHA256),
|
|
1670
|
+
* HKDF-SHA256, AES-256-GCM, empty `info`, the CEK sealed single-shot with
|
|
1671
|
+
* empty associated data; `enc` the 32-byte encapsulated key, `ct` the
|
|
1672
|
+
* 48-byte sealed CEK;
|
|
1673
|
+
* - every binary value base64url without padding; `encrypted_keys` keyed by
|
|
1674
|
+
* the reader's DID. The reader key is an X25519 key distinct from the
|
|
1675
|
+
* DID's signing key.
|
|
1676
|
+
*
|
|
1677
|
+
* The conformance vector `proposal-encryption.json` fixes the CEK, the IV
|
|
1678
|
+
* and the ephemeral keys so the output is reproducible; real use draws all
|
|
1679
|
+
* three at random, and the deterministic hooks exist for that test only.
|
|
1680
|
+
*/
|
|
1681
|
+
interface ProposalContentEnvelope {
|
|
1682
|
+
ciphertext: string;
|
|
1683
|
+
encrypted_keys: Record<string, {
|
|
1684
|
+
ct: string;
|
|
1685
|
+
enc: string;
|
|
1686
|
+
}>;
|
|
1687
|
+
readers: string[];
|
|
1688
|
+
unreadable: string[];
|
|
1689
|
+
}
|
|
1690
|
+
interface ReaderKeyPair {
|
|
1691
|
+
/** Raw X25519 private key, 32 bytes. */
|
|
1692
|
+
privateKey: Uint8Array;
|
|
1693
|
+
/** Raw X25519 public key, 32 bytes. */
|
|
1694
|
+
publicKey: Uint8Array;
|
|
1695
|
+
}
|
|
1696
|
+
/** The content's JCS bytes, as a string (rule 1). */
|
|
1697
|
+
declare function proposalContentJcs(args: Record<string, unknown>): string;
|
|
1698
|
+
/** `proposalContentHash` — `"sha256:" + hex(sha256(JCS(content)))` (rule 4). */
|
|
1699
|
+
declare function computeProposalContentHash(args: Record<string, unknown>): string;
|
|
1700
|
+
/** A fresh reader key pair (X25519). */
|
|
1701
|
+
declare function generateReaderKeyPair(): Promise<ReaderKeyPair>;
|
|
1702
|
+
/** A reader key pair derived from input keying material (RFC 9180
|
|
1703
|
+
* DeriveKeyPair) — deterministic; for tests and vectors. */
|
|
1704
|
+
declare function deriveReaderKeyPair(ikm: Uint8Array): Promise<ReaderKeyPair>;
|
|
1705
|
+
interface EncryptOptions {
|
|
1706
|
+
/** Signed deciders for whom no reader key exists; listed, notified, unable to decide. */
|
|
1707
|
+
unreadable?: string[];
|
|
1708
|
+
/** Deterministic inputs — TESTS AND VECTORS ONLY. */
|
|
1709
|
+
deterministic?: {
|
|
1710
|
+
contentKey: Uint8Array;
|
|
1711
|
+
iv: Uint8Array;
|
|
1712
|
+
/** Per reader DID: the ephemeral key material for its HPKE wrap. */
|
|
1713
|
+
ephemeralIkm: Record<string, Uint8Array>;
|
|
1714
|
+
};
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Encrypt a proposal's content to its readers and compute its fingerprint.
|
|
1718
|
+
* @param readers Each reader's DID and raw X25519 reader public key.
|
|
1719
|
+
*/
|
|
1720
|
+
declare function encryptProposalContent(args: Record<string, unknown>, readers: ReadonlyArray<{
|
|
1721
|
+
did: string;
|
|
1722
|
+
publicKey: Uint8Array;
|
|
1723
|
+
}>, opts?: EncryptOptions): Promise<{
|
|
1724
|
+
content: ProposalContentEnvelope;
|
|
1725
|
+
proposalContentHash: string;
|
|
1726
|
+
}>;
|
|
1727
|
+
/**
|
|
1728
|
+
* Decrypt a proposal's content as one reader. A reader whose HPKE open or
|
|
1729
|
+
* GCM decryption fails MUST treat the proposal as unreadable — never as
|
|
1730
|
+
* empty or partial content (rule 3); this throws rather than returning.
|
|
1731
|
+
* @returns the argument object and its JCS, so the caller recomputes the
|
|
1732
|
+
* fingerprint and refuses on a mismatch (rule 8).
|
|
1733
|
+
*/
|
|
1734
|
+
declare function decryptProposalContent(content: ProposalContentEnvelope, readerDid: string, readerPrivateKey: Uint8Array): Promise<{
|
|
1735
|
+
arguments: Record<string, unknown>;
|
|
1736
|
+
contentJcs: string;
|
|
1737
|
+
proposalContentHash: string;
|
|
1738
|
+
}>;
|
|
1739
|
+
/**
|
|
1740
|
+
* The reader-set rules an Authority Server applies at submission (rule 2):
|
|
1741
|
+
* `readers` ∪ `unreadable` equals the owner plus the signed deciders;
|
|
1742
|
+
* `readers` equals the key set of `encrypted_keys`.
|
|
1743
|
+
* @throws HapError `PROPOSAL_APPROVERS_INVALID` | `PROPOSAL_NOT_ENCRYPTED`
|
|
1744
|
+
*/
|
|
1745
|
+
declare function checkProposalReaders(content: ProposalContentEnvelope, expected: {
|
|
1746
|
+
ownerDid: string;
|
|
1747
|
+
deciders: readonly string[];
|
|
1748
|
+
}): void;
|
|
1749
|
+
|
|
1750
|
+
/**
|
|
1751
|
+
* Pure checks both enforcement points apply around issuance and execution
|
|
1752
|
+
* (v0.8). An Authority Server composes them into its stage order
|
|
1753
|
+
* (protocol.md → *Mandate Issuance & Validation*, *Ticket Issuance*); a
|
|
1754
|
+
* Gatekeeper applies the execution-side ones locally (*Validation Steps*).
|
|
1755
|
+
* They live here so the two cannot disagree about what a value means.
|
|
1756
|
+
*/
|
|
1757
|
+
|
|
1758
|
+
/**
|
|
1759
|
+
* `execution_context_hash` — sha256 over the JCS of the profile's
|
|
1760
|
+
* `executionContextSchema`, or of `{}` when the profile has none (protocol.md
|
|
1761
|
+
* → *Execution Context Schema*, stated in v0.8).
|
|
1762
|
+
*/
|
|
1763
|
+
declare function computeExecutionContextHash(profile: Pick<AgentProfile, 'executionContextSchema'>): string;
|
|
1764
|
+
/** The execution-context fields some bound of the profile reads
|
|
1765
|
+
* (`boundType.of` of every `per_transaction` and `cumulative_sum` bound). */
|
|
1766
|
+
declare function boundReadFields(profile: AgentProfile): Set<string>;
|
|
1767
|
+
/**
|
|
1768
|
+
* Build the wire execution context (*Validation Steps*, step 11; *Ticket
|
|
1769
|
+
* Request Schema*, rules 7–8): only what a bound reads travels. `action_type`
|
|
1770
|
+
* travels as the request's own `actionType`, scope values never travel,
|
|
1771
|
+
* `_`-prefixed keys are advisory metadata. A `null` value is no value.
|
|
1772
|
+
*/
|
|
1773
|
+
declare function wireExecutionContext(execution: Record<string, unknown>, profile: AgentProfile): Record<string, unknown>;
|
|
1774
|
+
/**
|
|
1775
|
+
* Every value present for a field some bound reads MUST be a finite,
|
|
1776
|
+
* non-negative number (*Ticket Issuance*, stage 7; *Validation Steps*, step
|
|
1777
|
+
* 8). `null` counts as absent. A `_`-prefixed key is refused.
|
|
1778
|
+
* @throws HapError `MALFORMED_TICKET_REQUEST`
|
|
1779
|
+
*/
|
|
1780
|
+
declare function checkExecutionValues(execution: Record<string, unknown>, profile: AgentProfile): void;
|
|
1781
|
+
/** Whether a cumulative bound governs this action type: its `appliesTo`
|
|
1782
|
+
* names it, or it has none (Bounds Schema rule 7). */
|
|
1783
|
+
declare function boundGoverns(def: ProfileBoundsField, actionType: string): boolean;
|
|
1784
|
+
/**
|
|
1785
|
+
* The `cumulative_sum` bounds that govern this action type and whose field is
|
|
1786
|
+
* absent from the execution context (*Ticket Issuance*, stage 7): each is a
|
|
1787
|
+
* `BOUND_EXCEEDED`, unless a committed above-cap approval covers the action.
|
|
1788
|
+
*/
|
|
1789
|
+
declare function missingSumFields(execution: Record<string, unknown>, profile: AgentProfile, actionType: string): Array<{
|
|
1790
|
+
bound: string;
|
|
1791
|
+
field: string;
|
|
1792
|
+
}>;
|
|
1793
|
+
/**
|
|
1794
|
+
* Bounds values against the profile at issuance (*Mandate Issuance*, stage
|
|
1795
|
+
* 4): a number where the field is numeric (`"100"` is refused), no higher
|
|
1796
|
+
* than a declared `maximum`, and an `enum` value in its `values`.
|
|
1797
|
+
* @throws HapError `BOUNDS_INVALID_VALUE`
|
|
1798
|
+
*/
|
|
1799
|
+
declare function checkBoundsValues(bounds: AgentBoundsParams, profile: AgentProfile): void;
|
|
1800
|
+
/** A group's caps for one profile, as the AS holds them. */
|
|
1801
|
+
interface GroupCaps {
|
|
1802
|
+
/** Caps a proposal may lift (`approval` kind) — numeric per_transaction fields only. */
|
|
1803
|
+
approval?: Record<string, number>;
|
|
1804
|
+
/** Hard caps: refused at signing, never routed. Numeric or enum values. */
|
|
1805
|
+
hard?: Record<string, number | string>;
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Whether a bound value exceeds a cap. For an `enum` bound the cap is one of
|
|
1809
|
+
* its values, and a value that comes EARLIER in the profile's `values` order
|
|
1810
|
+
* (more permissive) exceeds it (Bounds Schema rule 10; *Group ceilings*).
|
|
1811
|
+
*/
|
|
1812
|
+
declare function exceedsCap(value: string | number, cap: string | number, def: ProfileBoundsField): boolean;
|
|
1813
|
+
/**
|
|
1814
|
+
* Hard group ceilings at signing (*Group ceilings*; *Group roles*, rule 5):
|
|
1815
|
+
* a cap on a bound the Gatekeeper alone enforces (`enforcedBy: "gatekeeper"`)
|
|
1816
|
+
* or on an `enum` bound is always hard, as is every cap in `hard`; a bound
|
|
1817
|
+
* above one, or an optional bound omitted where a cap exists, is refused.
|
|
1818
|
+
* Caps in `approval` on a cumulative bound are hard too (Commitment Modes,
|
|
1819
|
+
* rule 7). An omitted REQUIRED bound is `MALFORMED_MANDATE`, checked
|
|
1820
|
+
* elsewhere.
|
|
1821
|
+
* @throws HapError `GROUP_CAP_EXCEEDED`
|
|
1822
|
+
*/
|
|
1823
|
+
declare function checkGroupCeilings(bounds: AgentBoundsParams, profile: AgentProfile, caps: GroupCaps): void;
|
|
1824
|
+
/**
|
|
1825
|
+
* The above-cap configuration a mandate request or a group supplies
|
|
1826
|
+
* (*Commitment Modes*, rule 7; *Group roles*, rules 2 and 4; Mandate rule
|
|
1827
|
+
* 10): caps name numeric `per_transaction` bounds of the profile and never
|
|
1828
|
+
* `profile`; approvers are key-bearing DIDs; outside a group the count is an
|
|
1829
|
+
* integer ≥ 1 and no greater than the approvers other than the owner.
|
|
1830
|
+
* @throws HapError `ABOVE_CAP_CONFIG_INVALID`
|
|
1831
|
+
*/
|
|
1832
|
+
declare function validateAboveCapConfig(config: {
|
|
1833
|
+
caps?: Record<string, number>;
|
|
1834
|
+
approvers?: readonly string[];
|
|
1835
|
+
approvals?: number;
|
|
1836
|
+
}, profile: AgentProfile, opts: {
|
|
1837
|
+
ownerDid: string;
|
|
1838
|
+
inGroup: boolean;
|
|
1839
|
+
}): void;
|
|
1840
|
+
/**
|
|
1841
|
+
* Whether a request exceeds an approval-kind cap of the mandate, or — v0.8 —
|
|
1842
|
+
* the field the cap reads is absent (an action of unknown amount is above
|
|
1843
|
+
* the cap). Returns the offending caps.
|
|
1844
|
+
*/
|
|
1845
|
+
declare function capsExceeded(execution: Record<string, unknown>, mandate: Pick<MandatePayload, 'above_cap_caps'>, profile: AgentProfile): Array<{
|
|
1846
|
+
bound: string;
|
|
1847
|
+
field: string;
|
|
1848
|
+
cap: number;
|
|
1849
|
+
value: unknown;
|
|
1850
|
+
}>;
|
|
1851
|
+
|
|
1852
|
+
/**
|
|
1853
|
+
* Gatekeeper — local (Phase 1) verification for bounded execution (v0.8;
|
|
1854
|
+
* v0.7 mandates verified under their own rules).
|
|
1387
1855
|
*
|
|
1388
1856
|
* protocol.md → *Validation Steps* (Phase 1, never reaches the wire):
|
|
1389
1857
|
* 1. Resolve profile from bounds.profile
|
|
@@ -1477,4 +1945,4 @@ declare function decodeDidKey(did: string): Uint8Array;
|
|
|
1477
1945
|
/** True iff the DID decodes as a key-bearing Ed25519 did:key. Never throws. */
|
|
1478
1946
|
declare function isKeyBearingDid(did: string): boolean;
|
|
1479
1947
|
|
|
1480
|
-
export { type AgentBoundsParams, type AgentProfile, type AgentScopeParams, type ApprovalObject, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type FieldConstraint, type FieldUnit, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, HapError, type HapErrorCode, MANDATE_ERROR_CODES, type Mandate, type MandateHeader, type MandateOwnerEntry, type MandatePayload, type MandateProjection, type OwnerSignatureBinding, OwnerSignatureError, PROTOCOL_VERSION, type ProfileBoundsField, type ProfileOwnerSignatureFloor, type ProfileScopeField, type ProfileValidationError, SIGNABLE_COMMITMENT_MODES, SUPPORTED_VERSIONS, type SignableCommitmentMode, type SigningSurface, type Subject, type SubjectValidation, TICKET_ERROR_CODES, type TicketPayload, type VerifyOptions, allowedCommitmentModes, approvalSigningBytes, bindingAppliesTo, boundActionTypes, buildMandateProjection, canonicalBounds, canonicalScope, canonicalize, canonicalizeText, checkDiscloseSubset, checkMandateExpiry, checkOwnerSignatureRequirement, clearProfiles, computeBoundsHash, computeContentHash, computeFieldsContentHash, computeIntentDisclosureHash, computeIntentHash, computeProfileHash, computeScopeHash, contentCanonicalBytes, decodeDidKey, decodeMandateBlob, deriveIdentityLine, encodeDidKey, encodeMandateBlob, fromBase64Url, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isCommitmentModeAllowed, isFieldBinding, isKeyBearingDid, listProfiles, mandateBlobId, negotiateVersion, projectionSigningBytes, publicTicketView, registerProfile, selectBoundFields, signApproval, signMandate, signMandateProjection, signTicket, toBase64Url, validateBoundsParams, validateMandateOwners, validateProfile, validateScopeParams, validateSubject, verify, verifyApproval, verifyMandate, verifyMandateSignature, verifyOwnerSignature, verifyOwnerSignatures, verifyTicketSignature };
|
|
1948
|
+
export { type AgentBoundsParams, type AgentProfile, type AgentScopeParams, type ApprovalObject, type ApprovalSignatureEntry, type ApproverSignatureEntry, BINDING_RANK, type BoundType, COMMITMENT_MODES, CanonicalValueError, type CommitmentMode, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type ContentFieldKind, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type EncryptOptions, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type FieldConstraint, type FieldUnit, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type GroupCaps, HapError, type HapErrorCode, ISSUABLE_VERSIONS, MANDATE_ERROR_CODES, type Mandate, type MandateHeader, type MandateOwnerEntry, type MandatePayload, type MandateProjection, type OwnerSignatureBinding, OwnerSignatureError, PROJECTION_MAX_VALIDITY_SECONDS, PROPOSAL_ERROR_CODES, PROTOCOL_VERSION, PolicyError, type PolicyInput, type ProfileBoundsField, type ProfileOwnerSignatureFloor, type ProfileScopeField, type ProfileValidationError, type ProposalContentEnvelope, type ProtocolVersion, type ReaderKeyPair, SIGNABLE_COMMITMENT_MODES, SUPPORTED_VERSIONS, type SignableCommitmentMode, type SigningSurface, type Subject, type SubjectValidation, type SupportedVersion, TICKET_ERROR_CODES, TICKET_FRESHNESS_SECONDS, type TicketPayload, type TicketProjection, type TicketRequestEcho, type VerifiedApprovals, type VerifierPolicy, type VerifyOptions, allowedCommitmentModes, approvalSigningBytes, approvalsSufficient, assertSupportedVersion, assertTicketShape, bindingAppliesTo, bindingRank, boundActionTypes, boundGoverns, boundReadFields, buildMandateProjection, buildTicketProjection, canonicalBounds, canonicalScope, canonicalize, canonicalizeText, capsExceeded, checkBoundsValues, checkDiscloseSubset, checkExecutionValues, checkGroupCeilings, checkMandateExpiry, checkOwnerSignatureRequirement, checkProposalReaders, clearProfiles, computeBoundsHash, computeContentHash, computeExecutionContextHash, computeFieldsContentHash, computeIntentDisclosureHash, computeIntentHash, computeProfileHash, computeProposalContentHash, computeScopeHash, contentCanonicalBytes, decodeDidKey, decodeMandateBlob, decryptProposalContent, deriveIdentityLine, deriveReaderKeyPair, encodeDidKey, encodeMandateBlob, encryptProposalContent, evaluateVerifierPolicy, exceedsCap, filesFields, fromBase64Url, generateReaderKeyPair, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, invalidFieldKindsReason, isCommitmentModeAllowed, isFieldBinding, isKeyBearingDid, isSupportedVersion, listProfiles, mandateBlobId, missingSumFields, negotiateVersion, projectionSigningBytes, proposalContentJcs, publicTicketView, reconstructApproval, registerProfile, selectBoundFields, signApproval, signMandate, signMandateProjection, signTicket, signTicketProjection, toBase64Url, validateAboveCapConfig, validateAboveCapFields, validateBoundsParams, validateMandateOwners, validateProfile, validateScopeParams, validateSubject, verify, verifyApproval, verifyMandate, verifyMandateSignature, verifyOwnerSignature, verifyOwnerSignatures, verifyProjectionOwner, verifyTicketAgainstRequest, verifyTicketApprovals, verifyTicketProjection, verifyTicketSignature, wireExecutionContext };
|