@terminal3/t3n-sdk 5.2.0 → 5.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/dist/cli/index.js +1 -1
- package/dist/index.d.ts +55 -11
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -605,6 +605,11 @@ interface QuoteVerifyResult {
|
|
|
605
605
|
valid: boolean;
|
|
606
606
|
error?: string;
|
|
607
607
|
rtmr3?: string;
|
|
608
|
+
/**
|
|
609
|
+
* Base64-encoded RTMR1 (48 bytes). The real rootfs-integrity signal —
|
|
610
|
+
* see {@link TrustAnchor.rtmr1_allowlist}.
|
|
611
|
+
*/
|
|
612
|
+
rtmr1?: string;
|
|
608
613
|
report_data?: string;
|
|
609
614
|
}
|
|
610
615
|
interface PeerQuoteResult {
|
|
@@ -612,6 +617,8 @@ interface PeerQuoteResult {
|
|
|
612
617
|
valid: boolean;
|
|
613
618
|
error?: string;
|
|
614
619
|
rtmr3?: string;
|
|
620
|
+
/** See {@link QuoteVerifyResult.rtmr1}. */
|
|
621
|
+
rtmr1?: string;
|
|
615
622
|
}
|
|
616
623
|
interface DkgVerifyResult {
|
|
617
624
|
valid: boolean;
|
|
@@ -628,7 +635,15 @@ interface DkgVerifyResult {
|
|
|
628
635
|
* forge a complete, cryptographically-valid bundle for their own key
|
|
629
636
|
* (SP-003). The anchor is the independent ground truth that closes it:
|
|
630
637
|
* the bundle must describe *our* cluster (`expected_peer_ids`) running
|
|
631
|
-
* *our* image (`
|
|
638
|
+
* *our* image (`rtmr1_allowlist`).
|
|
639
|
+
*
|
|
640
|
+
* `rtmr3_allowlist` is checked too, for backward compatibility, but is
|
|
641
|
+
* **not** the real protection: `tee-init.sh` no longer extends RTMR3
|
|
642
|
+
* with a content hash, so RTMR3 is a fixed value every
|
|
643
|
+
* image reports identically. `rtmr1_allowlist` is what actually pins
|
|
644
|
+
* image identity now — RTMR1 is the TD loader measurement, which under
|
|
645
|
+
* Trinity's direct-UEFI UKI boot chain captures the UKI PE binary
|
|
646
|
+
* (embedding the dm-verity root hash in its kernel cmdline).
|
|
632
647
|
*/
|
|
633
648
|
interface TrustAnchor {
|
|
634
649
|
/**
|
|
@@ -641,9 +656,23 @@ interface TrustAnchor {
|
|
|
641
656
|
* Base64-encoded 48-byte RTMR3 measurements of the expected node
|
|
642
657
|
* image. Every quote's RTMR3 must be a member. **Must be non-empty.**
|
|
643
658
|
* An array (not a singleton) so a rolling deploy's two in-flight
|
|
644
|
-
* image measurements both verify.
|
|
659
|
+
* image measurements both verify. Kept for backward compatibility —
|
|
660
|
+
* see {@link TrustAnchor} above for why this alone no longer protects
|
|
661
|
+
* against SP-003.
|
|
645
662
|
*/
|
|
646
663
|
rtmr3_allowlist: string[];
|
|
664
|
+
/**
|
|
665
|
+
* Base64-encoded 48-byte RTMR1 measurements of the expected node
|
|
666
|
+
* image. Every quote's RTMR1 must be a member. **Must be non-empty.**
|
|
667
|
+
* This is the real SP-003 mitigation — see {@link TrustAnchor} above.
|
|
668
|
+
* Unlike RTMR3's old rolling-deploy-only reason for being an array
|
|
669
|
+
* (two in-flight image measurements), RTMR1 legitimately needs **more**
|
|
670
|
+
* entries than that: confirmed empirically, RTMR1 varies by physical
|
|
671
|
+
* host TDX firmware even for a single, unchanged image, so a fleet's
|
|
672
|
+
* full firmware diversity — not just old‖new — must all be represented
|
|
673
|
+
* here.
|
|
674
|
+
*/
|
|
675
|
+
rtmr1_allowlist: string[];
|
|
647
676
|
/**
|
|
648
677
|
* Optional provenance of the pinned values, for diagnostics only —
|
|
649
678
|
* never passed to the verifier and never part of any security
|
|
@@ -684,20 +713,25 @@ declare function isUnsafeTrustServer(anchor: TrustAnchorOrUnsafe): anchor is Uns
|
|
|
684
713
|
* @param attestationMsgB64 - Base64-encoded attestation message
|
|
685
714
|
* (for DKG: encaps_key || sorted_peer_id_bytes)
|
|
686
715
|
* @param expectedRtmr3B64 - Optional base64-encoded 48-byte RTMR3
|
|
716
|
+
* @param expectedRtmr1B64 - Optional base64-encoded 48-byte RTMR1 — the
|
|
717
|
+
* real rootfs-integrity signal (see {@link TrustAnchor})
|
|
687
718
|
* @returns Verification result with extracted measurements
|
|
688
719
|
*/
|
|
689
|
-
declare function verifyTdxQuote(quoteB64: string, attestationMsgB64: string, expectedRtmr3B64?: string): Promise<QuoteVerifyResult>;
|
|
720
|
+
declare function verifyTdxQuote(quoteB64: string, attestationMsgB64: string, expectedRtmr3B64?: string, expectedRtmr1B64?: string): Promise<QuoteVerifyResult>;
|
|
690
721
|
/**
|
|
691
722
|
* Verify a full DKG attestation bundle against a client-pinned
|
|
692
723
|
* {@link TrustAnchor}: multiple TDX quotes from all participating
|
|
693
724
|
* nodes, plus the binding between the quotes and the ML-KEM
|
|
694
725
|
* encapsulation key. Checks:
|
|
695
|
-
* 1. `expected_peer_ids` / `rtmr3_allowlist`
|
|
726
|
+
* 1. `expected_peer_ids` / `rtmr3_allowlist` / `rtmr1_allowlist` are
|
|
727
|
+
* all non-empty
|
|
696
728
|
* 2. the bundle's `peer_ids` equal the pinned set exactly
|
|
697
729
|
* 3. attestationMsg starts with encapsKey (server can't swap the key)
|
|
698
730
|
* 4. every quote's ECDSA signature chains to Intel's SGX root CA
|
|
699
731
|
* 5. every quote's report_data == keccak512(attestationMsg)
|
|
700
732
|
* 6. every quote's RTMR3 is a member of `rtmr3_allowlist`
|
|
733
|
+
* 7. every quote's RTMR1 is a member of `rtmr1_allowlist` — the real
|
|
734
|
+
* SP-003 mitigation (see {@link TrustAnchor})
|
|
701
735
|
*
|
|
702
736
|
* The anchor is **required**: there is no unauthenticated mode. Callers
|
|
703
737
|
* that genuinely want to trust the server must not call this at all —
|
|
@@ -710,7 +744,7 @@ declare function verifyTdxQuote(quoteB64: string, attestationMsgB64: string, exp
|
|
|
710
744
|
* (from `/status.dkg_attestation.attestation_msg`)
|
|
711
745
|
* @param peerIds - Base58 peer IDs as reported by the bundle
|
|
712
746
|
* @param quotes - Map of peer_id → base64-encoded TDX quote
|
|
713
|
-
* @param anchor - Client-pinned expected peer IDs +
|
|
747
|
+
* @param anchor - Client-pinned expected peer IDs + RTMR allowlists
|
|
714
748
|
* @returns Per-peer verification results and overall validity
|
|
715
749
|
*/
|
|
716
750
|
declare function verifyDkgAttestation(encapsKeyB64: string, attestationMsgB64: string, peerIds: string[], quotes: Record<string, string>, anchor: TrustAnchor): Promise<DkgVerifyResult>;
|
|
@@ -748,8 +782,9 @@ interface T3nClientConfig {
|
|
|
748
782
|
* **Required.** Client-pinned trust anchor the node's DKG attestation
|
|
749
783
|
* is verified against before the handshake trusts its ML-KEM key
|
|
750
784
|
* (SP-003). Either a {@link TrustAnchor} (`expected_peer_ids` +
|
|
751
|
-
* `rtmr3_allowlist`) or the explicit
|
|
752
|
-
* opt-out for local dev / mock-signer
|
|
785
|
+
* `rtmr1_allowlist` + `rtmr3_allowlist`) or the explicit
|
|
786
|
+
* `{ unsafe_trust_server: true }` opt-out for local dev / mock-signer
|
|
787
|
+
* nodes.
|
|
753
788
|
*
|
|
754
789
|
* Without this, a network attacker with their own TDX VM can hand the
|
|
755
790
|
* SDK a forged-but-valid attestation for a key it controls and read
|
|
@@ -5359,7 +5394,9 @@ interface ConfigValidationResult {
|
|
|
5359
5394
|
*
|
|
5360
5395
|
* The SDK's attestation check (see `TrustAnchor`) needs a trusted source
|
|
5361
5396
|
* for the expected cluster identity — the set of node peer IDs and the
|
|
5362
|
-
* allow-listed RTMR3 image measurements
|
|
5397
|
+
* allow-listed RTMR1/RTMR3 image measurements (RTMR1 is the real rootfs
|
|
5398
|
+
* signal, RTMR3 is kept for backward compatibility — see `TrustAnchor`'s
|
|
5399
|
+
* own doc comment). Without a trusted source, every
|
|
5363
5400
|
* caller has to hand-pin those values or fall back to
|
|
5364
5401
|
* `{ unsafe_trust_server: true }`, which disables verification entirely.
|
|
5365
5402
|
*
|
|
@@ -5375,8 +5412,9 @@ interface ConfigValidationResult {
|
|
|
5375
5412
|
* can serve any bytes at the manifest URL, but cannot forge a signature
|
|
5376
5413
|
* for a manifest naming their own node identities/measurements without
|
|
5377
5414
|
* the operator's private key. The manifest only ever *narrows* trust to
|
|
5378
|
-
* the real cluster — it never widens what the on-quote RTMR3
|
|
5379
|
-
* peer-id set-equality already enforce inside the WASM
|
|
5415
|
+
* the real cluster — it never widens what the on-quote RTMR1/RTMR3
|
|
5416
|
+
* pinning and peer-id set-equality already enforce inside the WASM
|
|
5417
|
+
* verifier.
|
|
5380
5418
|
*/
|
|
5381
5419
|
|
|
5382
5420
|
/**
|
|
@@ -5391,8 +5429,14 @@ interface SignedTrustManifest {
|
|
|
5391
5429
|
version: number;
|
|
5392
5430
|
/** Base58 peer IDs of the expected cluster nodes. */
|
|
5393
5431
|
peer_ids: string[];
|
|
5394
|
-
/**
|
|
5432
|
+
/**
|
|
5433
|
+
* Base64-encoded 48-byte RTMR3 measurements of the expected image(s).
|
|
5434
|
+
* Kept for backward compatibility — see `TrustAnchor`'s doc comment
|
|
5435
|
+
* for why `rtmr1_allowlist` is the real rootfs-integrity signal.
|
|
5436
|
+
*/
|
|
5395
5437
|
rtmr3_allowlist: string[];
|
|
5438
|
+
/** Base64-encoded 48-byte RTMR1 measurements of the expected image(s). */
|
|
5439
|
+
rtmr1_allowlist: string[];
|
|
5396
5440
|
/** RFC 3339 timestamp the manifest was signed. */
|
|
5397
5441
|
signed_at: string;
|
|
5398
5442
|
/** Hex secp256k1 signature (compact 64-byte r‖s) over the canonical payload. */
|