@suveren/gateway 0.19.5 → 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.
Files changed (46) hide show
  1. package/content/integrations/crm.json +1 -1
  2. package/content/integrations/deploy-github.json +1 -1
  3. package/content/integrations/erp.json +1 -1
  4. package/content/integrations/mail.json +1 -1
  5. package/content/integrations/records.json +1 -1
  6. package/dist/control-plane/index.mjs +21 -13
  7. package/dist/mcp-server/{chunk-ZRRZFGRL.mjs → chunk-APIQIEUA.mjs} +39 -27
  8. package/dist/mcp-server/http.mjs +308 -97
  9. package/dist/mcp-server/report-verify-cli.mjs +1 -1
  10. package/dist/ui/assets/index-1s1q-XLL.js +116 -0
  11. package/dist/ui/index.html +1 -1
  12. package/node_modules/@hap/core/README.md +92 -29
  13. package/node_modules/@hap/core/dist/index.d.mts +614 -593
  14. package/node_modules/@hap/core/dist/index.d.ts +614 -593
  15. package/node_modules/@hap/core/dist/index.js +774 -749
  16. package/node_modules/@hap/core/dist/index.mjs +744 -724
  17. package/node_modules/@hap/core/package.json +1 -1
  18. package/node_modules/@hap/core/src/base64url.ts +39 -0
  19. package/node_modules/@hap/core/src/commitment-modes.ts +0 -21
  20. package/node_modules/@hap/core/src/errors.ts +76 -0
  21. package/node_modules/@hap/core/src/frame.ts +47 -178
  22. package/node_modules/@hap/core/src/gatekeeper.ts +219 -600
  23. package/node_modules/@hap/core/src/identity.ts +9 -12
  24. package/node_modules/@hap/core/src/index.ts +8 -4
  25. package/node_modules/@hap/core/src/mandate.ts +177 -166
  26. package/node_modules/@hap/core/src/owner-signature.ts +282 -0
  27. package/node_modules/@hap/core/src/profile.ts +234 -0
  28. package/node_modules/@hap/core/src/ticket.ts +148 -0
  29. package/node_modules/@hap/core/src/types.ts +191 -344
  30. package/node_modules/@hap/core/src/versions.ts +47 -0
  31. package/package.json +2 -2
  32. package/profiles/calendar/0.6.profile.json +191 -0
  33. package/profiles/charge/0.6.profile.json +211 -0
  34. package/profiles/customers/0.9.profile.json +182 -0
  35. package/profiles/delegation/0.3.profile.json +118 -0
  36. package/profiles/deploy/0.11.profile.json +177 -0
  37. package/profiles/email/0.8.profile.json +226 -0
  38. package/profiles/index.json +12 -1
  39. package/profiles/publish/0.6.profile.json +187 -0
  40. package/profiles/purchase/0.7.profile.json +235 -0
  41. package/profiles/records/0.6.profile.json +118 -0
  42. package/profiles/reporting/0.3.profile.json +98 -0
  43. package/profiles/sales/0.4.profile.json +291 -0
  44. package/dist/ui/assets/index-Du68zJhH.js +0 -116
  45. package/node_modules/@hap/core/src/attestation.ts +0 -173
  46. package/node_modules/@hap/core/src/receipt.ts +0 -74
@@ -1,173 +0,0 @@
1
- /**
2
- * Attestation Encoding, Decoding, and Verification
3
- *
4
- * Supports both v0.3 (frame_hash) and v0.4 (bounds_hash + context_hash).
5
- */
6
-
7
- import { createHash } from 'crypto';
8
- import * as ed from '@noble/ed25519';
9
- import type { Attestation, AttestationPayload } from './types';
10
- import { canonicalize } from './canonicalize';
11
-
12
- /**
13
- * Decodes a base64url-encoded attestation blob.
14
- */
15
- export function decodeAttestationBlob(blob: string): Attestation {
16
- try {
17
- const base64 = blob.replace(/-/g, '+').replace(/_/g, '/');
18
- const padding = base64.length % 4 === 0 ? '' : '='.repeat(4 - (base64.length % 4));
19
- const json = Buffer.from(base64 + padding, 'base64').toString('utf8');
20
- return JSON.parse(json);
21
- } catch {
22
- throw new Error('MALFORMED_ATTESTATION: Failed to decode attestation blob');
23
- }
24
- }
25
-
26
- /**
27
- * Encodes an attestation as a base64url blob (no padding).
28
- */
29
- export function encodeAttestationBlob(attestation: Attestation): string {
30
- const json = JSON.stringify(attestation);
31
- const base64 = Buffer.from(json, 'utf8').toString('base64');
32
- return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
33
- }
34
-
35
- /**
36
- * Computes the attestation ID (hash of the blob).
37
- */
38
- export function attestationId(blob: string): string {
39
- const hash = createHash('sha256').update(blob, 'utf8').digest('hex');
40
- return `sha256:${hash}`;
41
- }
42
-
43
- /**
44
- * Verifies an attestation signature using the SP public key.
45
- *
46
- * @returns true if valid
47
- * @throws Error with code prefix if invalid
48
- */
49
- export async function verifyAttestationSignature(
50
- attestation: Attestation,
51
- publicKeyHex: string
52
- ): Promise<void> {
53
- try {
54
- // JCS-canonical bytes (RFC 8785) — must match the canonicalization the
55
- // signer used. The AS signs the same canonical form (see keys.ts).
56
- const payloadJson = canonicalize(attestation.payload);
57
- const payloadBytes = new TextEncoder().encode(payloadJson);
58
- const signatureBytes = Buffer.from(attestation.signature, 'base64');
59
- const publicKeyBytes = Buffer.from(publicKeyHex, 'hex');
60
-
61
- const isValid = await ed.verifyAsync(signatureBytes, payloadBytes, publicKeyBytes);
62
-
63
- if (!isValid) {
64
- throw new Error('INVALID_SIGNATURE: Attestation signature verification failed');
65
- }
66
- } catch (error) {
67
- if (error instanceof Error && error.message.startsWith('INVALID_SIGNATURE')) throw error;
68
- throw new Error(`INVALID_SIGNATURE: Signature verification error: ${error}`);
69
- }
70
- }
71
-
72
- /**
73
- * Checks if an attestation has expired.
74
- *
75
- * @throws Error if expired
76
- */
77
- export function checkAttestationExpiry(
78
- payload: AttestationPayload,
79
- now: number = Math.floor(Date.now() / 1000)
80
- ): void {
81
- if (payload.expires_at <= now) {
82
- throw new Error(
83
- `TTL_EXPIRED: Attestation expired at ${payload.expires_at}, current time is ${now}`
84
- );
85
- }
86
- }
87
-
88
- /**
89
- * Verifies that the frame hash in the attestation matches the expected hash (v0.3).
90
- *
91
- * @throws Error if frame hash doesn't match
92
- */
93
- export function verifyFrameHash(attestation: Attestation, expectedFrameHash: string): void {
94
- if (attestation.payload.frame_hash !== expectedFrameHash) {
95
- throw new Error('FRAME_MISMATCH: Frame hash mismatch');
96
- }
97
- }
98
-
99
- /**
100
- * Detects whether an attestation is v0.4 (has bounds_hash + context_hash)
101
- * or v0.3 (has frame_hash).
102
- *
103
- * Migration rule: if attestation has frame_hash but not bounds_hash, it is v0.3.
104
- */
105
- export function isV4Attestation(attestation: Attestation): boolean {
106
- return attestation.payload.bounds_hash !== undefined;
107
- }
108
-
109
- /**
110
- * Verifies that the bounds hash in the attestation matches the expected hash (v0.4).
111
- *
112
- * @throws Error if bounds hash doesn't match
113
- */
114
- export function verifyBoundsHash(attestation: Attestation, expectedBoundsHash: string): void {
115
- // Migration: if attestation has frame_hash but not bounds_hash, treat frame_hash as bounds_hash
116
- const attestedHash = attestation.payload.bounds_hash ?? attestation.payload.frame_hash;
117
- if (attestedHash !== expectedBoundsHash) {
118
- throw new Error('BOUNDS_MISMATCH: Bounds hash mismatch');
119
- }
120
- }
121
-
122
- /**
123
- * Verifies that the context hash in the attestation matches the expected hash (v0.4).
124
- *
125
- * @throws Error if context hash doesn't match
126
- */
127
- export function verifyContextHash(attestation: Attestation, expectedContextHash: string): void {
128
- if (attestation.payload.context_hash !== expectedContextHash) {
129
- throw new Error('CONTEXT_MISMATCH: Context hash mismatch');
130
- }
131
- }
132
-
133
- /**
134
- * Full attestation verification (signature + expiry + frame hash) — v0.3.
135
- *
136
- * @returns The decoded attestation payload
137
- * @throws Error on any validation failure
138
- */
139
- export async function verifyAttestation(
140
- blob: string,
141
- publicKeyHex: string,
142
- expectedFrameHash: string
143
- ): Promise<AttestationPayload> {
144
- const attestation = decodeAttestationBlob(blob);
145
-
146
- await verifyAttestationSignature(attestation, publicKeyHex);
147
- checkAttestationExpiry(attestation.payload);
148
- verifyFrameHash(attestation, expectedFrameHash);
149
-
150
- return attestation.payload;
151
- }
152
-
153
- /**
154
- * Full attestation verification for v0.4 (signature + expiry + bounds_hash + context_hash).
155
- *
156
- * @returns The decoded attestation payload
157
- * @throws Error on any validation failure
158
- */
159
- export async function verifyAttestationV4(
160
- blob: string,
161
- publicKeyHex: string,
162
- expectedBoundsHash: string,
163
- expectedContextHash: string
164
- ): Promise<AttestationPayload> {
165
- const attestation = decodeAttestationBlob(blob);
166
-
167
- await verifyAttestationSignature(attestation, publicKeyHex);
168
- checkAttestationExpiry(attestation.payload);
169
- verifyBoundsHash(attestation, expectedBoundsHash);
170
- verifyContextHash(attestation, expectedContextHash);
171
-
172
- return attestation.payload;
173
- }
@@ -1,74 +0,0 @@
1
- /**
2
- * Execution receipts (HAP v0.5/v0.6) — the wire type and holder-side
3
- * verification. Until v0.6 this library had no receipt surface at all; every
4
- * verifier hand-assembled the strip→canonicalize→verify dance. This module is
5
- * that dance, once.
6
- *
7
- * Receipt payloads are camelCase on the wire (unlike the snake_case
8
- * attestation payload) — a shipped inconsistency v0.6 chose to document
9
- * rather than break (changelog.md → "Renames and terminology").
10
- */
11
-
12
- import * as ed from '@noble/ed25519';
13
- import type { ContentBinding, Subject } from './types';
14
- import { canonicalize } from './canonicalize';
15
-
16
- /** Signed execution receipt — protocol.md → "Receipt Payload Schema". */
17
- export interface ReceiptPayload {
18
- id: string;
19
- groupId?: string | null;
20
- userId?: string;
21
- boundsHash: string;
22
- profileId: string;
23
- /** Downstream tool name. Audit metadata only — never a dispatch key. */
24
- action: string;
25
- /** Semantic category — drives cumulative bucketing and bounds dispatch. */
26
- actionType: string;
27
- executionContext: Record<string, unknown>;
28
- cumulativeState?: Record<string, unknown>;
29
- limits?: Record<string, unknown>;
30
- timestamp: number;
31
- /** v0.6 — hash of the bound content, computed by the Gatekeeper, copied
32
- * verbatim by the AS. The AS never sees the content. */
33
- contentHash?: string;
34
- /** v0.6 — the binding declaration echoed into the signed receipt, so a
35
- * verifier knows exactly what `contentHash` covers. */
36
- contentBinding?: Pick<ContentBinding, 'version' | 'kind' | 'fields' | 'required_fields' | 'appliesTo'>;
37
- /** v0.6 — disclosed subset of the attestation's identity overlay. */
38
- subjects?: Subject[];
39
- /** v0.6 — review path: the proposal this receipt executed. */
40
- proposalId?: string;
41
- /** v0.6 — review path: the owner's HAP-approval signature (or its sha256)
42
- * for the executed proposal. */
43
- approvalSignature?: string;
44
- /** Ed25519 over the JCS-canonical payload (this field excluded), base64url. */
45
- signature: string;
46
- }
47
-
48
- /**
49
- * Verify a receipt's AS signature: strip `signature`, JCS-canonicalize the
50
- * rest, Ed25519-verify against the AS public key (hex). This is holder-side
51
- * verification — it needs the COMPLETE receipt; a redacted public view cannot
52
- * be re-verified this way (protocol.md → "Receipt Verification").
53
- *
54
- * Content is checked separately: where `contentHash` is present, recompute it
55
- * from the held artifact via the content-binding module and compare.
56
- *
57
- * @throws Error prefixed `INVALID_SIGNATURE:` when verification fails.
58
- */
59
- export async function verifyReceiptSignature(receipt: ReceiptPayload, publicKeyHex: string): Promise<void> {
60
- const { signature, ...unsigned } = receipt;
61
- if (!signature) {
62
- throw new Error('INVALID_SIGNATURE: receipt carries no signature');
63
- }
64
- const bytes = new TextEncoder().encode(canonicalize(unsigned));
65
- const base64 = signature.replace(/-/g, '+').replace(/_/g, '/');
66
- const padding = base64.length % 4 === 0 ? '' : '='.repeat(4 - (base64.length % 4));
67
- const sigBytes = new Uint8Array(Buffer.from(base64 + padding, 'base64'));
68
- const publicKeyBytes = new Uint8Array(Buffer.from(publicKeyHex, 'hex'));
69
-
70
- const ok = await ed.verifyAsync(sigBytes, bytes, publicKeyBytes).catch(() => false);
71
- if (!ok) {
72
- throw new Error('INVALID_SIGNATURE: receipt signature verification failed');
73
- }
74
- }