@suveren/gateway 0.2.12 → 0.3.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 +21 -7
- package/dist/control-plane/index.mjs +146 -2
- package/dist/mcp-server/http.mjs +80 -38
- package/dist/ui/assets/index-RkZBhIxU.js +105 -0
- package/dist/ui/index.html +1 -1
- package/node_modules/@hap/core/dist/index.d.mts +147 -3
- package/node_modules/@hap/core/dist/index.d.ts +147 -3
- package/node_modules/@hap/core/dist/index.js +74 -10
- package/node_modules/@hap/core/dist/index.mjs +69 -10
- package/node_modules/@hap/core/package.json +1 -1
- package/node_modules/@hap/core/src/gatekeeper.ts +4 -4
- package/node_modules/@hap/core/src/identity.ts +77 -0
- package/node_modules/@hap/core/src/index.ts +2 -0
- package/node_modules/@hap/core/src/intent-disclosure.ts +69 -0
- package/node_modules/@hap/core/src/types.ts +62 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/README.md +16 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/index.js +4 -20
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/lib/read.js +17 -17
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/lib/types/json.js +60 -32
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/lib/types/raw.js +3 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/lib/types/text.js +3 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/lib/types/urlencoded.js +16 -20
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/lib/utils.js +18 -16
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/LICENSE +22 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/README.md +69 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +26 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.js +170 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/package.json +52 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/package.json +23 -10
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/assert/strict.d.ts +10 -1
- package/node_modules/@types/node/assert.d.ts +144 -17
- package/node_modules/@types/node/async_hooks.d.ts +9 -9
- package/node_modules/@types/node/buffer.d.ts +0 -5
- package/node_modules/@types/node/child_process.d.ts +17 -21
- package/node_modules/@types/node/cluster.d.ts +13 -13
- package/node_modules/@types/node/console.d.ts +1 -1
- package/node_modules/@types/node/crypto.d.ts +454 -571
- package/node_modules/@types/node/diagnostics_channel.d.ts +37 -29
- package/node_modules/@types/node/dns.d.ts +14 -14
- package/node_modules/@types/node/events.d.ts +3 -3
- package/node_modules/@types/node/fs/promises.d.ts +4 -4
- package/node_modules/@types/node/fs.d.ts +3 -12
- package/node_modules/@types/node/globals.d.ts +4 -4
- package/node_modules/@types/node/http.d.ts +5 -5
- package/node_modules/@types/node/http2.d.ts +5 -1
- package/node_modules/@types/node/index.d.ts +0 -3
- package/node_modules/@types/node/inspector.d.ts +1 -1
- package/node_modules/@types/node/module.d.ts +16 -45
- package/node_modules/@types/node/net.d.ts +1 -1
- package/node_modules/@types/node/os.d.ts +2 -2
- package/node_modules/@types/node/package.json +4 -4
- package/node_modules/@types/node/perf_hooks.d.ts +1 -9
- package/node_modules/@types/node/process.d.ts +11 -11
- package/node_modules/@types/node/readline.d.ts +12 -11
- package/node_modules/@types/node/repl.d.ts +10 -10
- package/node_modules/@types/node/sqlite.d.ts +1 -1
- package/node_modules/@types/node/stream/promises.d.ts +2 -2
- package/node_modules/@types/node/stream/web.d.ts +1 -1
- package/node_modules/@types/node/stream.d.ts +5 -5
- package/node_modules/@types/node/test/reporters.d.ts +1 -1
- package/node_modules/@types/node/test.d.ts +8 -8
- package/node_modules/@types/node/tls.d.ts +1 -1
- package/node_modules/@types/node/ts5.6/index.d.ts +1 -4
- package/node_modules/@types/node/ts5.7/index.d.ts +0 -3
- package/node_modules/@types/node/url.d.ts +3 -3
- package/node_modules/@types/node/util/types.d.ts +1 -1
- package/node_modules/@types/node/util.d.ts +3 -20
- package/node_modules/@types/node/v8.d.ts +1 -1
- package/node_modules/@types/node/vm.d.ts +9 -9
- package/node_modules/@types/node/web-globals/domexception.d.ts +15 -0
- package/node_modules/@types/node/worker_threads.d.ts +2 -5
- package/node_modules/@types/node/zlib.d.ts +3 -3
- package/node_modules/fast-uri/index.js +1 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +28 -0
- package/node_modules/hono/dist/adapter/aws-lambda/handler.js +14 -20
- package/node_modules/hono/dist/adapter/lambda-edge/handler.js +8 -2
- package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +14 -20
- package/node_modules/hono/dist/cjs/adapter/lambda-edge/handler.js +8 -2
- package/node_modules/hono/dist/cjs/helper/css/common.js +3 -1
- package/node_modules/hono/dist/cjs/helper/css/index.js +9 -1
- package/node_modules/hono/dist/cjs/jsx/base.js +8 -14
- package/node_modules/hono/dist/cjs/jsx/components.js +41 -21
- package/node_modules/hono/dist/cjs/jsx/context.js +131 -5
- package/node_modules/hono/dist/cjs/jsx/streaming.js +9 -7
- package/node_modules/hono/dist/cjs/middleware/bearer-auth/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +2 -5
- package/node_modules/hono/dist/cjs/middleware/language/language.js +10 -32
- package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/timing/timing.js +3 -1
- package/node_modules/hono/dist/cjs/utils/ipaddr.js +6 -1
- package/node_modules/hono/dist/helper/css/common.js +3 -1
- package/node_modules/hono/dist/helper/css/index.js +9 -1
- package/node_modules/hono/dist/jsx/base.js +15 -15
- package/node_modules/hono/dist/jsx/components.js +42 -22
- package/node_modules/hono/dist/jsx/context.js +129 -5
- package/node_modules/hono/dist/jsx/streaming.js +10 -8
- package/node_modules/hono/dist/middleware/bearer-auth/index.js +1 -1
- package/node_modules/hono/dist/middleware/cors/index.js +2 -5
- package/node_modules/hono/dist/middleware/language/language.js +10 -32
- package/node_modules/hono/dist/middleware/serve-static/index.js +1 -1
- package/node_modules/hono/dist/middleware/timing/timing.js +3 -1
- package/node_modules/hono/dist/tsconfig.build.tsbuildinfo +1 -1
- package/node_modules/hono/dist/types/adapter/aws-lambda/handler.d.ts +1 -1
- package/node_modules/hono/dist/types/jsx/base.d.ts +1 -3
- package/node_modules/hono/dist/types/jsx/context.d.ts +39 -0
- package/node_modules/hono/dist/utils/ipaddr.js +6 -1
- package/node_modules/hono/package.json +19 -13
- package/node_modules/http-proxy-middleware/README.md +3 -10
- package/node_modules/http-proxy-middleware/dist/errors.d.ts +4 -0
- package/node_modules/http-proxy-middleware/dist/errors.js +16 -1
- package/node_modules/http-proxy-middleware/dist/factory.d.ts +2 -2
- package/node_modules/http-proxy-middleware/dist/handlers/fix-request-body-utils/stringify-form-data.d.ts +7 -0
- package/node_modules/http-proxy-middleware/dist/handlers/fix-request-body-utils/stringify-form-data.js +45 -0
- package/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.d.ts +1 -1
- package/node_modules/http-proxy-middleware/dist/handlers/fix-request-body.js +23 -23
- package/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.d.ts +1 -1
- package/node_modules/http-proxy-middleware/dist/handlers/response-interceptor.js +1 -1
- package/node_modules/http-proxy-middleware/dist/http-proxy-middleware.d.ts +1 -1
- package/node_modules/http-proxy-middleware/dist/http-proxy-middleware.js +2 -2
- package/node_modules/http-proxy-middleware/dist/legacy/create-proxy-middleware.d.ts +1 -1
- package/node_modules/http-proxy-middleware/dist/legacy/create-proxy-middleware.js +1 -1
- package/node_modules/http-proxy-middleware/dist/legacy/options-adapter.js +1 -1
- package/node_modules/http-proxy-middleware/dist/legacy/types.d.ts +1 -1
- package/node_modules/http-proxy-middleware/dist/path-filter.d.ts +1 -1
- package/node_modules/http-proxy-middleware/dist/path-filter.js +1 -1
- package/node_modules/http-proxy-middleware/dist/path-rewriter.js +1 -1
- package/node_modules/http-proxy-middleware/dist/plugins/default/error-response-plugin.js +2 -1
- package/node_modules/http-proxy-middleware/dist/plugins/default/logger-plugin.js +3 -3
- package/node_modules/http-proxy-middleware/dist/router.js +26 -8
- package/node_modules/http-proxy-middleware/dist/status-code.js +15 -12
- package/node_modules/http-proxy-middleware/dist/types.d.ts +3 -3
- package/node_modules/http-proxy-middleware/dist/types.js +0 -4
- package/node_modules/http-proxy-middleware/dist/utils/sanitize.d.ts +1 -0
- package/node_modules/http-proxy-middleware/dist/utils/sanitize.js +6 -0
- package/node_modules/http-proxy-middleware/package.json +30 -28
- package/node_modules/qs/CHANGELOG.md +11 -0
- package/node_modules/qs/dist/qs.js +17 -17
- package/node_modules/qs/lib/parse.js +19 -8
- package/node_modules/qs/lib/utils.js +47 -8
- package/node_modules/qs/package.json +6 -5
- package/node_modules/qs/test/parse.js +230 -0
- package/node_modules/qs/test/utils.js +194 -0
- package/node_modules/side-channel/CHANGELOG.md +10 -0
- package/node_modules/side-channel/README.md +1 -1
- package/node_modules/side-channel/index.js +5 -2
- package/node_modules/side-channel/package.json +10 -10
- package/node_modules/side-channel/test/index.js +16 -0
- package/node_modules/undici-types/agent.d.ts +0 -2
- package/node_modules/undici-types/client.d.ts +25 -19
- package/node_modules/undici-types/dispatcher.d.ts +7 -33
- package/node_modules/undici-types/dispatcher1-wrapper.d.ts +7 -0
- package/node_modules/undici-types/fetch.d.ts +24 -4
- package/node_modules/undici-types/h2c-client.d.ts +6 -6
- package/node_modules/undici-types/handlers.d.ts +1 -2
- package/node_modules/undici-types/header.d.ts +5 -0
- package/node_modules/undici-types/index.d.ts +3 -1
- package/node_modules/undici-types/interceptors.d.ts +1 -1
- package/node_modules/undici-types/package.json +1 -1
- package/node_modules/undici-types/pool.d.ts +0 -2
- package/node_modules/undici-types/proxy-agent.d.ts +2 -2
- package/node_modules/undici-types/round-robin-pool.d.ts +0 -2
- package/node_modules/undici-types/snapshot-agent.d.ts +4 -0
- package/node_modules/undici-types/socks5-proxy-agent.d.ts +2 -2
- package/node_modules/undici-types/webidl.d.ts +0 -1
- package/package.json +3 -3
- package/dist/ui/assets/index-CS16uhqb.js +0 -102
- package/node_modules/@types/node/compatibility/iterators.d.ts +0 -21
package/dist/ui/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Suveren</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-RkZBhIxU.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-BUgn3e63.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -14,7 +14,7 @@ interface ResolvedDomain {
|
|
|
14
14
|
}
|
|
15
15
|
interface AttestationPayload {
|
|
16
16
|
attestation_id: string;
|
|
17
|
-
version: '0.3' | '0.4';
|
|
17
|
+
version: '0.3' | '0.4' | '0.5';
|
|
18
18
|
profile_id: string;
|
|
19
19
|
/** v0.3 (deprecated) — hash of the authorization frame */
|
|
20
20
|
frame_hash?: string;
|
|
@@ -23,8 +23,37 @@ interface AttestationPayload {
|
|
|
23
23
|
/** v0.4 — hash of the context parameters */
|
|
24
24
|
context_hash?: string;
|
|
25
25
|
execution_context_hash: string;
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* v0.4 (deprecated in v0.5) — domain-scoped owners. Optional so v0.5
|
|
28
|
+
* attestations that carry only `resolved_owners` remain valid. During the
|
|
29
|
+
* transition the AS emits BOTH `resolved_domains` (internal coverage) and
|
|
30
|
+
* `resolved_owners` (the v0.5 signed wire field).
|
|
31
|
+
*/
|
|
32
|
+
resolved_domains?: ResolvedDomain[];
|
|
33
|
+
/**
|
|
34
|
+
* v0.5 — the Decision Owner DIDs this attestation covers (person-centric
|
|
35
|
+
* model; replaces the abstract domain in `resolved_domains`). Carried in the
|
|
36
|
+
* signed payload so verifiers bind the action to the human(s) who authorized it.
|
|
37
|
+
*/
|
|
38
|
+
resolved_owners?: string[];
|
|
27
39
|
gate_content_hashes: Record<string, string>;
|
|
40
|
+
/**
|
|
41
|
+
* v0.5 (companion spec `intent-disclosure@0.1`) — present iff the attestation
|
|
42
|
+
* carries an encrypted-intent disclosure object. `sha256:`-prefixed hash that
|
|
43
|
+
* binds the disclosure's `intent_ciphertext` + `approvers_frozen` into the
|
|
44
|
+
* signed payload (see {@link computeIntentDisclosureHash}), so a compromised
|
|
45
|
+
* AS cannot swap the ciphertext/wrapped keys or alter the approver set
|
|
46
|
+
* without invalidating the attestation signature (companion invariant C2).
|
|
47
|
+
*/
|
|
48
|
+
intent_disclosure_hash?: string;
|
|
49
|
+
/**
|
|
50
|
+
* v0.6 (Identity Assurance) — optional signed overlay carrying the verified
|
|
51
|
+
* real-world identity of the Decision Owner(s), one entry per owner. Present
|
|
52
|
+
* only when identity is disclosed; an attestation with no `subjects` renders
|
|
53
|
+
* as `low` (pseudonymous, no name). See {@link Subject} and
|
|
54
|
+
* {@link deriveIdentityLine}.
|
|
55
|
+
*/
|
|
56
|
+
subjects?: Subject[];
|
|
28
57
|
/**
|
|
29
58
|
* v0.4 — commitment mode chosen by the decision owner at attestation time.
|
|
30
59
|
* - 'automatic': agent may invoke bounded tools without per-action review.
|
|
@@ -38,6 +67,38 @@ interface AttestationPayload {
|
|
|
38
67
|
issued_at: number;
|
|
39
68
|
expires_at: number;
|
|
40
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* v0.6 Identity Assurance — a signed overlay binding a Decision Owner's verified
|
|
72
|
+
* real-world identity to the attestation, gated by HOW the identity was verified.
|
|
73
|
+
*
|
|
74
|
+
* Two display levels (`assurance`): `low` discloses no name; `high` MAY disclose a
|
|
75
|
+
* name. At `high`, two trust roots: `as` (the AS operator vouches — valid only
|
|
76
|
+
* within its own domain) and `external` (an external eID such as EUDI — carries the
|
|
77
|
+
* owner's own signature, AS-independent). See review.md → "Identity Assurance".
|
|
78
|
+
*/
|
|
79
|
+
interface Subject {
|
|
80
|
+
/** The Decision Owner DID this subject describes (matches an entry in resolved_owners). */
|
|
81
|
+
did: string;
|
|
82
|
+
/** `low` → no name shown; `high` → the name MAY be shown. */
|
|
83
|
+
assurance: 'low' | 'high';
|
|
84
|
+
/** How identity was established. */
|
|
85
|
+
method: 'self_declared' | 'as_vouched' | 'eudi';
|
|
86
|
+
/** Who vouches: `self` (owner's claim), `as` (operator), `external` (eID scheme). */
|
|
87
|
+
trust_root: 'self' | 'as' | 'external';
|
|
88
|
+
/** Verifier id — the AS operator (as_vouched) or the eID scheme (eudi). Required at `high`. */
|
|
89
|
+
verifier?: string;
|
|
90
|
+
/** Disclosed attributes. `name` present ONLY at `assurance:"high"` and when disclosure is on. */
|
|
91
|
+
disclose?: {
|
|
92
|
+
name: string;
|
|
93
|
+
};
|
|
94
|
+
/** When the underlying verification was performed (unix seconds). */
|
|
95
|
+
verified_at?: number;
|
|
96
|
+
/**
|
|
97
|
+
* eudi only (Phase 2) — the owner's per-event wallet signature, making the
|
|
98
|
+
* identity claim non-repudiable independent of the AS. Null/absent otherwise.
|
|
99
|
+
*/
|
|
100
|
+
owner_signature?: string | null;
|
|
101
|
+
}
|
|
41
102
|
interface Attestation {
|
|
42
103
|
header: AttestationHeader;
|
|
43
104
|
payload: AttestationPayload;
|
|
@@ -518,6 +579,89 @@ declare function contentCanonicalBytes(kind: ContentBinding['kind'], content: Re
|
|
|
518
579
|
*/
|
|
519
580
|
declare function computeContentHash(binding: ContentBinding, content: Record<string, unknown> | string): string;
|
|
520
581
|
|
|
582
|
+
/**
|
|
583
|
+
* Intent hashing + intent-disclosure binding (HAP v0.5).
|
|
584
|
+
*
|
|
585
|
+
* Two shared, environment-independent hashes that the attester (gateway), the
|
|
586
|
+
* Authority Server, and any approver MUST compute identically:
|
|
587
|
+
*
|
|
588
|
+
* 1. {@link computeIntentHash} — `gate_content_hashes.intent`. The intent text
|
|
589
|
+
* is canonicalized (Unicode NFC, LF line endings, trailing-whitespace strip
|
|
590
|
+
* — the same rule as content-binding's `canonicalizeText`) before hashing,
|
|
591
|
+
* so independent multi-owner approvers reproduce an identical hash from the
|
|
592
|
+
* same logical statement. See protocol.md → "Intent canonicalization".
|
|
593
|
+
*
|
|
594
|
+
* 2. {@link computeIntentDisclosureHash} — `intent_disclosure_hash`, the C2
|
|
595
|
+
* binding from companion spec `intent-disclosure@0.1`. It commits the
|
|
596
|
+
* encrypted disclosure object (`intent_ciphertext` + `approvers_frozen`)
|
|
597
|
+
* into the SIGNED attestation payload, so a compromised AS cannot swap the
|
|
598
|
+
* ciphertext/wrapped keys or widen/shrink the approver set without breaking
|
|
599
|
+
* the attestation signature.
|
|
600
|
+
*
|
|
601
|
+
* Both produce `sha256:<hex>` to match the frame/bounds/context hash format.
|
|
602
|
+
*/
|
|
603
|
+
/**
|
|
604
|
+
* `gate_content_hashes.intent` for an intent statement.
|
|
605
|
+
* Canonicalizes the text (NFC / LF / trailing-whitespace strip) before hashing.
|
|
606
|
+
*/
|
|
607
|
+
declare function computeIntentHash(intentText: string): string;
|
|
608
|
+
/**
|
|
609
|
+
* The exact bytes `intent_disclosure_hash` is taken over, WITHOUT hashing —
|
|
610
|
+
* exposed so an implementer debugging a mismatch can inspect the serialization
|
|
611
|
+
* both sides must agree on:
|
|
612
|
+
*
|
|
613
|
+
* intent_ciphertext ‖ "\n" ‖ JCS(sort(approvers_frozen))
|
|
614
|
+
*
|
|
615
|
+
* where `intent_ciphertext` is the exact base64url string of the disclosure
|
|
616
|
+
* object, `sort` orders the approver DIDs by Unicode code point, and `JCS` is
|
|
617
|
+
* RFC 8785 canonicalization of the sorted array (via {@link canonicalize}).
|
|
618
|
+
*/
|
|
619
|
+
declare function intentDisclosureCanonicalBytes(intentCiphertext: string, approversFrozen: string[]): string;
|
|
620
|
+
/**
|
|
621
|
+
* `intent_disclosure_hash` — `sha256:<hex>` over
|
|
622
|
+
* {@link intentDisclosureCanonicalBytes}. Computed by the attester after
|
|
623
|
+
* encryption and signed into the attestation; recomputed by the AS (at
|
|
624
|
+
* issuance) and by each approver (on receipt) and compared, fail-closed.
|
|
625
|
+
*/
|
|
626
|
+
declare function computeIntentDisclosureHash(intentCiphertext: string, approversFrozen: string[]): string;
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Identity Assurance (HAP v0.6) — validation + footer derivation for the signed
|
|
630
|
+
* {@link Subject} overlay. See review.md → "Identity Assurance".
|
|
631
|
+
*
|
|
632
|
+
* Two pure helpers, the single source of truth for both the gateway footer and
|
|
633
|
+
* the AS verify page:
|
|
634
|
+
* - {@link validateSubject} — enforces the level/method/trust-root invariants.
|
|
635
|
+
* - {@link deriveIdentityLine} — the human-readable footer line for a subject.
|
|
636
|
+
*/
|
|
637
|
+
|
|
638
|
+
interface SubjectValidation {
|
|
639
|
+
valid: boolean;
|
|
640
|
+
errors: string[];
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Enforce the Identity-Assurance invariants on a single subject:
|
|
644
|
+
* - `self_declared` ⇒ `low` / `self`, no disclosed name.
|
|
645
|
+
* - `as_vouched` ⇒ `high` / `as`, `verifier` required.
|
|
646
|
+
* - `eudi` ⇒ `high` / `external`, `verifier` + `owner_signature` required.
|
|
647
|
+
* - `disclose.name` only at `assurance:"high"`.
|
|
648
|
+
*/
|
|
649
|
+
declare function validateSubject(subject: Subject): SubjectValidation;
|
|
650
|
+
/**
|
|
651
|
+
* The footer line for a subject — the ONE place this wording lives.
|
|
652
|
+
* The name appears only at `high` with a disclosed name; otherwise no name.
|
|
653
|
+
*
|
|
654
|
+
* - low / no disclosure → "Sent by an AI agent via «operator»"
|
|
655
|
+
* - high / as_vouched → "Sent by an AI agent of «name» — verified by «operator»"
|
|
656
|
+
* - high / eudi → "Sent by an AI agent of «name» — identity verified (EUDI)"
|
|
657
|
+
*
|
|
658
|
+
* `operatorName` is the rendered AS operator (e.g. "Suveren") — never hardcode it
|
|
659
|
+
* upstream; a different operator self-vouches under its own name.
|
|
660
|
+
*/
|
|
661
|
+
declare function deriveIdentityLine(subject: Subject | undefined | null, { operatorName }: {
|
|
662
|
+
operatorName: string;
|
|
663
|
+
}): string;
|
|
664
|
+
|
|
521
665
|
/**
|
|
522
666
|
* Frame Canonicalization for Agent Profiles
|
|
523
667
|
*
|
|
@@ -715,4 +859,4 @@ declare function listProfiles(): string[];
|
|
|
715
859
|
declare function getAllProfiles(): AgentProfile[];
|
|
716
860
|
declare function clearProfiles(): void;
|
|
717
861
|
|
|
718
|
-
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type ContentBinding, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, attestationId, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFrameHash, contentCanonicalBytes, decodeAttestationBlob, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
|
862
|
+
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type ContentBinding, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, type Subject, type SubjectValidation, attestationId, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFrameHash, computeIntentDisclosureHash, computeIntentHash, contentCanonicalBytes, decodeAttestationBlob, deriveIdentityLine, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, validateSubject, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
|
@@ -14,7 +14,7 @@ interface ResolvedDomain {
|
|
|
14
14
|
}
|
|
15
15
|
interface AttestationPayload {
|
|
16
16
|
attestation_id: string;
|
|
17
|
-
version: '0.3' | '0.4';
|
|
17
|
+
version: '0.3' | '0.4' | '0.5';
|
|
18
18
|
profile_id: string;
|
|
19
19
|
/** v0.3 (deprecated) — hash of the authorization frame */
|
|
20
20
|
frame_hash?: string;
|
|
@@ -23,8 +23,37 @@ interface AttestationPayload {
|
|
|
23
23
|
/** v0.4 — hash of the context parameters */
|
|
24
24
|
context_hash?: string;
|
|
25
25
|
execution_context_hash: string;
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* v0.4 (deprecated in v0.5) — domain-scoped owners. Optional so v0.5
|
|
28
|
+
* attestations that carry only `resolved_owners` remain valid. During the
|
|
29
|
+
* transition the AS emits BOTH `resolved_domains` (internal coverage) and
|
|
30
|
+
* `resolved_owners` (the v0.5 signed wire field).
|
|
31
|
+
*/
|
|
32
|
+
resolved_domains?: ResolvedDomain[];
|
|
33
|
+
/**
|
|
34
|
+
* v0.5 — the Decision Owner DIDs this attestation covers (person-centric
|
|
35
|
+
* model; replaces the abstract domain in `resolved_domains`). Carried in the
|
|
36
|
+
* signed payload so verifiers bind the action to the human(s) who authorized it.
|
|
37
|
+
*/
|
|
38
|
+
resolved_owners?: string[];
|
|
27
39
|
gate_content_hashes: Record<string, string>;
|
|
40
|
+
/**
|
|
41
|
+
* v0.5 (companion spec `intent-disclosure@0.1`) — present iff the attestation
|
|
42
|
+
* carries an encrypted-intent disclosure object. `sha256:`-prefixed hash that
|
|
43
|
+
* binds the disclosure's `intent_ciphertext` + `approvers_frozen` into the
|
|
44
|
+
* signed payload (see {@link computeIntentDisclosureHash}), so a compromised
|
|
45
|
+
* AS cannot swap the ciphertext/wrapped keys or alter the approver set
|
|
46
|
+
* without invalidating the attestation signature (companion invariant C2).
|
|
47
|
+
*/
|
|
48
|
+
intent_disclosure_hash?: string;
|
|
49
|
+
/**
|
|
50
|
+
* v0.6 (Identity Assurance) — optional signed overlay carrying the verified
|
|
51
|
+
* real-world identity of the Decision Owner(s), one entry per owner. Present
|
|
52
|
+
* only when identity is disclosed; an attestation with no `subjects` renders
|
|
53
|
+
* as `low` (pseudonymous, no name). See {@link Subject} and
|
|
54
|
+
* {@link deriveIdentityLine}.
|
|
55
|
+
*/
|
|
56
|
+
subjects?: Subject[];
|
|
28
57
|
/**
|
|
29
58
|
* v0.4 — commitment mode chosen by the decision owner at attestation time.
|
|
30
59
|
* - 'automatic': agent may invoke bounded tools without per-action review.
|
|
@@ -38,6 +67,38 @@ interface AttestationPayload {
|
|
|
38
67
|
issued_at: number;
|
|
39
68
|
expires_at: number;
|
|
40
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* v0.6 Identity Assurance — a signed overlay binding a Decision Owner's verified
|
|
72
|
+
* real-world identity to the attestation, gated by HOW the identity was verified.
|
|
73
|
+
*
|
|
74
|
+
* Two display levels (`assurance`): `low` discloses no name; `high` MAY disclose a
|
|
75
|
+
* name. At `high`, two trust roots: `as` (the AS operator vouches — valid only
|
|
76
|
+
* within its own domain) and `external` (an external eID such as EUDI — carries the
|
|
77
|
+
* owner's own signature, AS-independent). See review.md → "Identity Assurance".
|
|
78
|
+
*/
|
|
79
|
+
interface Subject {
|
|
80
|
+
/** The Decision Owner DID this subject describes (matches an entry in resolved_owners). */
|
|
81
|
+
did: string;
|
|
82
|
+
/** `low` → no name shown; `high` → the name MAY be shown. */
|
|
83
|
+
assurance: 'low' | 'high';
|
|
84
|
+
/** How identity was established. */
|
|
85
|
+
method: 'self_declared' | 'as_vouched' | 'eudi';
|
|
86
|
+
/** Who vouches: `self` (owner's claim), `as` (operator), `external` (eID scheme). */
|
|
87
|
+
trust_root: 'self' | 'as' | 'external';
|
|
88
|
+
/** Verifier id — the AS operator (as_vouched) or the eID scheme (eudi). Required at `high`. */
|
|
89
|
+
verifier?: string;
|
|
90
|
+
/** Disclosed attributes. `name` present ONLY at `assurance:"high"` and when disclosure is on. */
|
|
91
|
+
disclose?: {
|
|
92
|
+
name: string;
|
|
93
|
+
};
|
|
94
|
+
/** When the underlying verification was performed (unix seconds). */
|
|
95
|
+
verified_at?: number;
|
|
96
|
+
/**
|
|
97
|
+
* eudi only (Phase 2) — the owner's per-event wallet signature, making the
|
|
98
|
+
* identity claim non-repudiable independent of the AS. Null/absent otherwise.
|
|
99
|
+
*/
|
|
100
|
+
owner_signature?: string | null;
|
|
101
|
+
}
|
|
41
102
|
interface Attestation {
|
|
42
103
|
header: AttestationHeader;
|
|
43
104
|
payload: AttestationPayload;
|
|
@@ -518,6 +579,89 @@ declare function contentCanonicalBytes(kind: ContentBinding['kind'], content: Re
|
|
|
518
579
|
*/
|
|
519
580
|
declare function computeContentHash(binding: ContentBinding, content: Record<string, unknown> | string): string;
|
|
520
581
|
|
|
582
|
+
/**
|
|
583
|
+
* Intent hashing + intent-disclosure binding (HAP v0.5).
|
|
584
|
+
*
|
|
585
|
+
* Two shared, environment-independent hashes that the attester (gateway), the
|
|
586
|
+
* Authority Server, and any approver MUST compute identically:
|
|
587
|
+
*
|
|
588
|
+
* 1. {@link computeIntentHash} — `gate_content_hashes.intent`. The intent text
|
|
589
|
+
* is canonicalized (Unicode NFC, LF line endings, trailing-whitespace strip
|
|
590
|
+
* — the same rule as content-binding's `canonicalizeText`) before hashing,
|
|
591
|
+
* so independent multi-owner approvers reproduce an identical hash from the
|
|
592
|
+
* same logical statement. See protocol.md → "Intent canonicalization".
|
|
593
|
+
*
|
|
594
|
+
* 2. {@link computeIntentDisclosureHash} — `intent_disclosure_hash`, the C2
|
|
595
|
+
* binding from companion spec `intent-disclosure@0.1`. It commits the
|
|
596
|
+
* encrypted disclosure object (`intent_ciphertext` + `approvers_frozen`)
|
|
597
|
+
* into the SIGNED attestation payload, so a compromised AS cannot swap the
|
|
598
|
+
* ciphertext/wrapped keys or widen/shrink the approver set without breaking
|
|
599
|
+
* the attestation signature.
|
|
600
|
+
*
|
|
601
|
+
* Both produce `sha256:<hex>` to match the frame/bounds/context hash format.
|
|
602
|
+
*/
|
|
603
|
+
/**
|
|
604
|
+
* `gate_content_hashes.intent` for an intent statement.
|
|
605
|
+
* Canonicalizes the text (NFC / LF / trailing-whitespace strip) before hashing.
|
|
606
|
+
*/
|
|
607
|
+
declare function computeIntentHash(intentText: string): string;
|
|
608
|
+
/**
|
|
609
|
+
* The exact bytes `intent_disclosure_hash` is taken over, WITHOUT hashing —
|
|
610
|
+
* exposed so an implementer debugging a mismatch can inspect the serialization
|
|
611
|
+
* both sides must agree on:
|
|
612
|
+
*
|
|
613
|
+
* intent_ciphertext ‖ "\n" ‖ JCS(sort(approvers_frozen))
|
|
614
|
+
*
|
|
615
|
+
* where `intent_ciphertext` is the exact base64url string of the disclosure
|
|
616
|
+
* object, `sort` orders the approver DIDs by Unicode code point, and `JCS` is
|
|
617
|
+
* RFC 8785 canonicalization of the sorted array (via {@link canonicalize}).
|
|
618
|
+
*/
|
|
619
|
+
declare function intentDisclosureCanonicalBytes(intentCiphertext: string, approversFrozen: string[]): string;
|
|
620
|
+
/**
|
|
621
|
+
* `intent_disclosure_hash` — `sha256:<hex>` over
|
|
622
|
+
* {@link intentDisclosureCanonicalBytes}. Computed by the attester after
|
|
623
|
+
* encryption and signed into the attestation; recomputed by the AS (at
|
|
624
|
+
* issuance) and by each approver (on receipt) and compared, fail-closed.
|
|
625
|
+
*/
|
|
626
|
+
declare function computeIntentDisclosureHash(intentCiphertext: string, approversFrozen: string[]): string;
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Identity Assurance (HAP v0.6) — validation + footer derivation for the signed
|
|
630
|
+
* {@link Subject} overlay. See review.md → "Identity Assurance".
|
|
631
|
+
*
|
|
632
|
+
* Two pure helpers, the single source of truth for both the gateway footer and
|
|
633
|
+
* the AS verify page:
|
|
634
|
+
* - {@link validateSubject} — enforces the level/method/trust-root invariants.
|
|
635
|
+
* - {@link deriveIdentityLine} — the human-readable footer line for a subject.
|
|
636
|
+
*/
|
|
637
|
+
|
|
638
|
+
interface SubjectValidation {
|
|
639
|
+
valid: boolean;
|
|
640
|
+
errors: string[];
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Enforce the Identity-Assurance invariants on a single subject:
|
|
644
|
+
* - `self_declared` ⇒ `low` / `self`, no disclosed name.
|
|
645
|
+
* - `as_vouched` ⇒ `high` / `as`, `verifier` required.
|
|
646
|
+
* - `eudi` ⇒ `high` / `external`, `verifier` + `owner_signature` required.
|
|
647
|
+
* - `disclose.name` only at `assurance:"high"`.
|
|
648
|
+
*/
|
|
649
|
+
declare function validateSubject(subject: Subject): SubjectValidation;
|
|
650
|
+
/**
|
|
651
|
+
* The footer line for a subject — the ONE place this wording lives.
|
|
652
|
+
* The name appears only at `high` with a disclosed name; otherwise no name.
|
|
653
|
+
*
|
|
654
|
+
* - low / no disclosure → "Sent by an AI agent via «operator»"
|
|
655
|
+
* - high / as_vouched → "Sent by an AI agent of «name» — verified by «operator»"
|
|
656
|
+
* - high / eudi → "Sent by an AI agent of «name» — identity verified (EUDI)"
|
|
657
|
+
*
|
|
658
|
+
* `operatorName` is the rendered AS operator (e.g. "Suveren") — never hardcode it
|
|
659
|
+
* upstream; a different operator self-vouches under its own name.
|
|
660
|
+
*/
|
|
661
|
+
declare function deriveIdentityLine(subject: Subject | undefined | null, { operatorName }: {
|
|
662
|
+
operatorName: string;
|
|
663
|
+
}): string;
|
|
664
|
+
|
|
521
665
|
/**
|
|
522
666
|
* Frame Canonicalization for Agent Profiles
|
|
523
667
|
*
|
|
@@ -715,4 +859,4 @@ declare function listProfiles(): string[];
|
|
|
715
859
|
declare function getAllProfiles(): AgentProfile[];
|
|
716
860
|
declare function clearProfiles(): void;
|
|
717
861
|
|
|
718
|
-
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type ContentBinding, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, attestationId, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFrameHash, contentCanonicalBytes, decodeAttestationBlob, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
|
862
|
+
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type ContentBinding, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, type Subject, type SubjectValidation, attestationId, canonicalBounds, canonicalContext, canonicalFrame, canonicalize, canonicalizeText, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContentHash, computeContextHash, computeFrameHash, computeIntentDisclosureHash, computeIntentHash, contentCanonicalBytes, decodeAttestationBlob, deriveIdentityLine, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, validateSubject, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
|
@@ -42,18 +42,23 @@ __export(index_exports, {
|
|
|
42
42
|
computeContentHash: () => computeContentHash,
|
|
43
43
|
computeContextHash: () => computeContextHash,
|
|
44
44
|
computeFrameHash: () => computeFrameHash,
|
|
45
|
+
computeIntentDisclosureHash: () => computeIntentDisclosureHash,
|
|
46
|
+
computeIntentHash: () => computeIntentHash,
|
|
45
47
|
contentCanonicalBytes: () => contentCanonicalBytes,
|
|
46
48
|
decodeAttestationBlob: () => decodeAttestationBlob,
|
|
49
|
+
deriveIdentityLine: () => deriveIdentityLine,
|
|
47
50
|
encodeAttestationBlob: () => encodeAttestationBlob,
|
|
48
51
|
frameHash: () => frameHash,
|
|
49
52
|
getAllProfiles: () => getAllProfiles,
|
|
50
53
|
getProfile: () => getProfile,
|
|
54
|
+
intentDisclosureCanonicalBytes: () => intentDisclosureCanonicalBytes,
|
|
51
55
|
isV4Attestation: () => isV4Attestation,
|
|
52
56
|
listProfiles: () => listProfiles,
|
|
53
57
|
registerProfile: () => registerProfile,
|
|
54
58
|
validateBoundsParams: () => validateBoundsParams,
|
|
55
59
|
validateContextParams: () => validateContextParams,
|
|
56
60
|
validateFrameParams: () => validateFrameParams,
|
|
61
|
+
validateSubject: () => validateSubject,
|
|
57
62
|
verify: () => verify,
|
|
58
63
|
verifyAttestation: () => verifyAttestation,
|
|
59
64
|
verifyAttestationSignature: () => verifyAttestationSignature,
|
|
@@ -116,8 +121,62 @@ function computeContentHash(binding, content) {
|
|
|
116
121
|
return `sha256:${sha256Hex(contentCanonicalBytes(binding.kind, content))}`;
|
|
117
122
|
}
|
|
118
123
|
|
|
119
|
-
// src/
|
|
124
|
+
// src/intent-disclosure.ts
|
|
120
125
|
var import_crypto2 = require("crypto");
|
|
126
|
+
function sha256Hex2(bytes) {
|
|
127
|
+
return (0, import_crypto2.createHash)("sha256").update(bytes, "utf8").digest("hex");
|
|
128
|
+
}
|
|
129
|
+
function computeIntentHash(intentText) {
|
|
130
|
+
return `sha256:${sha256Hex2(canonicalizeText(intentText))}`;
|
|
131
|
+
}
|
|
132
|
+
function intentDisclosureCanonicalBytes(intentCiphertext, approversFrozen) {
|
|
133
|
+
const sorted = [...approversFrozen].sort();
|
|
134
|
+
return `${intentCiphertext}
|
|
135
|
+
${canonicalize(sorted)}`;
|
|
136
|
+
}
|
|
137
|
+
function computeIntentDisclosureHash(intentCiphertext, approversFrozen) {
|
|
138
|
+
return `sha256:${sha256Hex2(intentDisclosureCanonicalBytes(intentCiphertext, approversFrozen))}`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/identity.ts
|
|
142
|
+
function validateSubject(subject) {
|
|
143
|
+
const errors = [];
|
|
144
|
+
const { did, assurance, method, trust_root, verifier, disclose, owner_signature } = subject;
|
|
145
|
+
if (!did) errors.push("subject.did is required");
|
|
146
|
+
if (assurance === "low") {
|
|
147
|
+
if (method !== "self_declared") errors.push(`low assurance requires method "self_declared", got "${method}"`);
|
|
148
|
+
if (trust_root !== "self") errors.push(`low assurance requires trust_root "self", got "${trust_root}"`);
|
|
149
|
+
if (disclose) errors.push("low assurance MUST NOT disclose a name");
|
|
150
|
+
} else if (assurance === "high") {
|
|
151
|
+
if (method === "as_vouched") {
|
|
152
|
+
if (trust_root !== "as") errors.push('as_vouched requires trust_root "as"');
|
|
153
|
+
if (!verifier) errors.push("as_vouched requires a verifier");
|
|
154
|
+
} else if (method === "eudi") {
|
|
155
|
+
if (trust_root !== "external") errors.push('eudi requires trust_root "external"');
|
|
156
|
+
if (!verifier) errors.push("eudi requires a verifier");
|
|
157
|
+
if (!owner_signature) errors.push("eudi requires an owner_signature");
|
|
158
|
+
} else {
|
|
159
|
+
errors.push(`high assurance requires method "as_vouched" or "eudi", got "${method}"`);
|
|
160
|
+
}
|
|
161
|
+
if (disclose && typeof disclose.name !== "string") errors.push("disclose.name must be a string");
|
|
162
|
+
} else {
|
|
163
|
+
errors.push(`assurance must be "low" or "high", got "${assurance}"`);
|
|
164
|
+
}
|
|
165
|
+
return { valid: errors.length === 0, errors };
|
|
166
|
+
}
|
|
167
|
+
function deriveIdentityLine(subject, { operatorName }) {
|
|
168
|
+
const name = subject?.assurance === "high" ? subject.disclose?.name : void 0;
|
|
169
|
+
if (!name) {
|
|
170
|
+
return `Sent by an AI agent via ${operatorName}`;
|
|
171
|
+
}
|
|
172
|
+
if (subject.method === "eudi") {
|
|
173
|
+
return `Sent by an AI agent of ${name} \u2014 identity verified (EUDI)`;
|
|
174
|
+
}
|
|
175
|
+
return `Sent by an AI agent of ${name} \u2014 verified by ${operatorName}`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/frame.ts
|
|
179
|
+
var import_crypto3 = require("crypto");
|
|
121
180
|
function validateFrameParams(params, profile) {
|
|
122
181
|
const errors = [];
|
|
123
182
|
if (!profile.frameSchema) {
|
|
@@ -154,7 +213,7 @@ function canonicalFrame(params, profile) {
|
|
|
154
213
|
return lines.join("\n");
|
|
155
214
|
}
|
|
156
215
|
function frameHash(canonicalFrameString) {
|
|
157
|
-
const hash = (0,
|
|
216
|
+
const hash = (0, import_crypto3.createHash)("sha256").update(canonicalFrameString, "utf8").digest("hex");
|
|
158
217
|
return `sha256:${hash}`;
|
|
159
218
|
}
|
|
160
219
|
function computeFrameHash(params, profile) {
|
|
@@ -238,17 +297,17 @@ function canonicalContext(params, profile) {
|
|
|
238
297
|
}
|
|
239
298
|
function computeBoundsHash(params, profile) {
|
|
240
299
|
const canonical = canonicalBounds(params, profile);
|
|
241
|
-
const hash = (0,
|
|
300
|
+
const hash = (0, import_crypto3.createHash)("sha256").update(canonical, "utf8").digest("hex");
|
|
242
301
|
return `sha256:${hash}`;
|
|
243
302
|
}
|
|
244
303
|
function computeContextHash(params, profile) {
|
|
245
304
|
const canonical = canonicalContext(params, profile);
|
|
246
|
-
const hash = (0,
|
|
305
|
+
const hash = (0, import_crypto3.createHash)("sha256").update(canonical, "utf8").digest("hex");
|
|
247
306
|
return `sha256:${hash}`;
|
|
248
307
|
}
|
|
249
308
|
|
|
250
309
|
// src/attestation.ts
|
|
251
|
-
var
|
|
310
|
+
var import_crypto4 = require("crypto");
|
|
252
311
|
var ed = __toESM(require("@noble/ed25519"));
|
|
253
312
|
function decodeAttestationBlob(blob) {
|
|
254
313
|
try {
|
|
@@ -266,7 +325,7 @@ function encodeAttestationBlob(attestation) {
|
|
|
266
325
|
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
267
326
|
}
|
|
268
327
|
function attestationId(blob) {
|
|
269
|
-
const hash = (0,
|
|
328
|
+
const hash = (0, import_crypto4.createHash)("sha256").update(blob, "utf8").digest("hex");
|
|
270
329
|
return `sha256:${hash}`;
|
|
271
330
|
}
|
|
272
331
|
async function verifyAttestationSignature(attestation, publicKeyHex) {
|
|
@@ -396,11 +455,11 @@ async function verifyV3(request, profile, publicKeyHex, now, executionLog, error
|
|
|
396
455
|
try {
|
|
397
456
|
checkAttestationExpiry(attestation.payload, now);
|
|
398
457
|
} catch {
|
|
399
|
-
const domainNames = attestation.payload.resolved_domains.map((d) => d.domain).join(", ");
|
|
458
|
+
const domainNames = (attestation.payload.resolved_domains ?? []).map((d) => d.domain).join(", ");
|
|
400
459
|
errors.push({ code: "TTL_EXPIRED", message: `Attestation for domain "${domainNames}" has expired` });
|
|
401
460
|
continue;
|
|
402
461
|
}
|
|
403
|
-
for (const rd of attestation.payload.resolved_domains) {
|
|
462
|
+
for (const rd of attestation.payload.resolved_domains ?? []) {
|
|
404
463
|
coveredDomains.add(rd.domain);
|
|
405
464
|
}
|
|
406
465
|
}
|
|
@@ -475,11 +534,11 @@ async function verifyV4(request, profile, publicKeyHex, now, executionLog) {
|
|
|
475
534
|
try {
|
|
476
535
|
checkAttestationExpiry(attestation.payload, now);
|
|
477
536
|
} catch {
|
|
478
|
-
const domainNames = attestation.payload.resolved_domains.map((d) => d.domain).join(", ");
|
|
537
|
+
const domainNames = (attestation.payload.resolved_domains ?? []).map((d) => d.domain).join(", ");
|
|
479
538
|
errors.push({ code: "TTL_EXPIRED", message: `Attestation for domain "${domainNames}" has expired` });
|
|
480
539
|
continue;
|
|
481
540
|
}
|
|
482
|
-
for (const rd of attestation.payload.resolved_domains) {
|
|
541
|
+
for (const rd of attestation.payload.resolved_domains ?? []) {
|
|
483
542
|
coveredDomains.add(rd.domain);
|
|
484
543
|
}
|
|
485
544
|
}
|
|
@@ -783,18 +842,23 @@ function resolveCumulativeFields(request, profile, executionLog, now) {
|
|
|
783
842
|
computeContentHash,
|
|
784
843
|
computeContextHash,
|
|
785
844
|
computeFrameHash,
|
|
845
|
+
computeIntentDisclosureHash,
|
|
846
|
+
computeIntentHash,
|
|
786
847
|
contentCanonicalBytes,
|
|
787
848
|
decodeAttestationBlob,
|
|
849
|
+
deriveIdentityLine,
|
|
788
850
|
encodeAttestationBlob,
|
|
789
851
|
frameHash,
|
|
790
852
|
getAllProfiles,
|
|
791
853
|
getProfile,
|
|
854
|
+
intentDisclosureCanonicalBytes,
|
|
792
855
|
isV4Attestation,
|
|
793
856
|
listProfiles,
|
|
794
857
|
registerProfile,
|
|
795
858
|
validateBoundsParams,
|
|
796
859
|
validateContextParams,
|
|
797
860
|
validateFrameParams,
|
|
861
|
+
validateSubject,
|
|
798
862
|
verify,
|
|
799
863
|
verifyAttestation,
|
|
800
864
|
verifyAttestationSignature,
|