@noy-db/hub 0.6.0-pre.20 → 0.6.0-pre.22
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/CHANGELOG.md +5437 -0
- package/dist/api-D6DBNTOS.js +20 -0
- package/dist/attestation/index.js +18 -18
- package/dist/{backup-K62BFMYK.js → backup-4PZAH67W.js} +12 -12
- package/dist/blobs/index.js +13 -13
- package/dist/broker/index.js +12 -12
- package/dist/cargo/index.js +31 -31
- package/dist/{chunk-IPDS2TYW.js → chunk-23XKHFNT.js} +4 -4
- package/dist/{chunk-GYUCRDAU.js → chunk-2DFE4TUE.js} +4 -4
- package/dist/{chunk-2IK6AC6A.js → chunk-2VMCJUK6.js} +5 -5
- package/dist/{chunk-DKYEVHZH.js → chunk-3ENNPCIW.js} +2 -2
- package/dist/{chunk-REL4OLWW.js → chunk-3TWEXEKX.js} +3 -3
- package/dist/{chunk-RNSC2ARR.js → chunk-47F6AI2K.js} +3 -3
- package/dist/{chunk-L2XQ776M.js → chunk-4BYZIQ5T.js} +2 -2
- package/dist/{chunk-NH2MST6J.js → chunk-4IPP2P74.js} +2 -2
- package/dist/{chunk-M4IKEOJS.js → chunk-4O52JH3C.js} +6 -6
- package/dist/{chunk-GDGTIWB4.js → chunk-4RZTW5JH.js} +2 -2
- package/dist/{chunk-WKD5ESK4.js → chunk-6QMOJTC6.js} +2 -2
- package/dist/{chunk-BTNKPDZM.js → chunk-6ZGDIN2D.js} +3 -3
- package/dist/{chunk-KDX6VEYV.js → chunk-7JOXCSDU.js} +2 -2
- package/dist/{chunk-VEX2BQVX.js → chunk-7LJA7T4W.js} +11 -3
- package/dist/{chunk-VEX2BQVX.js.map → chunk-7LJA7T4W.js.map} +1 -1
- package/dist/{chunk-S55DBWRC.js → chunk-A5YEUQOY.js} +2 -2
- package/dist/{chunk-5J5TTSGW.js → chunk-A66LJYFG.js} +7 -4
- package/dist/chunk-A66LJYFG.js.map +1 -0
- package/dist/{chunk-DJ23QZIN.js → chunk-AELW6OJZ.js} +2 -2
- package/dist/{chunk-YOT7D63X.js → chunk-AGETRKC5.js} +3 -3
- package/dist/{chunk-W6NFONOV.js → chunk-ANYVM4SX.js} +2 -2
- package/dist/{chunk-CADUYBQD.js → chunk-ATL3ZVXT.js} +2 -2
- package/dist/{chunk-GILI76SU.js → chunk-BFNBYT62.js} +2 -2
- package/dist/{chunk-N7YAQKAO.js → chunk-BPLSGN4X.js} +2 -2
- package/dist/{chunk-ZPMXYPBR.js → chunk-BXHG26KN.js} +2 -2
- package/dist/{chunk-437FDIHO.js → chunk-CW3VJARJ.js} +3 -3
- package/dist/{chunk-ODVIFBAQ.js → chunk-D5EXZVQC.js} +6 -6
- package/dist/{chunk-D5UDZANO.js → chunk-DIVPOJPV.js} +96 -8
- package/dist/chunk-DIVPOJPV.js.map +1 -0
- package/dist/{chunk-PZSS7MUM.js → chunk-DIYI32MG.js} +5 -5
- package/dist/{chunk-SFD2LL7G.js → chunk-DUUARUZI.js} +2 -2
- package/dist/{chunk-OWGEHDT2.js → chunk-ESXVNASI.js} +5 -5
- package/dist/{chunk-MNMYHZVU.js → chunk-F3BICEMK.js} +2 -2
- package/dist/{chunk-F5AJZC3U.js → chunk-F5IFR56V.js} +30 -11
- package/dist/chunk-F5IFR56V.js.map +1 -0
- package/dist/{chunk-RKDH6L53.js → chunk-FFESJQ5A.js} +303 -49
- package/dist/chunk-FFESJQ5A.js.map +1 -0
- package/dist/{chunk-HJRTFXAA.js → chunk-FFSQFH6D.js} +2 -2
- package/dist/{chunk-GT72D4FO.js → chunk-FGZ7GJXO.js} +3 -3
- package/dist/{chunk-WBNXZU42.js → chunk-FHEVZQQY.js} +4 -4
- package/dist/{chunk-VHVMJWM6.js → chunk-FKZI4NSG.js} +6 -6
- package/dist/{chunk-TENLCGYD.js → chunk-FUIG7QSS.js} +4 -4
- package/dist/{chunk-ZBDWKPBW.js → chunk-GWJJ5CK3.js} +5 -5
- package/dist/{chunk-MNUTPZRQ.js → chunk-H27DIXOV.js} +6 -6
- package/dist/{chunk-ZXW3X3DQ.js → chunk-H3SEW5HB.js} +7 -7
- package/dist/{chunk-ICCRAPWD.js → chunk-H6K24KLL.js} +4 -4
- package/dist/{chunk-DYASJSKI.js → chunk-HRSEAGLI.js} +3 -3
- package/dist/{chunk-6TXUVKPG.js → chunk-HUEG3YP4.js} +117 -92
- package/dist/chunk-HUEG3YP4.js.map +1 -0
- package/dist/{chunk-XGQGWZ6D.js → chunk-HZIIDYJV.js} +4 -4
- package/dist/{chunk-GQ3BX5EA.js → chunk-I3ISCYT7.js} +2 -2
- package/dist/{chunk-3Y4OFWQJ.js → chunk-IGNJOJEP.js} +1 -1
- package/dist/chunk-IGNJOJEP.js.map +1 -0
- package/dist/{chunk-N2HKBESK.js → chunk-IPA6ODWG.js} +4 -4
- package/dist/{chunk-OQLYMBJI.js → chunk-IUQPNAGR.js} +3 -3
- package/dist/{chunk-YVTADFTC.js → chunk-JPVJTTHU.js} +4 -4
- package/dist/{chunk-KUXTWVAR.js → chunk-JSTQGUE5.js} +43 -9
- package/dist/chunk-JSTQGUE5.js.map +1 -0
- package/dist/{chunk-JHO6FGZX.js → chunk-KMGAFLCK.js} +5 -5
- package/dist/{chunk-5EJQNA26.js → chunk-KYUKZIW5.js} +2 -2
- package/dist/{chunk-HGJC7I5F.js → chunk-L2YYIQYR.js} +2 -2
- package/dist/{chunk-PNAIDIP7.js → chunk-L3AM6EGU.js} +16 -9
- package/dist/{chunk-PNAIDIP7.js.map → chunk-L3AM6EGU.js.map} +1 -1
- package/dist/{chunk-KM6YR5XF.js → chunk-LLLSK7UQ.js} +2 -2
- package/dist/{chunk-QPIUFRUC.js → chunk-M3FKPVOU.js} +3 -3
- package/dist/{chunk-CV7WXCZD.js → chunk-M7VSXBUL.js} +10 -10
- package/dist/{chunk-APV42WPR.js → chunk-MBZFAJKM.js} +2 -2
- package/dist/{chunk-SG3OQCRG.js → chunk-MQFKH3ZJ.js} +3 -3
- package/dist/{chunk-ZWKF3CD3.js → chunk-NB2CKJ27.js} +2 -2
- package/dist/{chunk-HTHRCGWP.js → chunk-NCAMIRFB.js} +2 -2
- package/dist/{chunk-VH2W6BOG.js → chunk-NHXIFF4Y.js} +7 -7
- package/dist/{chunk-IGJCYUT5.js → chunk-NSITFOCJ.js} +1 -1
- package/dist/chunk-NSITFOCJ.js.map +1 -0
- package/dist/{chunk-VJ4B3ZXY.js → chunk-O5QXH7U7.js} +2 -2
- package/dist/{chunk-MQXYR65M.js → chunk-OBPL43F3.js} +6 -6
- package/dist/{chunk-HTMQBBF3.js → chunk-OCW3IM2F.js} +3 -3
- package/dist/{chunk-E6VDPBE3.js → chunk-OIW75CLW.js} +6 -6
- package/dist/{chunk-NRNTXBHT.js → chunk-OTHHO3KI.js} +2 -2
- package/dist/{chunk-4HVTRHSA.js → chunk-OZ5QBLEL.js} +6 -6
- package/dist/{chunk-ZVAFJQZB.js → chunk-PENPHA45.js} +2 -2
- package/dist/{chunk-CVYXIN5B.js → chunk-PGHSH4TY.js} +3 -3
- package/dist/{chunk-P7L3OQLL.js → chunk-PKUJ3JLQ.js} +25 -1
- package/dist/chunk-PKUJ3JLQ.js.map +1 -0
- package/dist/{chunk-IOURTXTM.js → chunk-PNXJV4OS.js} +79 -23
- package/dist/chunk-PNXJV4OS.js.map +1 -0
- package/dist/{chunk-A4K5GLE6.js → chunk-PWK3SSNB.js} +6 -6
- package/dist/{chunk-5JT4Y5UE.js → chunk-QK2QAMF7.js} +10 -10
- package/dist/{chunk-PG6PFMDC.js → chunk-QMJI5VHV.js} +2 -2
- package/dist/{chunk-RQY5UWEL.js → chunk-QTWWZ25B.js} +12 -12
- package/dist/{chunk-RSFG7XHM.js → chunk-REKDM67V.js} +2 -2
- package/dist/{chunk-2E2MKBMI.js → chunk-REQJLII3.js} +2 -2
- package/dist/{chunk-TC6MBEGH.js → chunk-RJYPFCID.js} +5 -5
- package/dist/{chunk-EJIVFOOQ.js → chunk-RT7CWTUG.js} +6 -6
- package/dist/{chunk-6S466CMQ.js → chunk-SRR22EW2.js} +8 -8
- package/dist/{chunk-C7WJNVJG.js → chunk-TKLQWOTY.js} +2 -2
- package/dist/{chunk-SA77BQ7F.js → chunk-UQUWSM33.js} +5 -5
- package/dist/{chunk-KBOPY6W2.js → chunk-VKYEEJJ2.js} +2 -2
- package/dist/{chunk-7RCZ436O.js → chunk-VMYXYFPX.js} +2 -2
- package/dist/{chunk-5BS6IQZZ.js → chunk-VWPJX5B3.js} +5 -5
- package/dist/{chunk-JIF3IBRK.js → chunk-VYLC5KAT.js} +2 -2
- package/dist/{chunk-OIIAXFKM.js → chunk-WFC2GHJG.js} +3 -3
- package/dist/{chunk-NYSD43OE.js → chunk-WKT7NNNR.js} +4 -4
- package/dist/{chunk-BP4I7IBK.js → chunk-WRGNEAUZ.js} +2 -2
- package/dist/{chunk-47ZFULEZ.js → chunk-WUNRUSBJ.js} +2 -2
- package/dist/{chunk-L6FSZFG7.js → chunk-XPTYXXMD.js} +3 -3
- package/dist/{chunk-EG6AQBYW.js → chunk-XZZIZ544.js} +8 -8
- package/dist/{chunk-RORE2GX2.js → chunk-YF3CIA6E.js} +2 -2
- package/dist/{chunk-AQF7JSQR.js → chunk-YOMI3ZCA.js} +2 -2
- package/dist/{chunk-A3NTKHDB.js → chunk-ZAZW5LLF.js} +2 -2
- package/dist/{chunk-32O2N2CH.js → chunk-ZUDIY7YP.js} +7 -7
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-PMDG3O36.js → classified-marker-EPL2NX3H.js} +3 -3
- package/dist/collection-facade-3DN4ETEP.js +45 -0
- package/dist/{computed-UHCBRILW.js → computed-UXN4AMI5.js} +3 -3
- package/dist/consent/index.js +9 -9
- package/dist/cover/index.js +9 -9
- package/dist/custody/index.js +11 -11
- package/dist/{dead-filter-777VWDER.js → dead-filter-56AYTNAO.js} +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/{delegation-4R5DU23X.js → delegation-MCCWCFZA.js} +11 -11
- package/dist/derivations/index.js +12 -12
- package/dist/derive-BSAF6N5X.js +22 -0
- package/dist/directory/index.js +10 -10
- package/dist/{dispatch-ASL257KG.js → dispatch-JM7X5BLP.js} +5 -5
- package/dist/{dispatch-3EN6YCCS.js → dispatch-UPZW4MAO.js} +18 -18
- package/dist/{enclave-ZJS5R5RH.js → enclave-CCXI3WEU.js} +11 -9
- package/dist/executor-6YQYFGHK.js +9 -0
- package/dist/executor-GLKPMISJ.js +9 -0
- package/dist/executor-ZEIX7Y7I.js +29 -0
- package/dist/export-accessible-SDIQEFHQ.js +23 -0
- package/dist/extract-partition-K232SO2V.js +38 -0
- package/dist/{fanout-sidecar-TFPWDOME.js → fanout-sidecar-2EHAV6UP.js} +9 -9
- package/dist/find-GKFC5753.js +11 -0
- package/dist/forget/index.js +9 -9
- package/dist/guards/index.js +7 -7
- package/dist/history/index.js +13 -13
- package/dist/i18n/index.js +14 -14
- package/dist/index.d.ts +2 -1
- package/dist/index.js +98 -94
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +4 -4
- package/dist/introspection/index.js +11 -11
- package/dist/issue-QTQYQJCB.js +19 -0
- package/dist/kernel/constants.d.ts +18 -0
- package/dist/kernel/enclave/index.d.ts +1 -0
- package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +88 -0
- package/dist/kernel/errors.d.ts +48 -1
- package/dist/kernel/noydb.d.ts +18 -1
- package/dist/kernel/query/builder.d.ts +36 -2
- package/dist/kernel/query/live.d.ts +31 -9
- package/dist/kernel/query/predicate.d.ts +9 -0
- package/dist/kernel/types.d.ts +20 -6
- package/dist/kernel/vault.d.ts +1 -1
- package/dist/{ledger-62CEPRPX.js → ledger-TZIDVW22.js} +11 -11
- package/dist/liberate-FOK7RFYQ.js +24 -0
- package/dist/{link-set-ZRYNUHN3.js → link-set-VOMRQB2H.js} +11 -11
- package/dist/{managed-secret-T2WB4O47.js → managed-secret-N6FWB5LX.js} +10 -10
- package/dist/materialized-views/index.js +22 -22
- package/dist/migrate-cek-UEO2EUWI.js +19 -0
- package/dist/migrate-cek-UEO2EUWI.js.map +1 -0
- package/dist/money/index.js +5 -5
- package/dist/noydb-3BBLBSHI.js +84 -0
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +12 -12
- package/dist/pod/index.js +58 -58
- package/dist/{pod-handle-UPLXOGIK.js → pod-handle-D6ZRTO4N.js} +9 -9
- package/dist/policy/index.js +10 -10
- package/dist/port/with/team-strategy.d.ts +5 -1
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-J4DEVNXK.js → post-register-XVGHYYSB.js} +6 -6
- package/dist/query/index.js +6 -6
- package/dist/reduce/index.js +6 -6
- package/dist/register-FVUE46K4.js +32 -0
- package/dist/registry-7PBVHSD5.js +19 -0
- package/dist/registry-CCXD57GV.js +18 -0
- package/dist/registry-K75FRKSU.js +9 -0
- package/dist/registry-KZYPKIOF.js +9 -0
- package/dist/request-withdrawal-WS7PXD7B.js +31 -0
- package/dist/{reveal-525XWQU2.js → reveal-Z62PLVJT.js} +6 -6
- package/dist/revoke-JH4VQTJ3.js +24 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +2 -2
- package/dist/sealed-record/index.js +12 -12
- package/dist/search/index.js +4 -4
- package/dist/{seed-SGIF3EN4.js → seed-R2JK2YQK.js} +11 -11
- package/dist/sequence/index.js +9 -9
- package/dist/session/index.js +9 -9
- package/dist/shadow/index.js +2 -2
- package/dist/signer-AFV6AXSN.js +25 -0
- package/dist/snapshots/index.js +10 -10
- package/dist/{stale-PQYPVCER.js → stale-FVK3WRMM.js} +10 -10
- package/dist/storage-EIM5HO2O.js +23 -0
- package/dist/{store-coordination-provider-TFHZLKHG.js → store-coordination-provider-HIPOZMC2.js} +10 -10
- package/dist/sync/index.js +10 -10
- package/dist/team/index.js +15 -15
- package/dist/tiers/index.js +11 -11
- package/dist/to/index.js +1 -1
- package/dist/transactions/index.js +3 -3
- package/dist/util/index.js +1 -1
- package/dist/vault-head/index.js +8 -8
- package/dist/{verify-J6DEOXP3.js → verify-KYICK5IW.js} +5 -5
- package/dist/walk-FV6JFWXV.js +21 -0
- package/dist/with-party/team/keyring.d.ts +132 -0
- package/dist/with-party/team/noydb-facade.d.ts +5 -1
- package/dist/with-party/team/roster-tag.d.ts +101 -0
- package/dist/with-shape/blobs/blob-set.d.ts +61 -9
- package/dist/withdraw-accessible-JYX3SPVY.js +28 -0
- package/package.json +4 -3
- package/dist/api-Z5VHH24A.js +0 -20
- package/dist/chunk-3Y4OFWQJ.js.map +0 -1
- package/dist/chunk-5J5TTSGW.js.map +0 -1
- package/dist/chunk-6TXUVKPG.js.map +0 -1
- package/dist/chunk-D5UDZANO.js.map +0 -1
- package/dist/chunk-F5AJZC3U.js.map +0 -1
- package/dist/chunk-IGJCYUT5.js.map +0 -1
- package/dist/chunk-IOURTXTM.js.map +0 -1
- package/dist/chunk-KUXTWVAR.js.map +0 -1
- package/dist/chunk-P7L3OQLL.js.map +0 -1
- package/dist/chunk-RKDH6L53.js.map +0 -1
- package/dist/collection-facade-ZJK5EB33.js +0 -45
- package/dist/derive-3WAS2G5T.js +0 -22
- package/dist/executor-GPM6DNWV.js +0 -9
- package/dist/executor-LJSMZ4IB.js +0 -9
- package/dist/executor-SHUVRZUJ.js +0 -29
- package/dist/export-accessible-GNY6DC6U.js +0 -23
- package/dist/extract-partition-BG3AF4NZ.js +0 -38
- package/dist/find-KX6OKHDP.js +0 -11
- package/dist/issue-PAUM7NCX.js +0 -19
- package/dist/liberate-I6AOLWXW.js +0 -24
- package/dist/noydb-SS6EN7TK.js +0 -84
- package/dist/register-UPD4GKBC.js +0 -32
- package/dist/registry-7KX2HWFS.js +0 -18
- package/dist/registry-PKYYEHEW.js +0 -9
- package/dist/registry-XHCYMD34.js +0 -19
- package/dist/registry-XIRTZHPC.js +0 -9
- package/dist/request-withdrawal-XZSESWZV.js +0 -31
- package/dist/revoke-QI7YHQ2B.js +0 -24
- package/dist/signer-BZWDPGGN.js +0 -25
- package/dist/storage-MJHKNQRO.js +0 -23
- package/dist/walk-BX4NSB5L.js +0 -21
- package/dist/withdraw-accessible-K4CPMH4C.js +0 -28
- /package/dist/{api-Z5VHH24A.js.map → api-D6DBNTOS.js.map} +0 -0
- /package/dist/{backup-K62BFMYK.js.map → backup-4PZAH67W.js.map} +0 -0
- /package/dist/{chunk-IPDS2TYW.js.map → chunk-23XKHFNT.js.map} +0 -0
- /package/dist/{chunk-GYUCRDAU.js.map → chunk-2DFE4TUE.js.map} +0 -0
- /package/dist/{chunk-2IK6AC6A.js.map → chunk-2VMCJUK6.js.map} +0 -0
- /package/dist/{chunk-DKYEVHZH.js.map → chunk-3ENNPCIW.js.map} +0 -0
- /package/dist/{chunk-REL4OLWW.js.map → chunk-3TWEXEKX.js.map} +0 -0
- /package/dist/{chunk-RNSC2ARR.js.map → chunk-47F6AI2K.js.map} +0 -0
- /package/dist/{chunk-L2XQ776M.js.map → chunk-4BYZIQ5T.js.map} +0 -0
- /package/dist/{chunk-NH2MST6J.js.map → chunk-4IPP2P74.js.map} +0 -0
- /package/dist/{chunk-M4IKEOJS.js.map → chunk-4O52JH3C.js.map} +0 -0
- /package/dist/{chunk-GDGTIWB4.js.map → chunk-4RZTW5JH.js.map} +0 -0
- /package/dist/{chunk-WKD5ESK4.js.map → chunk-6QMOJTC6.js.map} +0 -0
- /package/dist/{chunk-BTNKPDZM.js.map → chunk-6ZGDIN2D.js.map} +0 -0
- /package/dist/{chunk-KDX6VEYV.js.map → chunk-7JOXCSDU.js.map} +0 -0
- /package/dist/{chunk-S55DBWRC.js.map → chunk-A5YEUQOY.js.map} +0 -0
- /package/dist/{chunk-DJ23QZIN.js.map → chunk-AELW6OJZ.js.map} +0 -0
- /package/dist/{chunk-YOT7D63X.js.map → chunk-AGETRKC5.js.map} +0 -0
- /package/dist/{chunk-W6NFONOV.js.map → chunk-ANYVM4SX.js.map} +0 -0
- /package/dist/{chunk-CADUYBQD.js.map → chunk-ATL3ZVXT.js.map} +0 -0
- /package/dist/{chunk-GILI76SU.js.map → chunk-BFNBYT62.js.map} +0 -0
- /package/dist/{chunk-N7YAQKAO.js.map → chunk-BPLSGN4X.js.map} +0 -0
- /package/dist/{chunk-ZPMXYPBR.js.map → chunk-BXHG26KN.js.map} +0 -0
- /package/dist/{chunk-437FDIHO.js.map → chunk-CW3VJARJ.js.map} +0 -0
- /package/dist/{chunk-ODVIFBAQ.js.map → chunk-D5EXZVQC.js.map} +0 -0
- /package/dist/{chunk-PZSS7MUM.js.map → chunk-DIYI32MG.js.map} +0 -0
- /package/dist/{chunk-SFD2LL7G.js.map → chunk-DUUARUZI.js.map} +0 -0
- /package/dist/{chunk-OWGEHDT2.js.map → chunk-ESXVNASI.js.map} +0 -0
- /package/dist/{chunk-MNMYHZVU.js.map → chunk-F3BICEMK.js.map} +0 -0
- /package/dist/{chunk-HJRTFXAA.js.map → chunk-FFSQFH6D.js.map} +0 -0
- /package/dist/{chunk-GT72D4FO.js.map → chunk-FGZ7GJXO.js.map} +0 -0
- /package/dist/{chunk-WBNXZU42.js.map → chunk-FHEVZQQY.js.map} +0 -0
- /package/dist/{chunk-VHVMJWM6.js.map → chunk-FKZI4NSG.js.map} +0 -0
- /package/dist/{chunk-TENLCGYD.js.map → chunk-FUIG7QSS.js.map} +0 -0
- /package/dist/{chunk-ZBDWKPBW.js.map → chunk-GWJJ5CK3.js.map} +0 -0
- /package/dist/{chunk-MNUTPZRQ.js.map → chunk-H27DIXOV.js.map} +0 -0
- /package/dist/{chunk-ZXW3X3DQ.js.map → chunk-H3SEW5HB.js.map} +0 -0
- /package/dist/{chunk-ICCRAPWD.js.map → chunk-H6K24KLL.js.map} +0 -0
- /package/dist/{chunk-DYASJSKI.js.map → chunk-HRSEAGLI.js.map} +0 -0
- /package/dist/{chunk-XGQGWZ6D.js.map → chunk-HZIIDYJV.js.map} +0 -0
- /package/dist/{chunk-GQ3BX5EA.js.map → chunk-I3ISCYT7.js.map} +0 -0
- /package/dist/{chunk-N2HKBESK.js.map → chunk-IPA6ODWG.js.map} +0 -0
- /package/dist/{chunk-OQLYMBJI.js.map → chunk-IUQPNAGR.js.map} +0 -0
- /package/dist/{chunk-YVTADFTC.js.map → chunk-JPVJTTHU.js.map} +0 -0
- /package/dist/{chunk-JHO6FGZX.js.map → chunk-KMGAFLCK.js.map} +0 -0
- /package/dist/{chunk-5EJQNA26.js.map → chunk-KYUKZIW5.js.map} +0 -0
- /package/dist/{chunk-HGJC7I5F.js.map → chunk-L2YYIQYR.js.map} +0 -0
- /package/dist/{chunk-KM6YR5XF.js.map → chunk-LLLSK7UQ.js.map} +0 -0
- /package/dist/{chunk-QPIUFRUC.js.map → chunk-M3FKPVOU.js.map} +0 -0
- /package/dist/{chunk-CV7WXCZD.js.map → chunk-M7VSXBUL.js.map} +0 -0
- /package/dist/{chunk-APV42WPR.js.map → chunk-MBZFAJKM.js.map} +0 -0
- /package/dist/{chunk-SG3OQCRG.js.map → chunk-MQFKH3ZJ.js.map} +0 -0
- /package/dist/{chunk-ZWKF3CD3.js.map → chunk-NB2CKJ27.js.map} +0 -0
- /package/dist/{chunk-HTHRCGWP.js.map → chunk-NCAMIRFB.js.map} +0 -0
- /package/dist/{chunk-VH2W6BOG.js.map → chunk-NHXIFF4Y.js.map} +0 -0
- /package/dist/{chunk-VJ4B3ZXY.js.map → chunk-O5QXH7U7.js.map} +0 -0
- /package/dist/{chunk-MQXYR65M.js.map → chunk-OBPL43F3.js.map} +0 -0
- /package/dist/{chunk-HTMQBBF3.js.map → chunk-OCW3IM2F.js.map} +0 -0
- /package/dist/{chunk-E6VDPBE3.js.map → chunk-OIW75CLW.js.map} +0 -0
- /package/dist/{chunk-NRNTXBHT.js.map → chunk-OTHHO3KI.js.map} +0 -0
- /package/dist/{chunk-4HVTRHSA.js.map → chunk-OZ5QBLEL.js.map} +0 -0
- /package/dist/{chunk-ZVAFJQZB.js.map → chunk-PENPHA45.js.map} +0 -0
- /package/dist/{chunk-CVYXIN5B.js.map → chunk-PGHSH4TY.js.map} +0 -0
- /package/dist/{chunk-A4K5GLE6.js.map → chunk-PWK3SSNB.js.map} +0 -0
- /package/dist/{chunk-5JT4Y5UE.js.map → chunk-QK2QAMF7.js.map} +0 -0
- /package/dist/{chunk-PG6PFMDC.js.map → chunk-QMJI5VHV.js.map} +0 -0
- /package/dist/{chunk-RQY5UWEL.js.map → chunk-QTWWZ25B.js.map} +0 -0
- /package/dist/{chunk-RSFG7XHM.js.map → chunk-REKDM67V.js.map} +0 -0
- /package/dist/{chunk-2E2MKBMI.js.map → chunk-REQJLII3.js.map} +0 -0
- /package/dist/{chunk-TC6MBEGH.js.map → chunk-RJYPFCID.js.map} +0 -0
- /package/dist/{chunk-EJIVFOOQ.js.map → chunk-RT7CWTUG.js.map} +0 -0
- /package/dist/{chunk-6S466CMQ.js.map → chunk-SRR22EW2.js.map} +0 -0
- /package/dist/{chunk-C7WJNVJG.js.map → chunk-TKLQWOTY.js.map} +0 -0
- /package/dist/{chunk-SA77BQ7F.js.map → chunk-UQUWSM33.js.map} +0 -0
- /package/dist/{chunk-KBOPY6W2.js.map → chunk-VKYEEJJ2.js.map} +0 -0
- /package/dist/{chunk-7RCZ436O.js.map → chunk-VMYXYFPX.js.map} +0 -0
- /package/dist/{chunk-5BS6IQZZ.js.map → chunk-VWPJX5B3.js.map} +0 -0
- /package/dist/{chunk-JIF3IBRK.js.map → chunk-VYLC5KAT.js.map} +0 -0
- /package/dist/{chunk-OIIAXFKM.js.map → chunk-WFC2GHJG.js.map} +0 -0
- /package/dist/{chunk-NYSD43OE.js.map → chunk-WKT7NNNR.js.map} +0 -0
- /package/dist/{chunk-BP4I7IBK.js.map → chunk-WRGNEAUZ.js.map} +0 -0
- /package/dist/{chunk-47ZFULEZ.js.map → chunk-WUNRUSBJ.js.map} +0 -0
- /package/dist/{chunk-L6FSZFG7.js.map → chunk-XPTYXXMD.js.map} +0 -0
- /package/dist/{chunk-EG6AQBYW.js.map → chunk-XZZIZ544.js.map} +0 -0
- /package/dist/{chunk-RORE2GX2.js.map → chunk-YF3CIA6E.js.map} +0 -0
- /package/dist/{chunk-AQF7JSQR.js.map → chunk-YOMI3ZCA.js.map} +0 -0
- /package/dist/{chunk-A3NTKHDB.js.map → chunk-ZAZW5LLF.js.map} +0 -0
- /package/dist/{chunk-32O2N2CH.js.map → chunk-ZUDIY7YP.js.map} +0 -0
- /package/dist/{classified-marker-PMDG3O36.js.map → classified-marker-EPL2NX3H.js.map} +0 -0
- /package/dist/{collection-facade-ZJK5EB33.js.map → collection-facade-3DN4ETEP.js.map} +0 -0
- /package/dist/{computed-UHCBRILW.js.map → computed-UXN4AMI5.js.map} +0 -0
- /package/dist/{dead-filter-777VWDER.js.map → dead-filter-56AYTNAO.js.map} +0 -0
- /package/dist/{delegation-4R5DU23X.js.map → delegation-MCCWCFZA.js.map} +0 -0
- /package/dist/{derive-3WAS2G5T.js.map → derive-BSAF6N5X.js.map} +0 -0
- /package/dist/{dispatch-ASL257KG.js.map → dispatch-JM7X5BLP.js.map} +0 -0
- /package/dist/{dispatch-3EN6YCCS.js.map → dispatch-UPZW4MAO.js.map} +0 -0
- /package/dist/{enclave-ZJS5R5RH.js.map → enclave-CCXI3WEU.js.map} +0 -0
- /package/dist/{executor-GPM6DNWV.js.map → executor-6YQYFGHK.js.map} +0 -0
- /package/dist/{executor-LJSMZ4IB.js.map → executor-GLKPMISJ.js.map} +0 -0
- /package/dist/{executor-SHUVRZUJ.js.map → executor-ZEIX7Y7I.js.map} +0 -0
- /package/dist/{export-accessible-GNY6DC6U.js.map → export-accessible-SDIQEFHQ.js.map} +0 -0
- /package/dist/{extract-partition-BG3AF4NZ.js.map → extract-partition-K232SO2V.js.map} +0 -0
- /package/dist/{fanout-sidecar-TFPWDOME.js.map → fanout-sidecar-2EHAV6UP.js.map} +0 -0
- /package/dist/{find-KX6OKHDP.js.map → find-GKFC5753.js.map} +0 -0
- /package/dist/{issue-PAUM7NCX.js.map → issue-QTQYQJCB.js.map} +0 -0
- /package/dist/{ledger-62CEPRPX.js.map → ledger-TZIDVW22.js.map} +0 -0
- /package/dist/{liberate-I6AOLWXW.js.map → liberate-FOK7RFYQ.js.map} +0 -0
- /package/dist/{link-set-ZRYNUHN3.js.map → link-set-VOMRQB2H.js.map} +0 -0
- /package/dist/{managed-secret-T2WB4O47.js.map → managed-secret-N6FWB5LX.js.map} +0 -0
- /package/dist/{noydb-SS6EN7TK.js.map → noydb-3BBLBSHI.js.map} +0 -0
- /package/dist/{pod-handle-UPLXOGIK.js.map → pod-handle-D6ZRTO4N.js.map} +0 -0
- /package/dist/{post-register-J4DEVNXK.js.map → post-register-XVGHYYSB.js.map} +0 -0
- /package/dist/{register-UPD4GKBC.js.map → register-FVUE46K4.js.map} +0 -0
- /package/dist/{registry-7KX2HWFS.js.map → registry-7PBVHSD5.js.map} +0 -0
- /package/dist/{registry-PKYYEHEW.js.map → registry-CCXD57GV.js.map} +0 -0
- /package/dist/{registry-XHCYMD34.js.map → registry-K75FRKSU.js.map} +0 -0
- /package/dist/{registry-XIRTZHPC.js.map → registry-KZYPKIOF.js.map} +0 -0
- /package/dist/{request-withdrawal-XZSESWZV.js.map → request-withdrawal-WS7PXD7B.js.map} +0 -0
- /package/dist/{reveal-525XWQU2.js.map → reveal-Z62PLVJT.js.map} +0 -0
- /package/dist/{revoke-QI7YHQ2B.js.map → revoke-JH4VQTJ3.js.map} +0 -0
- /package/dist/{seed-SGIF3EN4.js.map → seed-R2JK2YQK.js.map} +0 -0
- /package/dist/{signer-BZWDPGGN.js.map → signer-AFV6AXSN.js.map} +0 -0
- /package/dist/{stale-PQYPVCER.js.map → stale-FVK3WRMM.js.map} +0 -0
- /package/dist/{storage-MJHKNQRO.js.map → storage-EIM5HO2O.js.map} +0 -0
- /package/dist/{store-coordination-provider-TFHZLKHG.js.map → store-coordination-provider-HIPOZMC2.js.map} +0 -0
- /package/dist/{verify-J6DEOXP3.js.map → verify-KYICK5IW.js.map} +0 -0
- /package/dist/{walk-BX4NSB5L.js.map → walk-FV6JFWXV.js.map} +0 -0
- /package/dist/{withdraw-accessible-K4CPMH4C.js.map → withdraw-accessible-JYX3SPVY.js.map} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NoydbStore, KeyringFile, KeyringAuthenticator, Role, Permissions, GrantOptions, RevokeOptions, UpdateUserOptions, UserInfo, EncryptedEnvelope, ExportCapability, ExportFormat, ImportCapability, VaultPolicyOnDisk, UserEnvelope } from '../../kernel/types.js';
|
|
2
2
|
import { type EnclaveKey, type EchoSecretParts } from '../../kernel/enclave/index.js';
|
|
3
|
+
import type { KeyringTamperedReason } from '../../kernel/errors.js';
|
|
3
4
|
import { type SecretPolicy, type EchoSecretPolicy } from '../../kernel/validation.js';
|
|
4
5
|
import type { DeviceSealProvider } from './device-seal.js';
|
|
5
6
|
/** In-memory representation of an unlocked keyring. */
|
|
@@ -77,6 +78,23 @@ export interface UnlockedKeyring {
|
|
|
77
78
|
}
|
|
78
79
|
/** Mint a fresh wrapped-canary string. Deterministic for a given KEK. */
|
|
79
80
|
export declare function mintKeyringCanary(kek: EnclaveKey): Promise<string>;
|
|
81
|
+
/**
|
|
82
|
+
* The vault roster key held by this keyring, or `null` when the keyring
|
|
83
|
+
* carries none.
|
|
84
|
+
*
|
|
85
|
+
* Null is expected on the resume-style paths (`kek: null` sessions, tier-3
|
|
86
|
+
* PIN resume, plaintext mode) — none of which may write a keyring file.
|
|
87
|
+
* Every stamping site null-guards this exactly as it guards `kek`: minting a
|
|
88
|
+
* file without a verifiable `roster_tag` would be worse than refusing, since
|
|
89
|
+
* it is indistinguishable on the next load from a store having stripped it.
|
|
90
|
+
*/
|
|
91
|
+
export declare function rosterKeyOf(keyring: UnlockedKeyring): EnclaveKey | null;
|
|
92
|
+
/**
|
|
93
|
+
* Shared wording for the stamping-site guards — mirrors the `kek` guard's shape.
|
|
94
|
+
* Exported so every roster-stamping site in the hub raises ONE error with one
|
|
95
|
+
* wording, rather than each hand-copying it (`peer-recover`, `liberate`).
|
|
96
|
+
*/
|
|
97
|
+
export declare function requireRosterKey(keyring: UnlockedKeyring, fn: string): EnclaveKey;
|
|
80
98
|
/** Options for {@link loadKeyring} (#846b). */
|
|
81
99
|
export interface LoadKeyringOptions {
|
|
82
100
|
/** The user whose keyring to unlock. */
|
|
@@ -173,6 +191,100 @@ export declare function createOwnerKeyring(store: NoydbStore, vault: string, opt
|
|
|
173
191
|
export declare function grant(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: GrantOptions): Promise<void>;
|
|
174
192
|
/** Revoke a user's access. Optionally rotate keys for affected collections. */
|
|
175
193
|
export declare function revoke(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: RevokeOptions): Promise<void>;
|
|
194
|
+
/** What {@link verifyRoster} found. */
|
|
195
|
+
export interface RosterVerifyResult {
|
|
196
|
+
/**
|
|
197
|
+
* How many `_keyring` files were examined.
|
|
198
|
+
*
|
|
199
|
+
* Reported first, and deliberately: "nothing unverified" is equally true of a
|
|
200
|
+
* sweep that examined nothing, and a roster check that silently covered zero
|
|
201
|
+
* members would look identical to a healthy vault. Same lesson as the vault
|
|
202
|
+
* head's `no-expectations` verdict (#1101).
|
|
203
|
+
*/
|
|
204
|
+
readonly checked: number;
|
|
205
|
+
/** The files that failed authentication, and why. */
|
|
206
|
+
readonly unverified: ReadonlyArray<{
|
|
207
|
+
readonly userId: string;
|
|
208
|
+
readonly reason: KeyringTamperedReason;
|
|
209
|
+
}>;
|
|
210
|
+
}
|
|
211
|
+
export declare function verifyRoster(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring): Promise<RosterVerifyResult>;
|
|
212
|
+
/** What {@link quarantineKeyring} did. */
|
|
213
|
+
export interface QuarantineResult {
|
|
214
|
+
readonly userId: string;
|
|
215
|
+
/** Why the file could not be authenticated — the justification for removing it. */
|
|
216
|
+
readonly reason: KeyringTamperedReason;
|
|
217
|
+
/** Collections re-keyed as part of the removal. */
|
|
218
|
+
readonly rotated: readonly string[];
|
|
219
|
+
/**
|
|
220
|
+
* (member, collection) pairs whose access the rotation dropped — the OTHER
|
|
221
|
+
* members, who must be re-granted.
|
|
222
|
+
*
|
|
223
|
+
* Passed through from `rotateKeys` rather than discarded, because a
|
|
224
|
+
* quarantine rotates broadly (see the scope note on the function) and so
|
|
225
|
+
* de-provisions more people than the one being removed. An operator who is
|
|
226
|
+
* not told this discovers it as unrelated `NoAccessError`s later.
|
|
227
|
+
*/
|
|
228
|
+
readonly needsRegrant: RotateResult['needsRegrant'];
|
|
229
|
+
/**
|
|
230
|
+
* OTHER members whose own files also failed authentication, found while
|
|
231
|
+
* rotating. One forged file is rarely the only one, and the operator is
|
|
232
|
+
* already holding the tool for them.
|
|
233
|
+
*/
|
|
234
|
+
readonly alsoUnverified: RotateResult['unverified'];
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Remove a `_keyring` file that cannot be authenticated, and re-key behind it
|
|
238
|
+
* (#1121).
|
|
239
|
+
*
|
|
240
|
+
* ## Why this is not a flag on `revoke`
|
|
241
|
+
*
|
|
242
|
+
* `revoke` reads the target's own `role` to decide whether the caller may
|
|
243
|
+
* revoke them, so it cannot act on a file it will not trust — which left a
|
|
244
|
+
* forged file removable only by editing the store by hand. Relaxing `revoke`
|
|
245
|
+
* conditionally would grow the safe path a parameter that turns it into the
|
|
246
|
+
* dangerous one; ADR 0003's standing rule is that if the implementation needs
|
|
247
|
+
* to weaken a guard, the design is wrong. This is a separate operation with its
|
|
248
|
+
* own contract, so `revoke`'s invariant stays absolute and the dangerous act is
|
|
249
|
+
* named at the call site rather than hidden in an option bag.
|
|
250
|
+
*
|
|
251
|
+
* ## The two properties that keep it from being a backdoor
|
|
252
|
+
*
|
|
253
|
+
* 1. **It refuses a file that verifies.** Otherwise it would delete any keyring
|
|
254
|
+
* while ignoring `canRevoke` — including an owner's, which `revoke` protects
|
|
255
|
+
* unconditionally.
|
|
256
|
+
* 2. **Because of (1) it can safely ignore the claimed `role` — and it must.**
|
|
257
|
+
* `canRevoke` refuses any target whose role reads `owner`, so a store that
|
|
258
|
+
* forged `"role":"owner"` onto its victim would otherwise make them
|
|
259
|
+
* permanently unremovable. Consulting the forged field is exactly the
|
|
260
|
+
* mistake this operation exists to avoid.
|
|
261
|
+
*
|
|
262
|
+
* Owner-only: the narrowest role that can always act, and quarantine
|
|
263
|
+
* deliberately consumes NO field of the file it is removing.
|
|
264
|
+
*
|
|
265
|
+
* ## Why it rotates, and why the scope comes from the CALLER
|
|
266
|
+
*
|
|
267
|
+
* Deleting the file is not a revocation — the store may decline the delete, and
|
|
268
|
+
* the member may already hold unwrapped DEKs. So this rotates, exactly as
|
|
269
|
+
* `revoke` does. The scope is every collection the CALLER holds, not the
|
|
270
|
+
* target's DEK map: that map is unauthenticated (#1115), so deriving the scope
|
|
271
|
+
* from it would let the store choose which collections survive a quarantine.
|
|
272
|
+
*
|
|
273
|
+
* ⚠️ **That is the security-correct scope, and it is NOT free.** An earlier
|
|
274
|
+
* draft of this comment called over-rotating "the safe direction"; a review
|
|
275
|
+
* probe disproved it. Rotation re-keys `store.list(vault, <name>)` plus the
|
|
276
|
+
* derived refs `rotateKeys` knows about, so a DEK slot whose ciphertext lives
|
|
277
|
+
* under a *different* collection name — `_blob`, whose data sits in
|
|
278
|
+
* `_blob_index`/`_blob_chunks`, and the `collection#tier` slots — is re-keyed
|
|
279
|
+
* without its data being re-encrypted, and that data then fails to open. That
|
|
280
|
+
* gap belongs to `rotateKeys` (it is reachable through an ordinary `revoke` of
|
|
281
|
+
* a whole-vault grantee, with no quarantine involved) and is filed as #1122,
|
|
282
|
+
* but a quarantine takes the maximal scope *unconditionally*, so it meets the
|
|
283
|
+
* gap every time rather than occasionally. Until that is fixed, treat a
|
|
284
|
+
* quarantine as an emergency operation with a real blast radius, and read
|
|
285
|
+
* `needsRegrant` afterwards.
|
|
286
|
+
*/
|
|
287
|
+
export declare function quarantineKeyring(store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, userId: string): Promise<QuarantineResult>;
|
|
176
288
|
/**
|
|
177
289
|
* Mutate `role`, `displayName`, and/or `permissions` on an existing
|
|
178
290
|
* keyring. Pure plaintext-header rewrite — no DEK rewrap, no KEK
|
|
@@ -222,6 +334,26 @@ export interface RotateResult {
|
|
|
222
334
|
readonly userId: string;
|
|
223
335
|
readonly collection: string;
|
|
224
336
|
}>;
|
|
337
|
+
/**
|
|
338
|
+
* Members skipped because their `_keyring` file failed roster verification
|
|
339
|
+
* (#1114).
|
|
340
|
+
*
|
|
341
|
+
* Rotation hands a member re-wrapped DEKs, so skipping one gives them
|
|
342
|
+
* **less**, never more: the file is left untouched and its wrappings for the
|
|
343
|
+
* rotated collections go stale. That is the same fail-closed end state as
|
|
344
|
+
* `needsRegrant`, but it needs a different remedy and so gets a different
|
|
345
|
+
* field — a `needsRegrant` entry is fixed by `grant()`, whereas one of these
|
|
346
|
+
* is a file that no longer authenticates and cannot be repaired by granting
|
|
347
|
+
* over it.
|
|
348
|
+
*
|
|
349
|
+
* Before this existed, one such file threw and took `revoke` and
|
|
350
|
+
* `rotateKeys` down vault-wide — the two operations most needed when a
|
|
351
|
+
* roster is suspect.
|
|
352
|
+
*/
|
|
353
|
+
readonly unverified: ReadonlyArray<{
|
|
354
|
+
readonly userId: string;
|
|
355
|
+
readonly reason: KeyringTamperedReason;
|
|
356
|
+
}>;
|
|
225
357
|
}
|
|
226
358
|
/** Options for {@link rotateKeys} (#846b — was a bare `string[]`). */
|
|
227
359
|
export interface RotateKeysOptions {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* Internal service — reached through `noydb.team.rotateSecret(...)` etc.
|
|
20
20
|
*/
|
|
21
21
|
import type { NoydbOptions, NoydbStore, KeyringAuthenticator } from '../../kernel/types.js';
|
|
22
|
-
import type { RotateResult, RotateKeysOptions } from './keyring.js';
|
|
22
|
+
import type { RotateResult, RotateKeysOptions, RosterVerifyResult, QuarantineResult } from './keyring.js';
|
|
23
23
|
import { type RotateSecretInput, type RecoverSecretInput, type RecoverSecretResult, type RotateRecoveryOptions, type RotateRecoveryResult, type EnrollRecoveryResult, type RecoveryEnrollmentInput, type RecoveryProof } from './rotate-recover.js';
|
|
24
24
|
import { type RecoverUserOptions } from './peer-recover.js';
|
|
25
25
|
import { type PaperRecoveryEntry, type ShamirRecoveryEntry } from './recovery.js';
|
|
@@ -74,6 +74,10 @@ export declare class TeamFacade {
|
|
|
74
74
|
runRevoke(engine: (adapter: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, options: RevokeOptions) => Promise<void>, vault: string, options: RevokeOptions, factors?: FactorProofBundle): Promise<void>;
|
|
75
75
|
/** Gate + run a `rotateKeys` engine. See `Noydb.rotate` for the public contract. */
|
|
76
76
|
runRotate(engine: (store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, opts: RotateKeysOptions) => Promise<RotateResult>, vault: string, collections: string[]): Promise<RotateResult>;
|
|
77
|
+
/** Gate + run the `verifyRoster` engine (#1121). See `Noydb.verifyRoster`. */
|
|
78
|
+
runVerifyRoster(engine: (store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring) => Promise<RosterVerifyResult>, vault: string): Promise<RosterVerifyResult>;
|
|
79
|
+
/** Gate + run the `quarantineKeyring` engine (#1121). See `Noydb.quarantineKeyring`. */
|
|
80
|
+
runQuarantine(engine: (store: NoydbStore, vault: string, callerKeyring: UnlockedKeyring, userId: string) => Promise<QuarantineResult>, vault: string, userId: string, factors?: FactorProofBundle): Promise<QuarantineResult>;
|
|
77
81
|
/**
|
|
78
82
|
* Add a tier-2 authenticator slot to the calling user's keyring.
|
|
79
83
|
* Each slot independently wraps the SAME KEK under a method-specific
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #1096 — the authenticated half of a `_keyring` file's AUTHORITY.
|
|
3
|
+
*
|
|
4
|
+
* A `_keyring` file is stored plaintext (`_iv: ''`) so admins can edit a
|
|
5
|
+
* member's authority without holding that member's credential. That means
|
|
6
|
+
* `role`/`permissions` were authenticated by NOTHING — a hostile store could
|
|
7
|
+
* promote a viewer to admin by editing one word (proven in
|
|
8
|
+
* `__tests__/keyring-replay-escalation.test.ts`).
|
|
9
|
+
*
|
|
10
|
+
* The fix is a vault-wide ROSTER KEY, carried as a reserved DEK-map entry
|
|
11
|
+
* (`deks['_roster']`, see `ROSTER_KEY_ID`) so it reaches every member through
|
|
12
|
+
* the channels a DEK already travels — grant's `_`-prefix propagation,
|
|
13
|
+
* `persistKeyring`, the wrapped-DEKs recovery blob, `peer-recover`, pod
|
|
14
|
+
* recipient slots — and a `roster_tag`: AES-GCM of the canonical authority
|
|
15
|
+
* fields under that key. Every roster EDITOR holds the key (constraint:
|
|
16
|
+
* admins edit authority they don't hold the target's credential for) — which
|
|
17
|
+
* is what sets the bound below.
|
|
18
|
+
*
|
|
19
|
+
* `user_id` is inside the canonical string so a genuine tag cannot be
|
|
20
|
+
* transplanted onto another member's file.
|
|
21
|
+
*
|
|
22
|
+
* ## What "authority half" does NOT cover
|
|
23
|
+
*
|
|
24
|
+
* The canonical string is exactly {@link RosterAuthorityFields} — the fields a
|
|
25
|
+
* privilege decision reads. Other plaintext fields are deliberately excluded
|
|
26
|
+
* and REMAIN FORGEABLE by the store: `display_name` (cosmetic), `policy`
|
|
27
|
+
* (round-tripped, never enforced at v1.0), `echo` and `authenticators` (each
|
|
28
|
+
* authenticated by its own wrapped key material — a forged one fails to
|
|
29
|
+
* unlock rather than granting anything), plus `created_at` / `salt` /
|
|
30
|
+
* `_noydb_keyring`. Adding a field to the tag means adding it to
|
|
31
|
+
* `rosterCanonical`; nothing else here is a claim about it.
|
|
32
|
+
*
|
|
33
|
+
* ## The bound
|
|
34
|
+
*
|
|
35
|
+
* This stops the STORE, which holds no keys. It deliberately does NOT stop a
|
|
36
|
+
* malicious MEMBER: every roster editor must hold the roster key, so anyone
|
|
37
|
+
* who legitimately holds it can forge any authority field for any member.
|
|
38
|
+
* That bound must be stated in `SECURITY.md` (tracked as part of the #1096
|
|
39
|
+
* PR) — it is not written there yet.
|
|
40
|
+
*/
|
|
41
|
+
import type { KeyringFile } from '../../kernel/types.js';
|
|
42
|
+
import type { EnclaveKey } from '../../kernel/enclave/index.js';
|
|
43
|
+
export interface RosterTag {
|
|
44
|
+
readonly iv: string;
|
|
45
|
+
readonly data: string;
|
|
46
|
+
}
|
|
47
|
+
export type RosterAuthorityFields = Pick<KeyringFile, 'user_id' | 'role' | 'permissions' | 'granted_by' | 'expires_at' | 'export_capability' | 'import_capability'>;
|
|
48
|
+
export declare function rosterCanonical(file: RosterAuthorityFields): string;
|
|
49
|
+
export declare function mintRosterTag(file: RosterAuthorityFields, rosterKey: EnclaveKey): Promise<RosterTag>;
|
|
50
|
+
/**
|
|
51
|
+
* false on decrypt failure OR canonical mismatch — never throws.
|
|
52
|
+
*
|
|
53
|
+
* `null` is accepted alongside `undefined` because the tag arrives from
|
|
54
|
+
* JSON a store controls: `"roster_tag": null` is a shape the type system
|
|
55
|
+
* says is impossible and the wire permits.
|
|
56
|
+
*/
|
|
57
|
+
export declare function verifyRosterTag(file: RosterAuthorityFields, tag: RosterTag | undefined | null, rosterKey: EnclaveKey): Promise<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* #1096 — THE CHOKEPOINT. Verify a keyring file's plaintext AUTHORITY half
|
|
60
|
+
* against the roster key carried in its own, already-unwrapped, DEK set.
|
|
61
|
+
* Throws {@link KeyringTamperedError}; returns silently when the roster is
|
|
62
|
+
* authentic.
|
|
63
|
+
*
|
|
64
|
+
* **Every path that builds an `UnlockedKeyring` from a `KeyringFile` must call
|
|
65
|
+
* this — not just `loadKeyring`.** A tier-2 unlock that reconstructs
|
|
66
|
+
* `role`/`permissions` from the plaintext header without it accepts exactly
|
|
67
|
+
* the forgery tier-1 refuses, and the vault is only as strong as its weakest
|
|
68
|
+
* unlock path. That is not hypothetical: the wrap-DEKs password path shipped
|
|
69
|
+
* in this state until it was caught in review.
|
|
70
|
+
*
|
|
71
|
+
* Deliberately says nothing about the canary. The canary proves the KEK, and
|
|
72
|
+
* tier-2 paths have no KEK to prove — the roster key they hold comes from the
|
|
73
|
+
* slot's own wrapped-DEK blob, which is authenticated by its own AES-GCM tag.
|
|
74
|
+
* Callers that DO hold a KEK check the canary separately, before this.
|
|
75
|
+
*
|
|
76
|
+
* @param deks the caller's UNWRAPPED DEK set — a roster key here is proof of
|
|
77
|
+
* possession, so this must never be handed a map built from unverified input.
|
|
78
|
+
*/
|
|
79
|
+
export declare function assertRosterAuthenticated(file: KeyringFile, deks: ReadonlyMap<string, EnclaveKey>, userId: string): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* #1096 — VERIFY BEFORE YOU TRUST, and especially before you RESTAMP.
|
|
82
|
+
*
|
|
83
|
+
* The sibling of {@link assertRosterAuthenticated} for the other half of the
|
|
84
|
+
* problem. That one guards paths that *unlock* a keyring; this one guards paths
|
|
85
|
+
* that **read another member's file** — because the roster key is vault-wide, a
|
|
86
|
+
* caller holding it can verify any member's tag, not just their own.
|
|
87
|
+
*
|
|
88
|
+
* Every read-modify-write on a member's roster must call this **before** the
|
|
89
|
+
* modify. A flow that reads a forged file, edits one field and restamps does
|
|
90
|
+
* not merely tolerate the forgery — it **launders** it, converting a file
|
|
91
|
+
* `loadKeyring` refuses into one it accepts, under a genuine tag. `revoke`
|
|
92
|
+
* calls into such a flow unconditionally, so without this a single forged
|
|
93
|
+
* member plus any later revocation anywhere in the vault is a complete bypass.
|
|
94
|
+
*
|
|
95
|
+
* Fail-closed, deliberately: a forged member's file aborts the operation rather
|
|
96
|
+
* than being skipped. Skipping would complete the revoke while leaving the
|
|
97
|
+
* forgery in place, and an untrusted store can already refuse writes — so the
|
|
98
|
+
* availability it costs was never guaranteed, while the integrity it buys is
|
|
99
|
+
* the point of the mechanism.
|
|
100
|
+
*/
|
|
101
|
+
export declare function assertRosterTagValid(file: KeyringFile, rosterKey: EnclaveKey, userId: string): Promise<void>;
|
|
@@ -13,7 +13,7 @@ export declare const BLOB_COLLECTION = "_blob";
|
|
|
13
13
|
/** Stores `BlobObject` metadata envelopes, keyed by eTag. */
|
|
14
14
|
export declare const BLOB_INDEX_COLLECTION = "_blob_index";
|
|
15
15
|
/**
|
|
16
|
-
* Stores encrypted chunk envelopes, keyed by `{eTag}
|
|
16
|
+
* Stores encrypted chunk envelopes, keyed by `{eTag}_{chunkIndex}`.
|
|
17
17
|
* NOT loaded into the in-memory query layer. Fetched on demand by
|
|
18
18
|
* `BlobSet.get()` / `BlobSet.response()`.
|
|
19
19
|
*/
|
|
@@ -39,7 +39,7 @@ export declare const DEFAULT_CHUNK_SIZE: number;
|
|
|
39
39
|
*
|
|
40
40
|
* ```
|
|
41
41
|
* _blob_index/{eTag} BlobObject metadata (vault-shared DEK)
|
|
42
|
-
* _blob_chunks/{eTag}
|
|
42
|
+
* _blob_chunks/{eTag}_{chunkIndex} Encrypted chunk data (vault-shared DEK + AAD)
|
|
43
43
|
* _blob_slots_{collection}/{recordId} Slot map (parent collection DEK)
|
|
44
44
|
* _blob_versions_{collection}/{recordId}/{slot}/{label} Published versions (parent collection DEK)
|
|
45
45
|
* ```
|
|
@@ -424,16 +424,68 @@ export declare class BlobSet {
|
|
|
424
424
|
* - not yet stamped → apply via `casUpdateRefCountStamped`, then proceed
|
|
425
425
|
* exactly like the unstamped path below.
|
|
426
426
|
*
|
|
427
|
-
* A crash can also land
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
427
|
+
* A crash can also land part-way through the deletion itself. Since #1127
|
|
428
|
+
* that deletion runs CHUNKS FIRST (see `deleteChunksThenIndex`), so what
|
|
429
|
+
* survives is an index row with some chunks already gone — a reachable,
|
|
430
|
+
* re-runnable state rather than chunks nothing can ever address again.
|
|
431
|
+
*
|
|
432
|
+
* An eTag whose index row is ALREADY absent on entry is therefore either
|
|
433
|
+
* pre-#1127 residue or a completed deletion. `loadBlobObject` returns null
|
|
434
|
+
* (indistinguishable from "never existed") and the object's `chunkCount` is
|
|
435
|
+
* gone with it. A stamped caller who knows the true count (the journal
|
|
436
|
+
* marker's captured `holds`, once that plumbing lands) supplies it via
|
|
437
|
+
* `chunkCountHint` so this call can still finish the chunk deletion; without
|
|
438
|
+
* it, an already-index-gone eTag is reported `'shredded'` same as today (best
|
|
434
439
|
* effort — nothing left to key the cleanup off of).
|
|
435
440
|
*/
|
|
436
441
|
private releaseRef;
|
|
442
|
+
/**
|
|
443
|
+
* Delete a blob's chunks, THEN its index row. The order is the whole point
|
|
444
|
+
* (#1127).
|
|
445
|
+
*
|
|
446
|
+
* Both deletions used to run index-first, which meant a crash in between
|
|
447
|
+
* stranded chunks with no index row. Nothing can ever reach those again:
|
|
448
|
+
* `loadBlobObject` returns null, so no reader addresses them — and
|
|
449
|
+
* `rekeyBlobSet` derives its chunk ids from each index entry's `chunkCount`,
|
|
450
|
+
* so a rotation never visits them either. For a LEGACY blob (bytes under the
|
|
451
|
+
* `_blob` DEK itself rather than a per-blob content CEK) the bodies then stay
|
|
452
|
+
* openable under the retired `_blob` DEK — precisely the key a revoked member
|
|
453
|
+
* walked away with. Crash during `forget()`, revoke later, and real blob
|
|
454
|
+
* content sits readable indefinitely, with no error on either side.
|
|
455
|
+
*
|
|
456
|
+
* Reversing it removes the class rather than cleaning up after it: every
|
|
457
|
+
* chunk that still exists has an index row, so every chunk is reachable by
|
|
458
|
+
* `rekeyBlobSet` and gets re-keyed. There is no orphan to sweep because none
|
|
459
|
+
* is produced.
|
|
460
|
+
*
|
|
461
|
+
* The residue this ordering leaves instead is an index row whose chunks are
|
|
462
|
+
* partly gone. That state is better, but it is NOT free — it cost one reader
|
|
463
|
+
* correction (`resolveRehomedVersionETag`, which read an old blob's bytes
|
|
464
|
+
* while resuming a rehome and now checks `refCount <= 0` instead of relying
|
|
465
|
+
* on the row having vanished). An earlier draft of this comment called the
|
|
466
|
+
* new state "strictly better"; the full suite disproved that, and any future
|
|
467
|
+
* path that reads a blob by index needs the same care. What is true of it:
|
|
468
|
+
* - it is REACHABLE, so a re-run of `releaseRef` completes the deletion
|
|
469
|
+
* idempotently (both `store.delete` calls are void on an absent key);
|
|
470
|
+
* - `rekeyBlobSet` already tolerates it — a missing chunk hits its
|
|
471
|
+
* `if (!chunkEnv || !chunkEnv._iv) continue`, so a rotation still
|
|
472
|
+
* succeeds and still re-keys every chunk that remains;
|
|
473
|
+
* - it cannot leak, because the bytes that survive are the ones still
|
|
474
|
+
* covered by rotation.
|
|
475
|
+
*
|
|
476
|
+
* This also makes one ordering rule true across the blob subsystem rather
|
|
477
|
+
* than two opposite ones: `kernel/enclave/record-keys/rekey-blob.ts` already
|
|
478
|
+
* re-encrypts chunks before re-sealing their index entry, and documents that
|
|
479
|
+
* order as its resume property.
|
|
480
|
+
*
|
|
481
|
+
* Deliberately NOT paired with a sweep that deletes pre-existing orphans:
|
|
482
|
+
* such a sweep must decide "orphaned" from `store.list(_blob_index)`, and the
|
|
483
|
+
* store is untrusted. A store that withholds one index row could make a LIVE
|
|
484
|
+
* blob's chunks look orphaned and have us destroy them — turning withholding,
|
|
485
|
+
* which is reversible, into permanent loss. Reporting them is safe; deleting
|
|
486
|
+
* them on the store's word is not. See #1133 for the report-then-reclaim follow-up.
|
|
487
|
+
*/
|
|
488
|
+
private deleteChunksThenIndex;
|
|
437
489
|
/**
|
|
438
490
|
* Crypto-shred this record's blob attachments — called by
|
|
439
491
|
* `vault.forget()`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FROZEN_SNAPSHOTS_COLLECTION,
|
|
3
|
+
freezeAndDeleteClosure,
|
|
4
|
+
freezeSnapshotOnly,
|
|
5
|
+
randomId,
|
|
6
|
+
withdrawAccessibleData
|
|
7
|
+
} from "./chunk-RJYPFCID.js";
|
|
8
|
+
import "./chunk-BXHG26KN.js";
|
|
9
|
+
import "./chunk-2VMCJUK6.js";
|
|
10
|
+
import "./chunk-HRSEAGLI.js";
|
|
11
|
+
import "./chunk-DIVPOJPV.js";
|
|
12
|
+
import "./chunk-PENPHA45.js";
|
|
13
|
+
import "./chunk-IUQPNAGR.js";
|
|
14
|
+
import "./chunk-AELW6OJZ.js";
|
|
15
|
+
import "./chunk-DUUARUZI.js";
|
|
16
|
+
import "./chunk-LP7BEXCT.js";
|
|
17
|
+
import "./chunk-O5QXH7U7.js";
|
|
18
|
+
import "./chunk-IGNJOJEP.js";
|
|
19
|
+
import "./chunk-PKUJ3JLQ.js";
|
|
20
|
+
import "./chunk-PZ5AY32C.js";
|
|
21
|
+
export {
|
|
22
|
+
FROZEN_SNAPSHOTS_COLLECTION,
|
|
23
|
+
freezeAndDeleteClosure,
|
|
24
|
+
freezeSnapshotOnly,
|
|
25
|
+
randomId,
|
|
26
|
+
withdrawAccessibleData
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=withdraw-accessible-JYX3SPVY.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noy-db/hub",
|
|
3
|
-
"version": "0.6.0-pre.
|
|
3
|
+
"version": "0.6.0-pre.22",
|
|
4
4
|
"description": "Zero-knowledge, offline-first, encrypted document store — core library with AES-256-GCM, PBKDF2, multi-user keyring, and sync engine",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "vLannaAi <vicio@lanna.ai>",
|
|
@@ -208,6 +208,7 @@
|
|
|
208
208
|
"files": [
|
|
209
209
|
"dist",
|
|
210
210
|
"README.md",
|
|
211
|
+
"CHANGELOG.md",
|
|
211
212
|
"LICENSE",
|
|
212
213
|
"codemods"
|
|
213
214
|
],
|
|
@@ -215,14 +216,14 @@
|
|
|
215
216
|
"node": ">=22.0.0"
|
|
216
217
|
},
|
|
217
218
|
"dependencies": {
|
|
218
|
-
"@noy-db/attestation": "0.6.0-pre.
|
|
219
|
+
"@noy-db/attestation": "0.6.0-pre.22"
|
|
219
220
|
},
|
|
220
221
|
"devDependencies": {
|
|
221
222
|
"@types/node": "^22.0.0",
|
|
222
223
|
"esbuild": "^0.25.0",
|
|
223
224
|
"zod": "^4.0.0",
|
|
224
225
|
"zod-to-json-schema": "^3.25.2",
|
|
225
|
-
"@noy-db/on-shamir": "0.6.0-pre.
|
|
226
|
+
"@noy-db/on-shamir": "0.6.0-pre.22"
|
|
226
227
|
},
|
|
227
228
|
"peerDependencies": {
|
|
228
229
|
"zod-to-json-schema": "^3.25.0"
|
package/dist/api-Z5VHH24A.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
UserApi,
|
|
3
|
-
createUserApi
|
|
4
|
-
} from "./chunk-CVYXIN5B.js";
|
|
5
|
-
import "./chunk-JHO6FGZX.js";
|
|
6
|
-
import "./chunk-D5UDZANO.js";
|
|
7
|
-
import "./chunk-ZVAFJQZB.js";
|
|
8
|
-
import "./chunk-OQLYMBJI.js";
|
|
9
|
-
import "./chunk-DJ23QZIN.js";
|
|
10
|
-
import "./chunk-SFD2LL7G.js";
|
|
11
|
-
import "./chunk-LP7BEXCT.js";
|
|
12
|
-
import "./chunk-VJ4B3ZXY.js";
|
|
13
|
-
import "./chunk-3Y4OFWQJ.js";
|
|
14
|
-
import "./chunk-P7L3OQLL.js";
|
|
15
|
-
import "./chunk-PZ5AY32C.js";
|
|
16
|
-
export {
|
|
17
|
-
UserApi,
|
|
18
|
-
createUserApi
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=api-Z5VHH24A.js.map
|