@suveren/gateway 0.40.0 → 0.41.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/control-plane/index.mjs +182 -37
- package/dist/mcp-server/http.mjs +355 -71
- package/dist/ui/assets/{index-C-lA_7Lt.js → index-CO-dj98E.js} +27 -27
- package/dist/ui/index.html +1 -1
- package/node_modules/@hap/core/README.md +3 -3
- package/node_modules/@hap/core/dist/index.d.mts +567 -123
- package/node_modules/@hap/core/dist/index.d.ts +567 -123
- package/node_modules/@hap/core/dist/index.js +869 -23
- package/node_modules/@hap/core/dist/index.mjs +829 -22
- package/node_modules/@hap/core/node_modules/@hpke/core/LICENSE +21 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/README.md +263 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/mod.d.ts +11 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/mod.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/mod.js +6 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/package.json +3 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/aesGcm.d.ts +80 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/aesGcm.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/aesGcm.js +167 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/exportOnly.d.ts +34 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/exportOnly.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/exportOnly.js +56 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/cipherSuiteNative.d.ts +145 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/cipherSuiteNative.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/cipherSuiteNative.js +326 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/encryptionContext.d.ts +15 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/encryptionContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/encryptionContext.js +68 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/exporterContext.d.ts +19 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/exporterContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/exporterContext.js +62 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/aeadParams.d.ts +17 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/aeadParams.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/aeadParams.js +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/cipherSuiteParams.d.ts +13 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/cipherSuiteParams.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/cipherSuiteParams.js +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encapsulator.d.ts +8 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encapsulator.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encapsulator.js +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encryptionContext.d.ts +40 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encryptionContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encryptionContext.js +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/exporter.d.ts +17 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/exporter.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/exporter.js +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/keyInfo.d.ts +7 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/keyInfo.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/keyInfo.js +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/responses.d.ts +10 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/responses.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/responses.js +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemNative.d.ts +26 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemNative.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemNative.js +112 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts +24 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.js +214 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts +24 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.js +214 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX25519.d.ts +38 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX25519.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX25519.js +66 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX448.d.ts +38 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX448.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX448.js +66 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/mutex.d.ts +5 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/mutex.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/mutex.js +28 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/native.d.ts +236 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/native.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/native.js +235 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/recipientContext.d.ts +6 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/recipientContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/recipientContext.js +38 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/senderContext.d.ts +11 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/senderContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/senderContext.js +45 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/utils/emitNotSupported.d.ts +2 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/utils/emitNotSupported.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/utils/emitNotSupported.js +6 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/package.json +46 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/mod.d.ts +11 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/mod.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/mod.js +47 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/package.json +3 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/aesGcm.d.ts +80 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/aesGcm.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/aesGcm.js +183 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/exportOnly.d.ts +34 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/exportOnly.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/exportOnly.js +70 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/cipherSuiteNative.d.ts +145 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/cipherSuiteNative.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/cipherSuiteNative.js +340 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/encryptionContext.d.ts +15 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/encryptionContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/encryptionContext.js +82 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/exporterContext.d.ts +19 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/exporterContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/exporterContext.js +78 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/aeadParams.d.ts +17 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/aeadParams.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/aeadParams.js +12 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/cipherSuiteParams.d.ts +13 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/cipherSuiteParams.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/cipherSuiteParams.js +12 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encapsulator.d.ts +8 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encapsulator.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encapsulator.js +12 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encryptionContext.d.ts +40 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encryptionContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encryptionContext.js +12 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/exporter.d.ts +17 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/exporter.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/exporter.js +12 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/keyInfo.d.ts +7 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/keyInfo.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/keyInfo.js +12 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/responses.d.ts +10 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/responses.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/responses.js +12 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemNative.d.ts +26 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemNative.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemNative.js +128 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts +24 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.js +228 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts +24 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.js +228 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX25519.d.ts +38 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX25519.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX25519.js +80 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX448.d.ts +38 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX448.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX448.js +80 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/mutex.d.ts +5 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/mutex.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/mutex.js +42 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/native.d.ts +236 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/native.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/native.js +255 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/recipientContext.d.ts +6 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/recipientContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/recipientContext.js +52 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/senderContext.d.ts +11 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/senderContext.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/senderContext.js +59 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/utils/emitNotSupported.d.ts +2 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/utils/emitNotSupported.d.ts.map +1 -0
- package/node_modules/@hap/core/node_modules/@hpke/core/script/src/utils/emitNotSupported.js +19 -0
- package/node_modules/@hap/core/package.json +2 -1
- package/node_modules/@hap/core/src/canonicalize.ts +9 -0
- package/node_modules/@hap/core/src/commitment-modes.ts +21 -9
- package/node_modules/@hap/core/src/errors.ts +24 -8
- package/node_modules/@hap/core/src/gatekeeper.ts +52 -8
- package/node_modules/@hap/core/src/index.ts +5 -1
- package/node_modules/@hap/core/src/issuance.ts +250 -0
- package/node_modules/@hap/core/src/mandate.ts +52 -14
- package/node_modules/@hap/core/src/owner-signature.ts +86 -39
- package/node_modules/@hap/core/src/profile.ts +45 -0
- package/node_modules/@hap/core/src/proposal-content.ts +219 -0
- package/node_modules/@hap/core/src/ticket-projection.ts +167 -0
- package/node_modules/@hap/core/src/ticket.ts +254 -20
- package/node_modules/@hap/core/src/types.ts +33 -5
- package/node_modules/@hap/core/src/verifier-policy.ts +178 -0
- package/node_modules/@hap/core/src/versions.ts +50 -19
- package/node_modules/@hono/node-server/dist/index.cjs +31 -6
- package/node_modules/@hono/node-server/dist/index.mjs +31 -6
- package/node_modules/@hono/node-server/package.json +1 -1
- package/node_modules/@hpke/common/esm/package.json +5 -1
- package/node_modules/@hpke/common/esm/src/curve/montgomery.d.ts +2 -2
- package/node_modules/@hpke/common/esm/src/curve/montgomery.d.ts.map +1 -1
- package/node_modules/@hpke/common/esm/src/curve/montgomery.js +41 -26
- package/node_modules/@hpke/common/esm/src/hash/sha3.d.ts.map +1 -1
- package/node_modules/@hpke/common/esm/src/hash/sha3.js +0 -15
- package/node_modules/@hpke/common/esm/src/kdfs/hkdf.d.ts +2 -1
- package/node_modules/@hpke/common/esm/src/kdfs/hkdf.d.ts.map +1 -1
- package/node_modules/@hpke/common/esm/src/kdfs/hkdf.js +12 -2
- package/node_modules/@hpke/common/esm/src/kems/dhkemPrimitives/xCurve.d.ts.map +1 -1
- package/node_modules/@hpke/common/esm/src/kems/dhkemPrimitives/xCurve.js +14 -3
- package/node_modules/@hpke/common/esm/src/utils/misc.d.ts +6 -0
- package/node_modules/@hpke/common/esm/src/utils/misc.d.ts.map +1 -1
- package/node_modules/@hpke/common/esm/src/utils/misc.js +43 -10
- package/node_modules/@hpke/common/esm/src/utils/noble.d.ts +1 -1
- package/node_modules/@hpke/common/esm/src/utils/noble.d.ts.map +1 -1
- package/node_modules/@hpke/common/esm/src/utils/noble.js +21 -10
- package/node_modules/@hpke/common/package.json +5 -1
- package/node_modules/@hpke/common/script/src/curve/montgomery.d.ts +2 -2
- package/node_modules/@hpke/common/script/src/curve/montgomery.d.ts.map +1 -1
- package/node_modules/@hpke/common/script/src/curve/montgomery.js +40 -25
- package/node_modules/@hpke/common/script/src/hash/sha3.d.ts.map +1 -1
- package/node_modules/@hpke/common/script/src/hash/sha3.js +0 -15
- package/node_modules/@hpke/common/script/src/kdfs/hkdf.d.ts +2 -1
- package/node_modules/@hpke/common/script/src/kdfs/hkdf.d.ts.map +1 -1
- package/node_modules/@hpke/common/script/src/kdfs/hkdf.js +12 -2
- package/node_modules/@hpke/common/script/src/kems/dhkemPrimitives/xCurve.d.ts.map +1 -1
- package/node_modules/@hpke/common/script/src/kems/dhkemPrimitives/xCurve.js +13 -2
- package/node_modules/@hpke/common/script/src/utils/misc.d.ts +6 -0
- package/node_modules/@hpke/common/script/src/utils/misc.d.ts.map +1 -1
- package/node_modules/@hpke/common/script/src/utils/misc.js +43 -9
- package/node_modules/@hpke/common/script/src/utils/noble.d.ts +1 -1
- package/node_modules/@hpke/common/script/src/utils/noble.d.ts.map +1 -1
- package/node_modules/@hpke/common/script/src/utils/noble.js +22 -11
- package/node_modules/@hpke/core/README.md +56 -56
- package/node_modules/@hpke/core/esm/package.json +2 -1
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts +3 -21
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -1
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.js +3 -201
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts +3 -21
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts.map +1 -1
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.js +3 -201
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/xCurveNative.d.ts +26 -0
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/xCurveNative.d.ts.map +1 -0
- package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/xCurveNative.js +216 -0
- package/node_modules/@hpke/core/package.json +6 -2
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts +3 -21
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -1
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.js +4 -202
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts +3 -21
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts.map +1 -1
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.js +4 -202
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/xCurveNative.d.ts +26 -0
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/xCurveNative.d.ts.map +1 -0
- package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/xCurveNative.js +230 -0
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/zlib.d.ts +752 -0
- package/node_modules/encodeurl/README.md +14 -0
- package/node_modules/encodeurl/index.js +5 -10
- package/node_modules/encodeurl/package.json +10 -6
- package/node_modules/express-rate-limit/dist/index.cjs +7 -3
- package/node_modules/express-rate-limit/dist/index.mjs +7 -3
- package/node_modules/express-rate-limit/package.json +10 -10
- package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +1 -1
- package/node_modules/hono/dist/cjs/context.js +1 -1
- package/node_modules/hono/dist/cjs/helper/css/common.js +3 -5
- package/node_modules/hono/dist/cjs/hono-base.js +4 -10
- package/node_modules/hono/dist/cjs/hono.js +0 -1
- package/node_modules/hono/dist/cjs/middleware/basic-auth/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/bearer-auth/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/csrf/index.js +2 -2
- package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +2 -2
- package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +2 -2
- package/node_modules/hono/dist/cjs/middleware/mount/index.js +4 -4
- package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +13 -11
- package/node_modules/hono/dist/cjs/router/reg-exp-router/prepared-router.js +4 -4
- package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +39 -51
- package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +15 -5
- package/node_modules/hono/dist/cjs/utils/jwt/jwt.js +2 -1
- package/node_modules/hono/dist/cjs/utils/mount.js +35 -0
- package/node_modules/hono/dist/cjs/utils/url.js +10 -0
- package/node_modules/hono/dist/cjs/validator/validator.js +1 -1
- package/node_modules/hono/dist/context.js +1 -1
- package/node_modules/hono/dist/helper/css/common.js +3 -5
- package/node_modules/hono/dist/hono-base.js +4 -10
- package/node_modules/hono/dist/hono.js +0 -1
- package/node_modules/hono/dist/middleware/basic-auth/index.js +1 -1
- package/node_modules/hono/dist/middleware/bearer-auth/index.js +1 -1
- package/node_modules/hono/dist/middleware/csrf/index.js +2 -2
- package/node_modules/hono/dist/middleware/jwk/jwk.js +2 -2
- package/node_modules/hono/dist/middleware/jwt/jwt.js +2 -2
- package/node_modules/hono/dist/middleware/language/language.js +1 -1
- package/node_modules/hono/dist/middleware/mount/index.js +4 -4
- package/node_modules/hono/dist/router/reg-exp-router/node.js +13 -11
- package/node_modules/hono/dist/router/reg-exp-router/prepared-router.js +5 -5
- package/node_modules/hono/dist/router/reg-exp-router/router.js +40 -52
- package/node_modules/hono/dist/router/reg-exp-router/trie.js +15 -5
- package/node_modules/hono/dist/types/middleware/mount/index.d.ts +1 -0
- package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +3 -3
- package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +1 -1
- package/node_modules/hono/dist/types/utils/mount.d.ts +4 -0
- package/node_modules/hono/dist/types/utils/url.d.ts +1 -0
- package/node_modules/hono/dist/utils/jwt/jwt.js +2 -1
- package/node_modules/hono/dist/utils/mount.js +34 -0
- package/node_modules/hono/dist/utils/url.js +10 -1
- package/node_modules/hono/dist/validator/validator.js +1 -1
- package/node_modules/hono/package.json +1 -1
- package/node_modules/ip-address/README.md +39 -39
- package/node_modules/ip-address/dist/ipv6.js +1 -1
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/node_modules/jose/dist/types/jwt/decrypt.d.ts +3 -0
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +2 -0
- package/node_modules/jose/dist/types/jwt/verify.d.ts +3 -0
- package/node_modules/jose/dist/types/types.d.ts +8 -0
- package/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -0
- package/node_modules/jose/dist/webapi/jwks/remote.js +3 -1
- package/node_modules/jose/dist/webapi/lib/deflate.js +2 -1
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +2 -1
- package/node_modules/jose/package.json +1 -1
- package/node_modules/qs/CHANGELOG.md +29 -22
- package/node_modules/qs/dist/qs.js +14 -14
- package/node_modules/qs/eslint.config.mjs +6 -0
- package/node_modules/qs/lib/stringify.js +1 -1
- package/node_modules/qs/package.json +5 -5
- package/node_modules/qs/test/stringify.js +74 -0
- package/package.json +2 -2
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -744,12 +744,19 @@ async function postInternal(path, body) {
|
|
|
744
744
|
clearTimeout(timer);
|
|
745
745
|
}
|
|
746
746
|
}
|
|
747
|
-
async function cpEncryptContent(toolArgs, recipientUserIds) {
|
|
748
|
-
const data = await postInternal("/internal/encrypt-content", { toolArgs, recipientUserIds });
|
|
747
|
+
async function cpEncryptContent(toolArgs, recipientUserIds, readers) {
|
|
748
|
+
const data = await postInternal("/internal/encrypt-content", { toolArgs, recipientUserIds, ...readers ? { readers } : {} });
|
|
749
749
|
return data;
|
|
750
750
|
}
|
|
751
751
|
async function cpDecryptContent(wire) {
|
|
752
|
-
const data = await postInternal("/internal/decrypt-content", {
|
|
752
|
+
const data = await postInternal("/internal/decrypt-content", {
|
|
753
|
+
ciphertext: wire.ciphertext,
|
|
754
|
+
// Both names: under a 0.8 mandate `encrypted_keys` is keyed by DID and
|
|
755
|
+
// `keys` by account id; the control plane finds this user's wrap by either.
|
|
756
|
+
keys: { ...wire.keys ?? {}, ...wire.encrypted_keys ?? {} },
|
|
757
|
+
// v0.8 rule 8: the control plane checks the decrypted content against the fingerprint.
|
|
758
|
+
...wire.proposalContentHash ? { proposalContentHash: wire.proposalContentHash } : wire.hash ? { hash: wire.hash } : {}
|
|
759
|
+
});
|
|
753
760
|
return data.plaintext;
|
|
754
761
|
}
|
|
755
762
|
|
|
@@ -983,7 +990,10 @@ var SPClient = class {
|
|
|
983
990
|
const { proposalContentHash, ...rest } = data;
|
|
984
991
|
const body = JSON.stringify({
|
|
985
992
|
...rest,
|
|
986
|
-
|
|
993
|
+
// v0.8 wire name is `proposalContentHash`; today's AS reads the
|
|
994
|
+
// Suveren-internal `proposal_content_hash`. Both are sent through the
|
|
995
|
+
// transition (same value); the AS of Track B reads the normative one.
|
|
996
|
+
...proposalContentHash ? { proposal_content_hash: proposalContentHash, proposalContentHash } : {}
|
|
987
997
|
});
|
|
988
998
|
const maxAttempts = data.idempotencyKey || data.proposalId ? this.receiptRetry.maxAttempts : 1;
|
|
989
999
|
let lastError;
|
|
@@ -1037,7 +1047,7 @@ var SPClient = class {
|
|
|
1037
1047
|
* read it; the caller reports who cannot.
|
|
1038
1048
|
*/
|
|
1039
1049
|
async submitProposal(data) {
|
|
1040
|
-
const { content, unreadableFor } = await cpEncryptContent(data.toolArgs, data.recipientUserIds);
|
|
1050
|
+
const { content, unreadableFor } = await cpEncryptContent(data.toolArgs, data.recipientUserIds, data.readers);
|
|
1041
1051
|
const res = await this.fetch("/api/proposals", {
|
|
1042
1052
|
method: "POST",
|
|
1043
1053
|
body: JSON.stringify({
|
|
@@ -1046,8 +1056,18 @@ var SPClient = class {
|
|
|
1046
1056
|
path: data.path,
|
|
1047
1057
|
pending_domains: data.pendingDomains,
|
|
1048
1058
|
tool: data.tool,
|
|
1059
|
+
// v0.8 normative object, beside the Suveren-internal fields today's AS
|
|
1060
|
+
// reads: `content` carries `encrypted_keys`/`readers`/`unreadable` with
|
|
1061
|
+
// the legacy `keys`/`hash`; the fingerprint travels as
|
|
1062
|
+
// `proposalContentHash`; the operation as `action` + `actionType`.
|
|
1049
1063
|
content,
|
|
1064
|
+
proposalContentHash: content.hash,
|
|
1065
|
+
action: data.tool,
|
|
1066
|
+
...data.actionType ? { actionType: data.actionType } : {},
|
|
1067
|
+
...data.mandateId ? { mandateId: data.mandateId } : {},
|
|
1068
|
+
...data.boundsHash ? { boundsHash: data.boundsHash } : {},
|
|
1050
1069
|
execution_context: data.executionContext,
|
|
1070
|
+
executionContext: data.executionContext,
|
|
1051
1071
|
// Phase 6
|
|
1052
1072
|
...data.pendingApprovers && data.pendingApprovers.length > 0 ? { pending_approvers: data.pendingApprovers } : {},
|
|
1053
1073
|
...data.createdBy ? { created_by: data.createdBy } : {}
|
|
@@ -1331,6 +1351,7 @@ var AttestationCache = class {
|
|
|
1331
1351
|
}
|
|
1332
1352
|
let signedCommitmentMode;
|
|
1333
1353
|
let subjects;
|
|
1354
|
+
let mandateId;
|
|
1334
1355
|
const firstBlob = result.attestations[0]?.blob;
|
|
1335
1356
|
if (firstBlob) {
|
|
1336
1357
|
try {
|
|
@@ -1341,6 +1362,39 @@ var AttestationCache = class {
|
|
|
1341
1362
|
signedCommitmentMode = void 0;
|
|
1342
1363
|
}
|
|
1343
1364
|
}
|
|
1365
|
+
const mandateIds = [];
|
|
1366
|
+
let mandateVersion;
|
|
1367
|
+
const nowSec4 = Math.floor(Date.now() / 1e3);
|
|
1368
|
+
for (const a of result.attestations) {
|
|
1369
|
+
if (!a.blob) continue;
|
|
1370
|
+
try {
|
|
1371
|
+
const id = decodeMandateBlob(a.blob).payload.mandate_id;
|
|
1372
|
+
if (typeof id !== "string") continue;
|
|
1373
|
+
if (!mandateIds.includes(id)) mandateIds.push(id);
|
|
1374
|
+
if (mandateId === void 0 && a.expires_at > nowSec4) {
|
|
1375
|
+
mandateId = id;
|
|
1376
|
+
const v = decodeMandateBlob(a.blob).payload.version;
|
|
1377
|
+
if (typeof v === "string") mandateVersion = v;
|
|
1378
|
+
}
|
|
1379
|
+
} catch {
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
mandateId ??= mandateIds[0];
|
|
1383
|
+
let proposalReaders;
|
|
1384
|
+
let latestIssuedAt = -Infinity;
|
|
1385
|
+
for (const a of result.attestations) {
|
|
1386
|
+
if (!a.blob) continue;
|
|
1387
|
+
try {
|
|
1388
|
+
const p = decodeMandateBlob(a.blob).payload;
|
|
1389
|
+
const ownerDid = p.mandate_owners?.[0]?.did;
|
|
1390
|
+
if (typeof p.version !== "string" || typeof ownerDid !== "string") continue;
|
|
1391
|
+
const issuedAt = typeof p.issued_at === "number" ? p.issued_at : 0;
|
|
1392
|
+
if (issuedAt < latestIssuedAt) continue;
|
|
1393
|
+
latestIssuedAt = issuedAt;
|
|
1394
|
+
proposalReaders = { version: p.version, ownerDid, deciders: [...p.above_cap_approvers ?? []] };
|
|
1395
|
+
} catch {
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1344
1398
|
const auth = {
|
|
1345
1399
|
authorizationId: result.authorization_id,
|
|
1346
1400
|
boundsHash: result.bounds_hash,
|
|
@@ -1362,6 +1416,10 @@ var AttestationCache = class {
|
|
|
1362
1416
|
attestedDomains: result.attested_domains ?? [],
|
|
1363
1417
|
deferredCommitmentDomains: result.deferred_commitment_domains ?? [],
|
|
1364
1418
|
signedCommitmentMode,
|
|
1419
|
+
mandateId,
|
|
1420
|
+
mandateIds,
|
|
1421
|
+
mandateVersion,
|
|
1422
|
+
proposalReaders,
|
|
1365
1423
|
subjects,
|
|
1366
1424
|
complete: result.complete,
|
|
1367
1425
|
groupId
|
|
@@ -2169,17 +2227,69 @@ var ExecutionJournal = class {
|
|
|
2169
2227
|
}
|
|
2170
2228
|
/** Look a ticket up. Always reads from disk — another process may have written. */
|
|
2171
2229
|
get(ticketId) {
|
|
2172
|
-
return this.load().entries.find((e) => e.ticketId === ticketId);
|
|
2230
|
+
return this.load().entries.find((e) => e.ticketId === ticketId && ticketId !== "");
|
|
2231
|
+
}
|
|
2232
|
+
/** The row for a request (idempotencyKey / proposalId), whatever its state. */
|
|
2233
|
+
getByRequest(requestKey) {
|
|
2234
|
+
return this.load().entries.find((e) => e.requestKey === requestKey);
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
* v0.8 — record that a ticket is about to be REQUESTED for this request,
|
|
2238
|
+
* before the request leaves the machine (*One execution per ticket*, rule 1).
|
|
2239
|
+
* A lost response then leaves a `requested` row: "the ticket never arrived,
|
|
2240
|
+
* so the action cannot have started" — the one case a replayed ticket may
|
|
2241
|
+
* run (rule 2). Idempotent for the same request key: a retry of the request
|
|
2242
|
+
* itself keeps the one row.
|
|
2243
|
+
*/
|
|
2244
|
+
requested(entry) {
|
|
2245
|
+
const file = this.load();
|
|
2246
|
+
if (file.entries.some((e) => e.requestKey === entry.requestKey)) return;
|
|
2247
|
+
file.entries.push({
|
|
2248
|
+
ticketId: "",
|
|
2249
|
+
...entry,
|
|
2250
|
+
state: "requested",
|
|
2251
|
+
startedAt: nowSec(),
|
|
2252
|
+
pid: process.pid
|
|
2253
|
+
});
|
|
2254
|
+
this.persist(file);
|
|
2173
2255
|
}
|
|
2174
2256
|
/**
|
|
2175
|
-
*
|
|
2176
|
-
*
|
|
2177
|
-
|
|
2257
|
+
* Close a `requested` row whose ticket was never issued (the AS refused).
|
|
2258
|
+
* Nothing ran; the row records that the request was judged and refused.
|
|
2259
|
+
*/
|
|
2260
|
+
refusedBeforeTicket(requestKey, outcome, detail) {
|
|
2261
|
+
const file = this.load();
|
|
2262
|
+
const row = file.entries.find((e) => e.requestKey === requestKey && e.state === "requested");
|
|
2263
|
+
if (!row) return;
|
|
2264
|
+
row.state = "failed";
|
|
2265
|
+
row.outcome = outcome;
|
|
2266
|
+
if (detail !== void 0) row.detail = detail.length > DETAIL_CAP ? detail.slice(0, DETAIL_CAP) : detail;
|
|
2267
|
+
row.finishedAt = nowSec();
|
|
2268
|
+
this.persist(file);
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* Claim the ticket for execution — the atomic move to `intent` ("started")
|
|
2272
|
+
* BEFORE the downstream call (*One execution per ticket*, rule 2). Refuses
|
|
2273
|
+
* if a row for that ticket already exists, whatever its state — deciding
|
|
2274
|
+
* what an existing row means is the caller's job, and it differs by state
|
|
2275
|
+
* (see commitments.ts). With a `requestKey`, a row for the SAME request that
|
|
2276
|
+
* is already `intent`/`done`/`failed` refuses too — a second ticket with a
|
|
2277
|
+
* new id for the same request is not executed again; a `requested` row is
|
|
2278
|
+
* upgraded in place.
|
|
2178
2279
|
*/
|
|
2179
2280
|
begin(entry) {
|
|
2180
2281
|
const file = this.load();
|
|
2181
|
-
const existing = file.entries.find((e) => e.ticketId === entry.ticketId);
|
|
2282
|
+
const existing = file.entries.find((e) => e.ticketId === entry.ticketId && e.ticketId !== "");
|
|
2182
2283
|
if (existing) return { ok: false, existing };
|
|
2284
|
+
if (entry.requestKey) {
|
|
2285
|
+
const sameRequest = file.entries.find((e) => e.requestKey === entry.requestKey);
|
|
2286
|
+
if (sameRequest && sameRequest.state !== "requested") return { ok: false, existing: sameRequest };
|
|
2287
|
+
if (sameRequest) {
|
|
2288
|
+
Object.assign(sameRequest, entry, { state: "intent", startedAt: nowSec(), pid: process.pid });
|
|
2289
|
+
this.persist(file);
|
|
2290
|
+
return { ok: true };
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2183
2293
|
file.entries.push({
|
|
2184
2294
|
...entry,
|
|
2185
2295
|
state: "intent",
|
|
@@ -2431,7 +2541,8 @@ var ProposalSubmissionStore = class {
|
|
|
2431
2541
|
authorizationId: entry.authorizationId,
|
|
2432
2542
|
profileId: entry.profileId,
|
|
2433
2543
|
submittedAt: nowSec3(),
|
|
2434
|
-
...entry.previewHash ? { previewHash: entry.previewHash } : {}
|
|
2544
|
+
...entry.previewHash ? { previewHash: entry.previewHash } : {},
|
|
2545
|
+
...entry.actionType ? { actionType: entry.actionType } : {}
|
|
2435
2546
|
});
|
|
2436
2547
|
this.persist(file);
|
|
2437
2548
|
}
|
|
@@ -3230,7 +3341,7 @@ var ReportStore = class {
|
|
|
3230
3341
|
};
|
|
3231
3342
|
|
|
3232
3343
|
// src/lib/shared-state.ts
|
|
3233
|
-
import {
|
|
3344
|
+
import { SUPPORTED_VERSIONS } from "@hap/core";
|
|
3234
3345
|
var SharedState = class {
|
|
3235
3346
|
spClient;
|
|
3236
3347
|
cache;
|
|
@@ -3259,7 +3370,7 @@ var SharedState = class {
|
|
|
3259
3370
|
* again whenever the AS URL this process pairs with changes — which, in
|
|
3260
3371
|
* practice, only happens across a restart; see bin/http.ts's
|
|
3261
3372
|
* `repairIfAsUrlChanged`). Non-null means the AS this gateway is paired
|
|
3262
|
-
* with
|
|
3373
|
+
* with shares no version with SUPPORTED_VERSIONS among its
|
|
3263
3374
|
* `supportedVersions` — every gated tool call MUST refuse with this
|
|
3264
3375
|
* message rather than reach the AS at all (checked in tool-proxy.ts,
|
|
3265
3376
|
* before anything else). `null` until the first check completes, which
|
|
@@ -3269,6 +3380,16 @@ var SharedState = class {
|
|
|
3269
3380
|
* unreachable at boot must not permanently brick the gateway).
|
|
3270
3381
|
*/
|
|
3271
3382
|
asVersionRefusal = null;
|
|
3383
|
+
/** v0.8: whether the paired Authority Server lists 0.8 among its supportedVersions —
|
|
3384
|
+
* read once at start-up ({@link checkAsCompat}); false until known. Where the wire
|
|
3385
|
+
* shape differs between a 0.7 and a 0.8 AS (today: nothing), this is the switch. */
|
|
3386
|
+
asSpeaks08 = false;
|
|
3387
|
+
/** v0.8: the paired AS's supportedVersions as read at start-up; null until
|
|
3388
|
+
* known. A mandate whose signed version is not in it can no longer be
|
|
3389
|
+
* exercised (protocol.md → Version negotiation, rule 3: a v0.8 AS issues no
|
|
3390
|
+
* ticket against a v0.7 mandate) and is shown as needing to be signed again
|
|
3391
|
+
* before any call is refused for it. */
|
|
3392
|
+
asSupportedVersions = null;
|
|
3272
3393
|
/**
|
|
3273
3394
|
* @param dataDir Passed to the AttestationCache so it can enforce AS key
|
|
3274
3395
|
* pinning (as-pairing.ts), and to the SPClient so it can enforce opt-in
|
|
@@ -3309,8 +3430,11 @@ var SharedState = class {
|
|
|
3309
3430
|
return;
|
|
3310
3431
|
}
|
|
3311
3432
|
const supported = Array.isArray(compat.supportedVersions) ? compat.supportedVersions : [];
|
|
3312
|
-
|
|
3313
|
-
|
|
3433
|
+
const common = SUPPORTED_VERSIONS.filter((v) => supported.includes(v));
|
|
3434
|
+
this.asSpeaks08 = supported.includes("0.8");
|
|
3435
|
+
this.asSupportedVersions = supported.filter((v) => typeof v === "string");
|
|
3436
|
+
if (common.length === 0) {
|
|
3437
|
+
this.asVersionRefusal = supported.length > 0 ? `This Authority Server supports protocol version(s) [${supported.join(", ")}], none of [${SUPPORTED_VERSIONS.join(", ")}] this gateway speaks. Update the gateway or the Authority Server so the two agree, then restart. No gated action can run until then.` : `This Authority Server's /api/as/compat does not name a supportedVersions list (it answered ${JSON.stringify(compat.protocolVersion ?? "unknown")}), so it cannot be confirmed to support any of protocol [${SUPPORTED_VERSIONS.join(", ")}]. Update the gateway or the Authority Server, then restart. No gated action can run until then.`;
|
|
3314
3438
|
console.error(`[Suveren MCP] ${this.asVersionRefusal}`);
|
|
3315
3439
|
} else {
|
|
3316
3440
|
this.asVersionRefusal = null;
|
|
@@ -3400,7 +3524,7 @@ var SharedState = class {
|
|
|
3400
3524
|
gateContent: gateEntry?.gateContent ?? null,
|
|
3401
3525
|
context: auth.context ?? gateEntry?.context,
|
|
3402
3526
|
contextHash: auth.contextHash ?? gateEntry?.contextHash,
|
|
3403
|
-
needsReapproval: this.cache.needsReapproval(auth.authorizationId)
|
|
3527
|
+
needsReapproval: this.cache.needsReapproval(auth.authorizationId) || this.asSupportedVersions !== null && this.asSupportedVersions.length > 0 && typeof auth.mandateVersion === "string" && !this.asSupportedVersions.includes(auth.mandateVersion)
|
|
3404
3528
|
};
|
|
3405
3529
|
}).filter((auth) => auth.gateContent !== null);
|
|
3406
3530
|
}
|
|
@@ -6418,7 +6542,13 @@ function attachTicketId(tool, args, ticketId) {
|
|
|
6418
6542
|
}
|
|
6419
6543
|
|
|
6420
6544
|
// src/lib/ticket-verify.ts
|
|
6421
|
-
import {
|
|
6545
|
+
import {
|
|
6546
|
+
verifyTicketSignature,
|
|
6547
|
+
verifyTicketAgainstRequest,
|
|
6548
|
+
verifyTicketApprovals,
|
|
6549
|
+
decodeMandateBlob as decodeMandateBlob2,
|
|
6550
|
+
HapError
|
|
6551
|
+
} from "@hap/core";
|
|
6422
6552
|
var TicketBindingMismatchError = class extends Error {
|
|
6423
6553
|
constructor(message) {
|
|
6424
6554
|
super(message);
|
|
@@ -6427,6 +6557,17 @@ var TicketBindingMismatchError = class extends Error {
|
|
|
6427
6557
|
};
|
|
6428
6558
|
var TICKET_MAX_AGE_SECONDS = 5 * 60;
|
|
6429
6559
|
var TICKET_MAX_CLOCK_SKEW_SECONDS = 30;
|
|
6560
|
+
function mandateForTicket(attestations, ticketMandateId) {
|
|
6561
|
+
if (typeof ticketMandateId !== "string") return void 0;
|
|
6562
|
+
for (const a of attestations ?? []) {
|
|
6563
|
+
try {
|
|
6564
|
+
const m = decodeMandateBlob2(a.blob);
|
|
6565
|
+
if (m.payload.mandate_id === ticketMandateId) return m;
|
|
6566
|
+
} catch {
|
|
6567
|
+
}
|
|
6568
|
+
}
|
|
6569
|
+
return void 0;
|
|
6570
|
+
}
|
|
6430
6571
|
async function verifyTicket(cache, receipt, expected) {
|
|
6431
6572
|
const trustedIssuer = await cache.getTrustedIssuer();
|
|
6432
6573
|
if (typeof receipt.signature !== "string" || !receipt.signature) {
|
|
@@ -6485,20 +6626,70 @@ async function verifyTicket(cache, receipt, expected) {
|
|
|
6485
6626
|
if (typeof timestamp !== "number" || !Number.isFinite(timestamp)) {
|
|
6486
6627
|
throw new TicketBindingMismatchError("Ticket carries no valid timestamp \u2014 refusing to execute.");
|
|
6487
6628
|
}
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6629
|
+
if (expected.replay !== true) {
|
|
6630
|
+
const nowSec4 = Math.floor(Date.now() / 1e3);
|
|
6631
|
+
const ageSec = nowSec4 - timestamp;
|
|
6632
|
+
if (ageSec > TICKET_MAX_AGE_SECONDS) {
|
|
6633
|
+
throw new TicketBindingMismatchError(
|
|
6634
|
+
`Ticket is ${ageSec}s old, older than the ${TICKET_MAX_AGE_SECONDS}s freshness window \u2014 refusing to execute.`
|
|
6635
|
+
);
|
|
6636
|
+
}
|
|
6637
|
+
if (ageSec < -TICKET_MAX_CLOCK_SKEW_SECONDS) {
|
|
6638
|
+
throw new TicketBindingMismatchError(
|
|
6639
|
+
`Ticket is timestamped ${-ageSec}s in the future, beyond the ${TICKET_MAX_CLOCK_SKEW_SECONDS}s clock-skew tolerance \u2014 refusing to execute.`
|
|
6640
|
+
);
|
|
6641
|
+
}
|
|
6494
6642
|
}
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6643
|
+
const ticket = receipt;
|
|
6644
|
+
let acceptedMandateId = expected.mandateId;
|
|
6645
|
+
if (expected.mandateIds && expected.mandateIds.length > 0) {
|
|
6646
|
+
if (typeof ticket.mandateId !== "string" || !expected.mandateIds.includes(ticket.mandateId)) {
|
|
6647
|
+
throw new TicketBindingMismatchError(
|
|
6648
|
+
`TICKET_REQUEST_MISMATCH: ticket mandateId ${String(ticket.mandateId)} is not a mandate of this grant \u2014 refusing to execute.`
|
|
6649
|
+
);
|
|
6650
|
+
}
|
|
6651
|
+
acceptedMandateId = ticket.mandateId;
|
|
6652
|
+
}
|
|
6653
|
+
try {
|
|
6654
|
+
verifyTicketAgainstRequest(
|
|
6655
|
+
ticket,
|
|
6656
|
+
{
|
|
6657
|
+
profileId: expected.profileId ?? ticket.profileId,
|
|
6658
|
+
actionType: expected.actionType ?? ticket.actionType,
|
|
6659
|
+
boundsHash: expected.boundsHash ?? ticket.boundsHash,
|
|
6660
|
+
executionContext: expected.executionContext ?? ticket.executionContext ?? {},
|
|
6661
|
+
mandateId: acceptedMandateId,
|
|
6662
|
+
idempotencyKey: expected.idempotencyKey,
|
|
6663
|
+
contentHash: expected.contentHash ?? ticket.contentHash,
|
|
6664
|
+
contentBinding: expected.contentBinding !== void 0 ? expected.contentBinding : ticket.contentBinding,
|
|
6665
|
+
proposalId: expected.proposalId ?? ticket.proposalId,
|
|
6666
|
+
// A v0.7 ticket has no `proposalContentHash` (today's Authority Server
|
|
6667
|
+
// binds the fingerprint on the request only); a v0.8 ticket MUST carry
|
|
6668
|
+
// the one this call sent.
|
|
6669
|
+
proposalContentHash: ticket.version === "0.7" ? ticket.proposalContentHash : expected.proposalContentHash ?? ticket.proposalContentHash
|
|
6670
|
+
},
|
|
6671
|
+
{ mandate: expected.mandate, replay: expected.replay === true }
|
|
6498
6672
|
);
|
|
6673
|
+
} catch (err) {
|
|
6674
|
+
if (err instanceof HapError) {
|
|
6675
|
+
throw new TicketBindingMismatchError(`${err.message} \u2014 refusing to execute.`);
|
|
6676
|
+
}
|
|
6677
|
+
throw err;
|
|
6678
|
+
}
|
|
6679
|
+
if (expected.mandate && (ticket.approvalSignature || (ticket.approvalSignatures?.length ?? 0) > 0)) {
|
|
6680
|
+
try {
|
|
6681
|
+
await verifyTicketApprovals(ticket, expected.mandate);
|
|
6682
|
+
} catch (err) {
|
|
6683
|
+
throw new TicketBindingMismatchError(
|
|
6684
|
+
`${err instanceof Error ? err.message : String(err)} \u2014 the approval does not cover this operation; refusing to execute.`
|
|
6685
|
+
);
|
|
6686
|
+
}
|
|
6499
6687
|
}
|
|
6500
6688
|
}
|
|
6501
6689
|
|
|
6690
|
+
// src/lib/tool-proxy.ts
|
|
6691
|
+
import { wireExecutionContext as hapWireExecutionContext, checkExecutionValues, missingSumFields } from "@hap/core";
|
|
6692
|
+
|
|
6502
6693
|
// src/lib/who-label.ts
|
|
6503
6694
|
var UNKNOWN_DECIDER = "the person";
|
|
6504
6695
|
async function resolveWhoLabel(archive, domainKey, userId) {
|
|
@@ -6720,21 +6911,8 @@ function profileMatches(profileId, shortName2) {
|
|
|
6720
6911
|
}
|
|
6721
6912
|
function wireExecutionContext(profileId, execution) {
|
|
6722
6913
|
const profile = getProfile5(profileId);
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
if (fields) {
|
|
6726
|
-
for (const fieldDef of Object.values(fields)) {
|
|
6727
|
-
const bt = fieldDef.boundType;
|
|
6728
|
-
if (bt && (bt.kind === "per_transaction" || bt.kind === "cumulative_sum") && bt.of) {
|
|
6729
|
-
allowed.add(bt.of);
|
|
6730
|
-
}
|
|
6731
|
-
}
|
|
6732
|
-
}
|
|
6733
|
-
const out = {};
|
|
6734
|
-
for (const [key, value] of Object.entries(execution)) {
|
|
6735
|
-
if (allowed.has(key)) out[key] = value;
|
|
6736
|
-
}
|
|
6737
|
-
return out;
|
|
6914
|
+
if (!profile) return {};
|
|
6915
|
+
return hapWireExecutionContext(execution, profile);
|
|
6738
6916
|
}
|
|
6739
6917
|
function countBoundsFor(profileId, actionType) {
|
|
6740
6918
|
const fields = getProfile5(profileId)?.boundsSchema?.fields;
|
|
@@ -6898,7 +7076,7 @@ function isStaleMandateRefusal(err) {
|
|
|
6898
7076
|
}
|
|
6899
7077
|
function isVersionUnsupportedRefusal(err) {
|
|
6900
7078
|
const errors = err.body?.errors;
|
|
6901
|
-
return
|
|
7079
|
+
return errors?.[0]?.code === "VERSION_UNSUPPORTED";
|
|
6902
7080
|
}
|
|
6903
7081
|
function createGatedToolHandlerInner(tool, integrationManager2, state2) {
|
|
6904
7082
|
if (!tool.gating || !tool.gating.profile) {
|
|
@@ -7004,7 +7182,8 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
|
|
|
7004
7182
|
ageBoundField
|
|
7005
7183
|
) : null;
|
|
7006
7184
|
const isTeam = typeof state2.cache?.isTeamGroup === "function" ? state2.cache.isTeamGroup(matchingAuths[0]?.groupId) : void 0;
|
|
7007
|
-
|
|
7185
|
+
const ceilingMarked = ageBoundField !== null && boundsSchema?.fields?.[ageBoundField]?.enforcedBy === "gatekeeper" && matchingAuths.some((a) => a.mandateVersion === "0.8");
|
|
7186
|
+
readMaxAge = (ceilingMarked || isTeam === true) && signedAge !== null ? localAge !== null ? Math.min(localAge, signedAge) : signedAge : localAge ?? signedAge;
|
|
7008
7187
|
if (readMaxAge === null) {
|
|
7009
7188
|
return denyRead(
|
|
7010
7189
|
state2,
|
|
@@ -7209,6 +7388,32 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
|
|
|
7209
7388
|
return { content: [{ type: "text", text: noMandateRefusal(tool.namespacedName, mandateLabel) }], isError: true };
|
|
7210
7389
|
}
|
|
7211
7390
|
if (matchingAuths.length === 0) return noEligibleMandate(refusals);
|
|
7391
|
+
{
|
|
7392
|
+
const profileDefs = [...new Set(matchingAuths.map((a) => a.profileId))].map((id) => getProfile5(id)).filter((d) => d !== void 0);
|
|
7393
|
+
for (const profileDef of profileDefs) {
|
|
7394
|
+
try {
|
|
7395
|
+
checkExecutionValues(hapWireExecutionContext(execution, profileDef), profileDef);
|
|
7396
|
+
} catch (err) {
|
|
7397
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
7398
|
+
const field = /executionContext\.([A-Za-z0-9_]+)/.exec(detail)?.[1];
|
|
7399
|
+
const bounds = field ? Object.entries(profileDef.boundsSchema?.fields ?? {}).filter(([, def]) => def.boundType?.of === field).map(([name]) => name) : [];
|
|
7400
|
+
recordBlocked(state2, tool, {
|
|
7401
|
+
kind: "bound",
|
|
7402
|
+
detail,
|
|
7403
|
+
...field ? { field } : {},
|
|
7404
|
+
who: "gateway",
|
|
7405
|
+
code: "MALFORMED_TICKET_REQUEST"
|
|
7406
|
+
});
|
|
7407
|
+
return {
|
|
7408
|
+
content: [{
|
|
7409
|
+
type: "text",
|
|
7410
|
+
text: `Blocked by Gatekeeper: ${field ? `"${field}" is not a number of zero or more` : "a value a bound reads is not a number of zero or more"}${bounds.length > 0 ? ` (read by ${bounds.join(", ")})` : ""} \u2014 ${detail}. Correct the request and try again.`
|
|
7411
|
+
}],
|
|
7412
|
+
isError: true
|
|
7413
|
+
};
|
|
7414
|
+
}
|
|
7415
|
+
}
|
|
7416
|
+
}
|
|
7212
7417
|
const blockingFails = await failedBlockingChecks(integrationManager2, tool.integrationId, tool.originalName, args);
|
|
7213
7418
|
if (blockingFails.length > 0) {
|
|
7214
7419
|
recordBlocked(state2, tool, {
|
|
@@ -7366,7 +7571,12 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
|
|
|
7366
7571
|
tool: tool.namespacedName,
|
|
7367
7572
|
toolArgs: enrichedArgs,
|
|
7368
7573
|
executionContext: wireExecCtx,
|
|
7369
|
-
recipientUserIds
|
|
7574
|
+
recipientUserIds,
|
|
7575
|
+
// v0.8 — the normative proposal object (protocol.md → Proposals).
|
|
7576
|
+
mandateId: auth.mandateId,
|
|
7577
|
+
boundsHash: auth.boundsHash,
|
|
7578
|
+
actionType: declaredActionType,
|
|
7579
|
+
...v08ProposalReaders(auth)
|
|
7370
7580
|
});
|
|
7371
7581
|
const previewHash = await computeSubmissionPreviewHash(
|
|
7372
7582
|
integrationManager2,
|
|
@@ -7381,7 +7591,8 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
|
|
|
7381
7591
|
executionContext: wireExecCtx,
|
|
7382
7592
|
authorizationId: authzId,
|
|
7383
7593
|
profileId: auth.profileId,
|
|
7384
|
-
previewHash
|
|
7594
|
+
previewHash,
|
|
7595
|
+
actionType: declaredActionType
|
|
7385
7596
|
});
|
|
7386
7597
|
return {
|
|
7387
7598
|
content: [{
|
|
@@ -7415,16 +7626,44 @@ Tell the person what you proposed and that it waits for their approval in the ga
|
|
|
7415
7626
|
finalArgs = finalized.args;
|
|
7416
7627
|
rebuildTransport = finalized.rebuildTransport;
|
|
7417
7628
|
}
|
|
7629
|
+
if (auth.signedCommitmentMode === "automatic" && auth.mandateVersion === "0.8") {
|
|
7630
|
+
const profileDef = getProfile5(auth.profileId);
|
|
7631
|
+
const missing = profileDef ? missingSumFields(wireExecutionContext(auth.profileId, execution), profileDef, declaredActionType) : [];
|
|
7632
|
+
if (missing.length > 0) {
|
|
7633
|
+
const detail = `"${missing[0].field}" is required by the bound ${missing[0].bound} for "${declaredActionType}" calls, but this call carries none.`;
|
|
7634
|
+
recordBlocked(state2, tool, {
|
|
7635
|
+
kind: "bound",
|
|
7636
|
+
detail,
|
|
7637
|
+
field: missing[0].field,
|
|
7638
|
+
who: "gateway",
|
|
7639
|
+
code: "BOUND_EXCEEDED"
|
|
7640
|
+
});
|
|
7641
|
+
return {
|
|
7642
|
+
content: [{
|
|
7643
|
+
type: "text",
|
|
7644
|
+
text: `Blocked by Gatekeeper: ${detail} Without it the spend cannot be counted against the mandate, so nothing ran.`
|
|
7645
|
+
}],
|
|
7646
|
+
isError: true
|
|
7647
|
+
};
|
|
7648
|
+
}
|
|
7649
|
+
}
|
|
7418
7650
|
let receiptId;
|
|
7651
|
+
let autoRequestKey;
|
|
7419
7652
|
try {
|
|
7420
7653
|
const actionType = declaredActionType;
|
|
7421
7654
|
const binding = computeContentBinding(auth.profileId, tool, finalArgs, actionType);
|
|
7422
7655
|
const idempotencyKey = randomUUID();
|
|
7423
7656
|
const wireExecCtx = wireExecutionContext(auth.profileId, execution);
|
|
7424
|
-
|
|
7657
|
+
state2.executionJournal?.requested?.({ requestKey: idempotencyKey, tool: tool.namespacedName, argsHash: hashToolArgs(finalArgs) });
|
|
7658
|
+
autoRequestKey = idempotencyKey;
|
|
7659
|
+
const { receipt, idempotent } = await state2.spClient.postReceipt({
|
|
7425
7660
|
authorizationId: authzId,
|
|
7426
7661
|
// Optional cross-check — the AS fails closed on a mismatch.
|
|
7427
7662
|
boundsHash: auth.boundsHash,
|
|
7663
|
+
// v0.8 — the mandate this call runs under, by its signed id, so a
|
|
7664
|
+
// revoked mandate and its replacement (same bounds_hash) cannot be
|
|
7665
|
+
// confused (Ticket Request Schema, rule 1).
|
|
7666
|
+
mandateId: auth.mandateId,
|
|
7428
7667
|
profileId: auth.profileId,
|
|
7429
7668
|
action: tool.namespacedName,
|
|
7430
7669
|
actionType,
|
|
@@ -7444,9 +7683,15 @@ Tell the person what you proposed and that it waits for their approval in the ga
|
|
|
7444
7683
|
executionContext: wireExecCtx,
|
|
7445
7684
|
authorizationId: authzId,
|
|
7446
7685
|
profileId: auth.profileId,
|
|
7686
|
+
actionType,
|
|
7687
|
+
boundsHash: auth.boundsHash,
|
|
7688
|
+
mandateId: auth.mandateId,
|
|
7689
|
+
mandateIds: auth.mandateIds,
|
|
7690
|
+
mandate: mandateForTicket(auth.attestations, receipt?.mandateId),
|
|
7447
7691
|
idempotencyKey,
|
|
7448
7692
|
contentHash: binding?.contentHash,
|
|
7449
|
-
contentBinding: binding?.contentBinding
|
|
7693
|
+
contentBinding: binding?.contentBinding,
|
|
7694
|
+
replay: idempotent
|
|
7450
7695
|
});
|
|
7451
7696
|
await state2.archiveReceipt(receipt, {
|
|
7452
7697
|
authorizationId: authzId,
|
|
@@ -7469,6 +7714,10 @@ Tell the person what you proposed and that it waits for their approval in the ga
|
|
|
7469
7714
|
sentArgs: finalArgs
|
|
7470
7715
|
});
|
|
7471
7716
|
} catch (err) {
|
|
7717
|
+
if (autoRequestKey && !receiptId) {
|
|
7718
|
+
const refusalCode = err instanceof SPReceiptError ? err.body?.errors?.[0]?.code ?? "TICKET_REFUSED" : "REQUEST_FAILED";
|
|
7719
|
+
state2.executionJournal?.refusedBeforeTicket?.(autoRequestKey, "as_refused", refusalCode);
|
|
7720
|
+
}
|
|
7472
7721
|
if (err instanceof AsKeyMismatchError || err instanceof TicketBindingMismatchError) {
|
|
7473
7722
|
void notifyControlPlane("as-key-mismatch");
|
|
7474
7723
|
return {
|
|
@@ -7499,7 +7748,7 @@ Tell the person what you proposed and that it waits for their approval in the ga
|
|
|
7499
7748
|
return {
|
|
7500
7749
|
content: [{
|
|
7501
7750
|
type: "text",
|
|
7502
|
-
text: `Blocked: mandate ${auth.authorizationId}
|
|
7751
|
+
text: `Blocked: mandate ${auth.authorizationId} must be signed again \u2014 the Authority Server no longer accepts its protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again; see list-authorizations). ${err.message}`
|
|
7503
7752
|
}],
|
|
7504
7753
|
isError: true
|
|
7505
7754
|
};
|
|
@@ -7570,7 +7819,12 @@ Tell the person what you proposed and that it waits for their approval in the ga
|
|
|
7570
7819
|
executionContext: wireExecCtx,
|
|
7571
7820
|
pendingApprovers: uniqueApprovers,
|
|
7572
7821
|
recipientUserIds,
|
|
7573
|
-
...ownerId ? { createdBy: ownerId } : {}
|
|
7822
|
+
...ownerId ? { createdBy: ownerId } : {},
|
|
7823
|
+
// v0.8 — the normative proposal object (protocol.md → Proposals).
|
|
7824
|
+
mandateId: auth.mandateId,
|
|
7825
|
+
boundsHash: auth.boundsHash,
|
|
7826
|
+
actionType: declaredActionType,
|
|
7827
|
+
...v08ProposalReaders(auth)
|
|
7574
7828
|
});
|
|
7575
7829
|
const previewHash = await computeSubmissionPreviewHash(
|
|
7576
7830
|
integrationManager2,
|
|
@@ -7585,7 +7839,8 @@ Tell the person what you proposed and that it waits for their approval in the ga
|
|
|
7585
7839
|
executionContext: wireExecCtx,
|
|
7586
7840
|
authorizationId: authzId,
|
|
7587
7841
|
profileId: auth.profileId,
|
|
7588
|
-
previewHash
|
|
7842
|
+
previewHash,
|
|
7843
|
+
actionType: declaredActionType
|
|
7589
7844
|
});
|
|
7590
7845
|
return {
|
|
7591
7846
|
content: [{
|
|
@@ -7651,6 +7906,7 @@ Proposal ID: ${proposal.id}. Use check-pending-commitments to track status.` + a
|
|
|
7651
7906
|
if (receiptId) {
|
|
7652
7907
|
const begun = state2.executionJournal.begin({
|
|
7653
7908
|
ticketId: receiptId,
|
|
7909
|
+
requestKey: autoRequestKey,
|
|
7654
7910
|
tool: tool.namespacedName,
|
|
7655
7911
|
argsHash: hashToolArgs(finalArgs)
|
|
7656
7912
|
});
|
|
@@ -7692,6 +7948,11 @@ function recordAutomaticOutcome(state2, ticketId, result, thrown) {
|
|
|
7692
7948
|
console.error(`[Suveren MCP] Could not record the execution result for ticket ${ticketId}:`, err);
|
|
7693
7949
|
}
|
|
7694
7950
|
}
|
|
7951
|
+
function v08ProposalReaders(auth) {
|
|
7952
|
+
const r = auth.proposalReaders;
|
|
7953
|
+
if (!r || r.version !== "0.8") return {};
|
|
7954
|
+
return { readers: { ownerDid: r.ownerDid, deciders: r.deciders } };
|
|
7955
|
+
}
|
|
7695
7956
|
function noMandateRefusal(toolName, profile) {
|
|
7696
7957
|
return `Refused: no mandate covers ${toolName} (${shortProfile(profile)}). Nothing was done. Ask the person to grant a ${shortProfile(profile)} mandate in the gateway, then try again. No ticket was requested.`;
|
|
7697
7958
|
}
|
|
@@ -7799,11 +8060,11 @@ function buildMandateBrief(opts) {
|
|
|
7799
8060
|
const needingReapproval = active.filter((a) => a.needsReapproval);
|
|
7800
8061
|
if (needingReapproval.length > 0) {
|
|
7801
8062
|
lines.push("");
|
|
7802
|
-
lines.push("===
|
|
8063
|
+
lines.push("=== MUST BE SIGNED AGAIN ===");
|
|
7803
8064
|
lines.push("");
|
|
7804
8065
|
for (const auth of needingReapproval) {
|
|
7805
8066
|
lines.push(
|
|
7806
|
-
`[${shortProfileName(auth.profileId)}] ${auth.authorizationId}: the Authority Server no longer
|
|
8067
|
+
`[${shortProfileName(auth.profileId)}] ${auth.authorizationId}: the Authority Server no longer accepts this mandate's protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again).`
|
|
7807
8068
|
);
|
|
7808
8069
|
}
|
|
7809
8070
|
lines.push("");
|
|
@@ -7963,10 +8224,10 @@ function listAuthorizationsHandler(state2, integrationManager2, contextDir) {
|
|
|
7963
8224
|
const earliestExpiry = Math.min(...auth.attestations.map((a) => a.expiresAt));
|
|
7964
8225
|
const remainingMin = Math.max(0, Math.round((earliestExpiry - now) / 60));
|
|
7965
8226
|
const boundsDesc = Object.entries(auth.frame).filter(([key]) => key !== "profile" && key !== "path").map(([key, value]) => `${key}: ${value}`).join(", ");
|
|
7966
|
-
const statusLabel = !auth.complete ? " (PENDING)" : auth.needsReapproval ? " (
|
|
8227
|
+
const statusLabel = !auth.complete ? " (PENDING)" : auth.needsReapproval ? " (MUST BE SIGNED AGAIN)" : "";
|
|
7967
8228
|
output2.push(`[${auth.path}] ${auth.profileId} (${remainingMin} min remaining)${statusLabel}`);
|
|
7968
8229
|
if (auth.needsReapproval) {
|
|
7969
|
-
output2.push(" The Authority Server no longer
|
|
8230
|
+
output2.push(" The Authority Server no longer accepts this mandate's protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again).");
|
|
7970
8231
|
}
|
|
7971
8232
|
output2.push("");
|
|
7972
8233
|
output2.push(` Bounds: ${boundsDesc}`);
|
|
@@ -8030,11 +8291,11 @@ function listAuthorizationsHandler(state2, integrationManager2, contextDir) {
|
|
|
8030
8291
|
const remainingMin = Math.max(0, Math.round((earliestExpiry - now) / 60));
|
|
8031
8292
|
const boundsDesc = Object.entries(auth.frame).filter(([key]) => key !== "profile" && key !== "path").map(([key, value]) => `${key}: ${value}`).join(", ");
|
|
8032
8293
|
if (auth.complete) {
|
|
8033
|
-
const statusLabel = auth.needsReapproval ? " (
|
|
8294
|
+
const statusLabel = auth.needsReapproval ? " (MUST BE SIGNED AGAIN)" : "";
|
|
8034
8295
|
const lines = [` [${auth.path}] ${auth.profileId} \u2014 ${remainingMin} min remaining${statusLabel}`];
|
|
8035
8296
|
lines.push(` Bounds: ${boundsDesc}`);
|
|
8036
8297
|
if (auth.needsReapproval) {
|
|
8037
|
-
lines.push(" The Authority Server no longer
|
|
8298
|
+
lines.push(" The Authority Server no longer accepts this mandate's protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again).");
|
|
8038
8299
|
}
|
|
8039
8300
|
if ((auth.deferredCommitmentDomains ?? []).length > 0) {
|
|
8040
8301
|
lines.push(" Mode: review (each action requires your approval)");
|
|
@@ -8268,12 +8529,6 @@ async function executeCommitted(proposal, state2, integrationManager2) {
|
|
|
8268
8529
|
const integrationId = proposal.tool.slice(0, sep);
|
|
8269
8530
|
const toolName = proposal.tool.slice(sep + 2);
|
|
8270
8531
|
const discovered = integrationManager2.getAllTools().find((t) => t.integrationId === integrationId && t.originalName === toolName);
|
|
8271
|
-
const proposalActionType = typeof proposal.executionContext.action_type === "string" ? proposal.executionContext.action_type : void 0;
|
|
8272
|
-
if (!proposalActionType) {
|
|
8273
|
-
console.error(
|
|
8274
|
-
`[Suveren MCP] Warning: proposal ${proposal.id} has no action_type in executionContext. Bounds check may be skipped. Fix the integration manifest for ${proposal.tool}.`
|
|
8275
|
-
);
|
|
8276
|
-
}
|
|
8277
8532
|
const cachedAuth = state2.cache.getAllAuthorizations().find((a) => a.authorizationId === proposal.authorizationId);
|
|
8278
8533
|
const submitted = state2.proposalSubmissions.get(proposal.id);
|
|
8279
8534
|
if (!submitted) {
|
|
@@ -8285,6 +8540,12 @@ async function executeCommitted(proposal, state2, integrationManager2) {
|
|
|
8285
8540
|
}
|
|
8286
8541
|
return { text: buildSkippedProposalNote(proposal.id), skipped: true };
|
|
8287
8542
|
}
|
|
8543
|
+
const proposalActionType = submitted.actionType ?? (typeof proposal.executionContext.action_type === "string" ? proposal.executionContext.action_type : void 0);
|
|
8544
|
+
if (!proposalActionType) {
|
|
8545
|
+
console.error(
|
|
8546
|
+
`[Suveren MCP] Warning: proposal ${proposal.id} has no action_type. Bounds check may be skipped. Fix the integration manifest for ${proposal.tool}.`
|
|
8547
|
+
);
|
|
8548
|
+
}
|
|
8288
8549
|
let toolArgs;
|
|
8289
8550
|
try {
|
|
8290
8551
|
toolArgs = await resolveProposalToolArgs(proposal);
|
|
@@ -8321,18 +8582,29 @@ async function executeCommitted(proposal, state2, integrationManager2) {
|
|
|
8321
8582
|
toolArgs,
|
|
8322
8583
|
proposalActionType
|
|
8323
8584
|
);
|
|
8585
|
+
state2.executionJournal?.requested?.({
|
|
8586
|
+
requestKey: proposal.id,
|
|
8587
|
+
proposalId: proposal.id,
|
|
8588
|
+
tool: proposal.tool,
|
|
8589
|
+
argsHash: hashToolArgs(toolArgs)
|
|
8590
|
+
});
|
|
8324
8591
|
const { receipt: r, idempotent } = await state2.spClient.postReceipt({
|
|
8325
8592
|
authorizationId: proposal.authorizationId,
|
|
8326
8593
|
// Optional cross-check — the AS fails closed on a mismatch. Parity
|
|
8327
8594
|
// with the automatic path (tool-proxy.ts).
|
|
8328
8595
|
boundsHash: cachedAuth?.boundsHash,
|
|
8596
|
+
// v0.8 — the mandate by its signed id (Ticket Request Schema, rule 1).
|
|
8597
|
+
mandateId: cachedAuth?.mandateId,
|
|
8329
8598
|
profileId: proposal.profileId,
|
|
8330
8599
|
action: proposal.tool,
|
|
8331
8600
|
actionType: proposalActionType,
|
|
8332
8601
|
executionContext: proposal.executionContext,
|
|
8333
8602
|
amount: typeof proposal.executionContext.amount === "number" ? proposal.executionContext.amount : void 0,
|
|
8334
8603
|
proposalId: proposal.id,
|
|
8335
|
-
|
|
8604
|
+
// v0.8 (Ticket Request Schema; Proposals, rule 1): the content itself
|
|
8605
|
+
// never travels on the ticket request — only its fingerprint below.
|
|
8606
|
+
// Today's AS matches by `proposal_content_hash` first, so dropping the
|
|
8607
|
+
// readable `toolArgs` it used to receive changes nothing it checks.
|
|
8336
8608
|
// PE1 — the fingerprint of what THIS gateway resolved (decrypted, or
|
|
8337
8609
|
// read plain on a legacy row) and is about to execute. The AS compares
|
|
8338
8610
|
// it against its own stored content_hash and refuses without echoing
|
|
@@ -8370,19 +8642,21 @@ async function executeCommitted(proposal, state2, integrationManager2) {
|
|
|
8370
8642
|
};
|
|
8371
8643
|
}
|
|
8372
8644
|
if (code === "PROPOSAL_REFUSED") {
|
|
8645
|
+
state2.executionJournal?.refusedBeforeTicket?.(proposal.id, "as_refused", `${code}: ${err.message}`);
|
|
8373
8646
|
return {
|
|
8374
8647
|
text: `Proposal ${proposal.id}: the Authority Server refused this proposal's ticket earlier \u2014 ${err.message} Nothing ran. Do not retry the same values; ask the person (e.g. for a higher limit).`,
|
|
8375
8648
|
isError: true
|
|
8376
8649
|
};
|
|
8377
8650
|
}
|
|
8378
|
-
if (
|
|
8651
|
+
if (code === "VERSION_UNSUPPORTED") {
|
|
8379
8652
|
state2.cache.markNeedsReapproval(proposal.authorizationId);
|
|
8380
8653
|
return {
|
|
8381
|
-
text: `Proposal ${proposal.id}: blocked \u2014 mandate ${proposal.authorizationId}
|
|
8654
|
+
text: `Proposal ${proposal.id}: blocked \u2014 mandate ${proposal.authorizationId} must be signed again \u2014 the Authority Server no longer accepts its protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again; see list-authorizations). ${err.message}`,
|
|
8382
8655
|
isError: true
|
|
8383
8656
|
};
|
|
8384
8657
|
}
|
|
8385
8658
|
if (proposal.id) {
|
|
8659
|
+
state2.executionJournal?.refusedBeforeTicket?.(proposal.id, "as_refused", `${code ?? "TICKET_REFUSED"}: ${err.message}`);
|
|
8386
8660
|
const asRefusedTicketId = `as_refused:${proposal.id}`;
|
|
8387
8661
|
const begun2 = state2.executionJournal.begin({
|
|
8388
8662
|
ticketId: asRefusedTicketId,
|
|
@@ -8412,6 +8686,7 @@ async function executeCommitted(proposal, state2, integrationManager2) {
|
|
|
8412
8686
|
}
|
|
8413
8687
|
const begun = state2.executionJournal.begin({
|
|
8414
8688
|
ticketId: receiptId,
|
|
8689
|
+
requestKey: proposal.id,
|
|
8415
8690
|
proposalId: proposal.id,
|
|
8416
8691
|
tool: proposal.tool,
|
|
8417
8692
|
argsHash: hashToolArgs(toolArgs)
|
|
@@ -8435,9 +8710,18 @@ async function executeCommitted(proposal, state2, integrationManager2) {
|
|
|
8435
8710
|
executionContext: proposal.executionContext,
|
|
8436
8711
|
authorizationId: proposal.authorizationId,
|
|
8437
8712
|
profileId: proposal.profileId,
|
|
8713
|
+
actionType: proposalActionType,
|
|
8714
|
+
boundsHash: cachedAuth?.boundsHash,
|
|
8715
|
+
mandateId: cachedAuth?.mandateId,
|
|
8716
|
+
mandateIds: cachedAuth?.mandateIds,
|
|
8717
|
+
// v0.8 — lets the ticket's version be checked against its mandate and
|
|
8718
|
+
// the approval signatures be verified under the deciders' own DIDs.
|
|
8719
|
+
mandate: mandateForTicket(cachedAuth?.attestations, receipt.mandateId),
|
|
8438
8720
|
proposalId: proposal.id,
|
|
8721
|
+
proposalContentHash: computeProposalContentHash(toolArgs),
|
|
8439
8722
|
contentHash: binding?.contentHash,
|
|
8440
|
-
contentBinding: binding?.contentBinding
|
|
8723
|
+
contentBinding: binding?.contentBinding,
|
|
8724
|
+
replay: replayed
|
|
8441
8725
|
});
|
|
8442
8726
|
await state2.archiveReceipt(receipt, {
|
|
8443
8727
|
authorizationId: proposal.authorizationId,
|
|
@@ -8577,7 +8861,7 @@ Result: ${resultText}` };
|
|
|
8577
8861
|
}
|
|
8578
8862
|
function localOutcomeOfExecuted(proposal, state2) {
|
|
8579
8863
|
const entry = state2.executionJournal?.findByProposal?.(proposal.id);
|
|
8580
|
-
if (!entry) return null;
|
|
8864
|
+
if (!entry || entry.state === "requested") return null;
|
|
8581
8865
|
const integration = proposal.tool.split("__")[0];
|
|
8582
8866
|
if (entry.state === "done") {
|
|
8583
8867
|
const stored = state2.executionResults?.get(proposal.id);
|
|
@@ -9010,7 +9294,7 @@ var AgentContactStore = class {
|
|
|
9010
9294
|
|
|
9011
9295
|
// src/lib/gate-content.ts
|
|
9012
9296
|
import { computeIntentHash } from "@hap/core";
|
|
9013
|
-
import { decodeMandateBlob as
|
|
9297
|
+
import { decodeMandateBlob as decodeMandateBlob3 } from "@hap/core";
|
|
9014
9298
|
function hashGateContent(text) {
|
|
9015
9299
|
return computeIntentHash(text);
|
|
9016
9300
|
}
|
|
@@ -9019,7 +9303,7 @@ function verifyGateContentHashes(content, auth) {
|
|
|
9019
9303
|
if (auth.attestations.length === 0) {
|
|
9020
9304
|
return { valid: false, errors: ["No attestations available to verify against"] };
|
|
9021
9305
|
}
|
|
9022
|
-
const attestation =
|
|
9306
|
+
const attestation = decodeMandateBlob3(auth.attestations[0].blob);
|
|
9023
9307
|
const expectedHashes = attestation.payload.gate_content_hashes;
|
|
9024
9308
|
if (!expectedHashes?.intent) {
|
|
9025
9309
|
return { valid: false, errors: ["Attestation does not contain intent hash"] };
|
|
@@ -11505,7 +11789,7 @@ function registerBuiltins(deps, factories = BUILTIN_FACTORIES) {
|
|
|
11505
11789
|
}
|
|
11506
11790
|
|
|
11507
11791
|
// bin/http.ts
|
|
11508
|
-
import { decodeMandateBlob as
|
|
11792
|
+
import { decodeMandateBlob as decodeMandateBlob4 } from "@hap/core";
|
|
11509
11793
|
|
|
11510
11794
|
// src/lib/committed-executor.ts
|
|
11511
11795
|
import { existsSync as existsSync21, mkdirSync as mkdirSync16, readFileSync as readFileSync22, unlinkSync as unlinkSync8, writeFileSync as writeFileSync16 } from "fs";
|
|
@@ -12170,7 +12454,7 @@ app.get("/internal/evidence", internalOnly, (_req, res) => {
|
|
|
12170
12454
|
...a,
|
|
12171
12455
|
attestations: a.attestations.map((att) => {
|
|
12172
12456
|
try {
|
|
12173
|
-
return { ...att, decoded:
|
|
12457
|
+
return { ...att, decoded: decodeMandateBlob4(att.blob) };
|
|
12174
12458
|
} catch {
|
|
12175
12459
|
return att;
|
|
12176
12460
|
}
|