@terminal3/t3n-sdk 5.2.0 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -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 (`rtmr3_allowlist`).
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` are both non-empty
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 + RTMR3 allowlist
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 `{ unsafe_trust_server: true }`
752
- * opt-out for local dev / mock-signer nodes.
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
@@ -5221,6 +5256,35 @@ declare class SessionUsageReportClient {
5221
5256
  * org's usage.
5222
5257
  */
5223
5258
  getOrgUsageReport(input: OrgUsageReportInput): Promise<OrgUsageReport>;
5259
+ /**
5260
+ * Fetch how many calls an organisation's members and their agents have
5261
+ * completed so far this calendar year (UTC).
5262
+ *
5263
+ * Counted by CALLER, not by contract owner, so calls into the platform's own
5264
+ * system contracts count as the organisation's usage. Unsuccessful calls and
5265
+ * admin-contract dispatches are excluded, the latter so that reading this
5266
+ * number does not increase it.
5267
+ *
5268
+ * Refuses with `not_org_admin: ...` when the authenticated session DID is
5269
+ * not in the org's admin set, exactly as {@link getOrgUsageReport} does.
5270
+ */
5271
+ getOrgCallCountThisYear(orgDid: string): Promise<number>;
5272
+ /** As {@link getOrgCallCountThisYear}, for a given UTC calendar year. */
5273
+ getOrgCallCountForYear(orgDid: string, year: number): Promise<number>;
5274
+ /**
5275
+ * As {@link getOrgCallCountThisYear}, over an explicit `[fromMs, toMs)`
5276
+ * window in milliseconds.
5277
+ *
5278
+ * Pass whole UTC days (multiples of 86400000) unless you can live with a
5279
+ * figure wider than its label: the counter has day granularity, so the node
5280
+ * widens a ragged window to the days it touches and the count then includes
5281
+ * the hours either side of what was asked for.
5282
+ *
5283
+ * Throws when the window covers more active days than the node reads in one
5284
+ * call — roughly eleven years of unbroken daily use — rather than returning
5285
+ * the partial count the node reports. The year forms cannot reach that.
5286
+ */
5287
+ getOrgCallCountForWindow(orgDid: string, fromMs: number, toMs: number): Promise<number>;
5224
5288
  }
5225
5289
  /**
5226
5290
  * Construct a {@link SessionUsageReportClient} from a caller-owned
@@ -5359,7 +5423,9 @@ interface ConfigValidationResult {
5359
5423
  *
5360
5424
  * The SDK's attestation check (see `TrustAnchor`) needs a trusted source
5361
5425
  * for the expected cluster identity — the set of node peer IDs and the
5362
- * allow-listed RTMR3 image measurements. Without a trusted source, every
5426
+ * allow-listed RTMR1/RTMR3 image measurements (RTMR1 is the real rootfs
5427
+ * signal, RTMR3 is kept for backward compatibility — see `TrustAnchor`'s
5428
+ * own doc comment). Without a trusted source, every
5363
5429
  * caller has to hand-pin those values or fall back to
5364
5430
  * `{ unsafe_trust_server: true }`, which disables verification entirely.
5365
5431
  *
@@ -5375,8 +5441,9 @@ interface ConfigValidationResult {
5375
5441
  * can serve any bytes at the manifest URL, but cannot forge a signature
5376
5442
  * for a manifest naming their own node identities/measurements without
5377
5443
  * the operator's private key. The manifest only ever *narrows* trust to
5378
- * the real cluster — it never widens what the on-quote RTMR3 pinning and
5379
- * peer-id set-equality already enforce inside the WASM verifier.
5444
+ * the real cluster — it never widens what the on-quote RTMR1/RTMR3
5445
+ * pinning and peer-id set-equality already enforce inside the WASM
5446
+ * verifier.
5380
5447
  */
5381
5448
 
5382
5449
  /**
@@ -5391,8 +5458,14 @@ interface SignedTrustManifest {
5391
5458
  version: number;
5392
5459
  /** Base58 peer IDs of the expected cluster nodes. */
5393
5460
  peer_ids: string[];
5394
- /** Base64-encoded 48-byte RTMR3 measurements of the expected image(s). */
5461
+ /**
5462
+ * Base64-encoded 48-byte RTMR3 measurements of the expected image(s).
5463
+ * Kept for backward compatibility — see `TrustAnchor`'s doc comment
5464
+ * for why `rtmr1_allowlist` is the real rootfs-integrity signal.
5465
+ */
5395
5466
  rtmr3_allowlist: string[];
5467
+ /** Base64-encoded 48-byte RTMR1 measurements of the expected image(s). */
5468
+ rtmr1_allowlist: string[];
5396
5469
  /** RFC 3339 timestamp the manifest was signed. */
5397
5470
  signed_at: string;
5398
5471
  /** Hex secp256k1 signature (compact 64-byte r‖s) over the canonical payload. */