permdock 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -35
- package/dist/{openapi-schema--ARjyfQr.js → 2020-C9VN-x8c.js} +5 -132
- package/dist/a2a/index.d.ts +8 -6
- package/dist/a2a/index.js +21 -31
- package/dist/{adapter-context-mlWsVGGg.js → adapter-context-CRhqyzCk.js} +1 -1
- package/dist/adoption-scan-B4R5fnMU.js +107 -0
- package/dist/agent/index.d.ts +3 -0
- package/dist/agent/index.js +1 -0
- package/dist/ai-sdk/index.d.ts +18 -23
- package/dist/ai-sdk/index.js +38 -21
- package/dist/app-data-MuyzVqX8.js +60 -0
- package/dist/approval-header-CJACtHkv.js +23 -0
- package/dist/approval-prompt-Dg5LeAcT.js +62 -0
- package/dist/approval-prompt-Djo_PyZc.d.ts +57 -0
- package/dist/approvals/index.d.ts +5 -3
- package/dist/approvals/index.js +8 -5
- package/dist/approvals-DJ6Yd5z1.js +995 -0
- package/dist/{approvers-DT4AVyIg.js → approvers-CqPOLD-o.js} +1 -1
- package/dist/arazzo-B6lebmiQ.js +36 -0
- package/dist/{arazzo-BAgw9ap6.js → arazzo-BWhNF-k0.js} +24 -17
- package/dist/args-IIolxxKA.js +197 -0
- package/dist/astro/index.d.ts +43 -0
- package/dist/astro/index.js +27 -0
- package/dist/audience-Dg8XsRaO.js +55 -0
- package/dist/auth-DRLEizbL.js +178 -0
- package/dist/authzen/index.d.ts +26 -6
- package/dist/authzen/index.js +228 -75
- package/dist/automation-BMZPIVUM.d.ts +114 -0
- package/dist/automation-DVjOckjV.js +157 -0
- package/dist/better-auth/index.d.ts +8 -6
- package/dist/better-auth/index.js +11 -23
- package/dist/better-supabase/index.d.ts +438 -86
- package/dist/better-supabase/index.js +1027 -184
- package/dist/bind--9EFVYWF.d.ts +38 -0
- package/dist/{bind-CuzGytRf.js → bind-CZzhx-Vj.js} +22 -10
- package/dist/body-CH5of8Ne.js +10 -0
- package/dist/body-text-QcXok_SI.js +52 -0
- package/dist/build-instance-BMnAudHn.js +52 -0
- package/dist/{canonical-json-DemiK4Vp.js → canonical-json-BC8_nMTw.js} +6 -6
- package/dist/{capability-2kYTMWDv.d.ts → capability-BSslw1QV.d.ts} +44 -25
- package/dist/{capability-4qPdO9gk.js → capability-N1K9IpqS.js} +69 -42
- package/dist/casbin-Cr7RLtA3.js +30 -0
- package/dist/casbin-Dyu2gnUD.js +234 -0
- package/dist/casl-64gpT-8x.js +24 -0
- package/dist/casl-DjEDhTCP.js +299 -0
- package/dist/catalog/index.d.ts +74 -2
- package/dist/catalog/index.js +51 -2
- package/dist/catalog-BECMPrwc.js +100 -0
- package/dist/catalog-DjhMYYCq.js +1 -0
- package/dist/catalog-R_A__RsH.js +52 -0
- package/dist/{catalog-doc-DdGm82XT.js → catalog-doc-C9wjsfNY.js} +54 -25
- package/dist/catalog-fingerprint-CCP0-yQS.js +153 -0
- package/dist/chat/index.d.ts +2 -0
- package/dist/chat/index.js +224 -0
- package/dist/chat-sdk/index.d.ts +87 -0
- package/dist/chat-sdk/index.js +197 -0
- package/dist/claims-map-7oQ3ue4X.js +13 -0
- package/dist/claims-map-Ca-QX8C6.d.ts +32 -0
- package/dist/claude-agent/index.d.ts +7 -14
- package/dist/claude-agent/index.js +26 -30
- package/dist/clerk/index.d.ts +9 -8
- package/dist/clerk/index.js +15 -45
- package/dist/cli/bin.js +36 -17
- package/dist/cli/index.d.ts +20 -6
- package/dist/cli/index.js +164 -4
- package/dist/cloud/index.d.ts +102 -63
- package/dist/cloud/index.js +240 -347
- package/dist/cloud-CIoHNevm.js +87 -0
- package/dist/codemod-Bmj9dWMH.js +37 -0
- package/dist/codemod-Cxvvc70T.js +2084 -0
- package/dist/{collect-DSTE3ml9.js → collect-CrZJJnEF.js} +79 -17
- package/dist/collect-DloHbDVa.js +55 -0
- package/dist/collect-FlXJlhus.js +1 -0
- package/dist/command-L8EstFNm.js +6 -0
- package/dist/{compact-y6vfu2_f.js → compact-CAf557ZB.js} +11 -1
- package/dist/compile/index.d.ts +1 -1
- package/dist/compile/index.js +1 -2
- package/dist/{compile-Ba4blROR.js → compile-CMqMx_IN.js} +13 -9
- package/dist/{compile-BkRyBDBw.d.ts → compile-Ckm2HqBZ.d.ts} +5 -3
- package/dist/completion-BqhRBJD8.js +143 -0
- package/dist/config-B46rm9sc.js +26 -0
- package/dist/{config-BJiM-xAm.js → config-bs_kZeYq.js} +15 -10
- package/dist/{config-report-CdCgbRnV.js → config-report-DUgj62Ai.js} +17 -8
- package/dist/{connection-CU8MQxRi.js → connection-DjhIJSs2.js} +8 -6
- package/dist/constants-DcJABbLW.js +20 -0
- package/dist/{context-Bcy85rGi.js → context-bbFHR-0D.js} +16 -5
- package/dist/convex/index.d.ts +11 -10
- package/dist/convex/index.js +18 -18
- package/dist/create-0VZ7Pdiu.d.ts +107 -0
- package/dist/create-BDS7wc3y.d.ts +138 -0
- package/dist/create-BFfm17UA.d.ts +110 -0
- package/dist/create-BWRSXgOF.js +403 -0
- package/dist/create-C3b4B5eF.js +130 -0
- package/dist/create-DnrmLnLW.js +323 -0
- package/dist/{credential-8P81ff4u.js → credential-DM2um3ha.js} +153 -32
- package/dist/credentials-DPyHmYz5.js +74 -0
- package/dist/deciding-columns-Sq12mEA6.js +123 -0
- package/dist/delegation-DaXVdDhM.js +286 -0
- package/dist/delegation-input-FTxMK3ji.js +19 -0
- package/dist/delivery/index.d.ts +5 -0
- package/dist/delivery/index.js +5 -0
- package/dist/delivery-DCAgNyCn.js +499 -0
- package/dist/delivery-event-xX4obB8F.js +40 -0
- package/dist/denied-text-D8jDHgsl.d.ts +19 -0
- package/dist/{describe-DMYiCjJV.d.ts → describe-BZUsixiL.d.ts} +11 -2
- package/dist/{describe-B_gVZEVi.js → describe-BybMRY7A.js} +10 -5
- package/dist/device-BARQ8eYG.js +193 -0
- package/dist/diff-CxZo9pTq.js +37 -0
- package/dist/{diff-2VaeChzX.js → diff-DCePiN6M.js} +61 -55
- package/dist/doctor-CxiwSfqH.js +44 -0
- package/dist/doctor-DFjUxf2f.js +2361 -0
- package/dist/drizzle/index.d.ts +5 -3
- package/dist/drizzle/index.js +6 -14
- package/dist/elysia/index.d.ts +16 -13
- package/dist/elysia/index.js +14 -13
- package/dist/env-DJZrPjRi.js +8 -0
- package/dist/errors-BDUwg2qC.js +27 -0
- package/dist/{errors-Cz5zn0mW.js → errors-BKy0EfhN.js} +6 -10
- package/dist/errors-BWXBMaKK.d.ts +11 -0
- package/dist/{errors-DPdqI50v.d.ts → errors-C2PXIv4c.d.ts} +2 -2
- package/dist/errors-CWTY6uih.js +143 -0
- package/dist/evaluate-_R8QkWaf.js +1732 -0
- package/dist/evaluations-16UqqQ6W.d.ts +32 -0
- package/dist/{evaluations-tz6D9A2G.js → evaluations-DZ2CbV5k.js} +181 -32
- package/dist/eve/index.d.ts +12 -16
- package/dist/eve/index.js +23 -29
- package/dist/event-time-CsegxXxB.js +23 -0
- package/dist/expiry-D4_YKRKD.js +52 -0
- package/dist/express/index.d.ts +13 -10
- package/dist/express/index.js +14 -12
- package/dist/fastify/index.d.ts +26 -13
- package/dist/fastify/index.js +17 -36
- package/dist/fetch-adapter-g0ypLkID.js +120 -0
- package/dist/fetch-adapter-qKJBuRqy.d.ts +31 -0
- package/dist/fields-D9tPVUUS.js +203 -0
- package/dist/files-C5ZI27eV.js +124 -0
- package/dist/{files-DWUN9PzI.js → files-D_JIzUrP.js} +12 -3
- package/dist/{fixtures-ht28Cplr.js → fixtures-B7XrLeY7.js} +12 -12
- package/dist/flags-C3DktBDY.js +86 -0
- package/dist/{from-snapshot-CTLijvdm.js → from-snapshot-D2lZt4Dd.js} +78 -65
- package/dist/{generate-CH7ThJ14.js → generate-CNU1pIOo.js} +1 -3
- package/dist/grantee-Cn1HyUsI.js +254 -0
- package/dist/grantee-conditions-CcXf8hMM.js +271 -0
- package/dist/grantee-match-DHArqY82.js +142 -0
- package/dist/h3/index.d.ts +37 -0
- package/dist/h3/index.js +35 -0
- package/dist/headers-BIjfMaoC.js +8 -0
- package/dist/headers-CIbDTUTK.d.ts +7 -0
- package/dist/{helpers-H_KARDVC.js → helpers-DTcZOzhF.js} +47 -39
- package/dist/hono/index.d.ts +12 -9
- package/dist/hono/index.js +14 -13
- package/dist/{hosted-DJQw46hn.js → hosted-BZIAYvon.js} +64 -15
- package/dist/hosted-DBDX0M-P.d.ts +78 -0
- package/dist/{http-SO7qGttf.js → http-BBoKefeS.js} +35 -2
- package/dist/{http-DPuDaChb.d.ts → http-B_LphE5Y.d.ts} +1 -2
- package/dist/http-DXJ37RDA.js +46 -0
- package/dist/{http-BIhmLfCc.js → http-ujKm0JXE.js} +3 -26
- package/dist/{openapi-import-cmwetbzw.js → import-CNV7I2Dw.js} +30 -26
- package/dist/{rls-import-4lLW_pbb.js → import-DMmOG27O.js} +271 -128
- package/dist/index-BcHcPyIo.d.ts +110 -0
- package/dist/index-CaxrMD1A.d.ts +1 -0
- package/dist/index-Chrs5fQ-.d.ts +210 -0
- package/dist/index-CxGUswIC.d.ts +431 -0
- package/dist/index-D8EovfsP.d.ts +91 -0
- package/dist/index-DOVf7RJv.d.ts +900 -0
- package/dist/{index-C8z4RjQV.d.ts → index-SGdIQyzc.d.ts} +34 -16
- package/dist/index.d.ts +20 -14
- package/dist/index.js +33 -23
- package/dist/init-DeMYsnYJ.js +96 -0
- package/dist/init-GG6Jh8HD.js +95 -0
- package/dist/{instance-options-jARdwfPN.d.ts → instance-options-Omfd793B.d.ts} +2 -2
- package/dist/instance-snapshot-Cxq4ygFc.js +600 -0
- package/dist/instant-BluqDvyS.js +19 -0
- package/dist/internals-Dk8A8fX3.js +17 -0
- package/dist/{json-schema-BsAflUGW.js → json-schema-B-vAwlde.js} +46 -9
- package/dist/json-schema-CN_iLFH2.d.ts +40 -0
- package/dist/jwt/index.d.ts +18 -11
- package/dist/jwt/index.js +166 -145
- package/dist/{kernel-_RRHmnMY.js → kernel-5JatXyND.js} +120 -43
- package/dist/kysely/index.d.ts +5 -3
- package/dist/kysely/index.js +6 -14
- package/dist/{live-options-H2eG8dfJ.js → live-options-BaAFCIiu.js} +16 -3
- package/dist/load-BxEtwlBS.js +1 -0
- package/dist/{load-DhWEB9P1.js → load-DFS_ry0W.js} +31 -7
- package/dist/{load-jose-BL6LH4bL.js → load-jose-DZ4dnjri.js} +1 -4
- package/dist/login-Dfe5RlYk.js +68 -0
- package/dist/login-imhuwvn3.js +254 -0
- package/dist/manifest-C8IzW3Do.js +42 -0
- package/dist/manifest-CtKR3GXL.js +370 -0
- package/dist/manifest-json-CAGzls-C.js +9 -0
- package/dist/{manifest-uDS9y5de.d.ts → manifest-mx5ghSFM.d.ts} +9 -2
- package/dist/manifest-schema-C0kK_8V0.js +399 -0
- package/dist/{map-claims-Z4QZOiFF.js → map-claims-D3oRmTk0.js} +19 -25
- package/dist/{map-error-pgUWNNtG.js → map-error-TCAdw-eW.js} +5 -5
- package/dist/{markers-B0hYLvMD.js → markers-C6joDI3o.js} +8 -3
- package/dist/mcp/index.d.ts +36 -9
- package/dist/mcp/index.js +476 -448
- package/dist/{rls-migrate-CN4TlJTO.js → migrate-BShP7Vf4.js} +119 -20
- package/dist/nest/index.d.ts +12 -9
- package/dist/nest/index.js +20 -20
- package/dist/next/index.d.ts +40 -20
- package/dist/next/index.js +37 -39
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +2 -2
- package/dist/node/index.d.ts +10 -10
- package/dist/node/index.js +7 -9
- package/dist/ocsf-BFp-PZZA.js +126 -0
- package/dist/openai/index.d.ts +9 -16
- package/dist/openai/index.js +18 -25
- package/dist/openapi/index.d.ts +3 -3
- package/dist/openapi/index.js +1 -1
- package/dist/{openapi-BqRBvAng.js → openapi-B7HZ0f-r.js} +9 -12
- package/dist/{openapi-CqqEbHsL.js → openapi-DTaEmTSW.js} +23 -26
- package/dist/openapi-ahr8rHu3.js +138 -0
- package/dist/operation-findings-DgATDpvh.js +36 -0
- package/dist/operations-CxybZErY.d.ts +59 -0
- package/dist/orpc/index.d.ts +13 -10
- package/dist/orpc/index.js +23 -20
- package/dist/otel/index.d.ts +3 -2
- package/dist/otel/index.js +53 -27
- package/dist/output-Dyw8fyPF.js +88 -0
- package/dist/output-files-B3IZJksC.js +1 -0
- package/dist/output-files-DhRBBE4n.js +138 -0
- package/dist/{rls-fields-CZOMlwHl.js → ownership-BatFgAA4.js} +2393 -2349
- package/dist/{package-root-zGkxO3oN.js → package-root-Dk_ETdkp.js} +4 -3
- package/dist/{parse-BuyjxhZV.js → parse-Cxq0WxrA.js} +3 -3
- package/dist/{parse-local-manifest-BrMozJCo.js → parse-local-manifest-CVSs6J9I.js} +2 -4
- package/dist/{parse-local-manifest-JLnaBH0S.d.ts → parse-local-manifest-DgqtruPn.d.ts} +1 -1
- package/dist/parse-request-D_tUXG6M.js +26 -0
- package/dist/paths-DXSHAMIa.js +42 -0
- package/dist/pdp/index.d.ts +7 -3
- package/dist/pdp/index.js +47 -29
- package/dist/{peer-BOr_kJE1.js → peer-C8swJ2GH.js} +23 -4
- package/dist/peer-CRvC7Hg1.js +1 -0
- package/dist/permdock-B9JxkBwC.js +868 -0
- package/dist/permdock-D7eeLJER.d.ts +502 -0
- package/dist/permission-registry-Br4jSNVi.js +385 -0
- package/dist/permissions-B-wCP5ZC.js +30 -0
- package/dist/{permissions-RJrovw98.js → permissions-CZKiUfFM.js} +4 -3
- package/dist/{permissions-CDgvKG5L.d.ts → permissions-oEWfl-kl.d.ts} +1 -2
- package/dist/policies-CO1oOymN.js +295 -0
- package/dist/{policy-D2W7uv19.d.ts → policy-Czo4n3Hs.d.ts} +2 -2
- package/dist/policy-DLZJ5gAp.js +399 -0
- package/dist/policy-from-catalog-DzhEc3Y9.js +450 -0
- package/dist/policy-module-CTlwMvLI.js +89 -0
- package/dist/{policy-IB6yxpC3.d.ts → policy-types-DzwivBgR.d.ts} +939 -1057
- package/dist/postgrest-CW0IqC-U.js +566 -0
- package/dist/postgrest-NUqZT-RB.d.ts +100 -0
- package/dist/powersync-BHfuehf3.js +62 -0
- package/dist/powersync-CbzkqL_M.js +1 -0
- package/dist/{powersync-Dv1_aWF7.js → powersync-bYUDLOAO.js} +30 -32
- package/dist/preset/index.d.ts +146 -0
- package/dist/preset/index.js +1 -0
- package/dist/preset-DZdU0tne.js +1768 -0
- package/dist/principal-source-pHneukrx.js +103 -0
- package/dist/prisma/index.d.ts +6 -3
- package/dist/prisma/index.js +6 -12
- package/dist/{problem-B43ztKIm.js → problem-CTviyH5L.js} +18 -27
- package/dist/{problem-details-DX075l9V.d.ts → problem-details-DXlt-vks.d.ts} +1 -1
- package/dist/{problem-details-_AMOYz-w.js → problem-details-cn5X30gZ.js} +45 -42
- package/dist/problem-types-CJ2325SZ.js +5 -0
- package/dist/{prompt-CXYhLfsS.js → prompt-DfZLJLIn.js} +2 -2
- package/dist/protected-DEPHc2xV.d.ts +38 -0
- package/dist/{protected-utU-SLuy.js → protected-DfjY5mLA.js} +37 -8
- package/dist/{provider-CSQd7m92.js → provider-CC-u3bYP.js} +23 -10
- package/dist/{provider-DZY281jO.d.ts → provider-DMVt6yYn.d.ts} +1 -1
- package/dist/{provider-store-Cfbvo4DE.js → provider-store-B5Yrkhzr.js} +6 -3
- package/dist/pull-BgIfno6w.js +256 -0
- package/dist/pull-ByOks_Tg.js +1 -0
- package/dist/push-CmFVBOeI.js +116 -0
- package/dist/pushed-policy-BImMTTIM.d.ts +57 -0
- package/dist/pushed-policy-DobP7AHI.js +238 -0
- package/dist/react/index.d.ts +8 -8
- package/dist/react/index.js +6 -6
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react/provider-client.js +1 -2
- package/dist/react-native/index.d.ts +24 -63
- package/dist/react-native/index.js +45 -27
- package/dist/{refs-KYb4ntaz.js → refs-K6eWUJ0H.js} +1 -1
- package/dist/relation-walk-3OyDBF0S.js +186 -0
- package/dist/relations-BnCWnJGI.js +163 -0
- package/dist/renames-CGj7YwcQ.js +175 -0
- package/dist/{replay-CYyiLiwO.d.ts → replay-D7iKcLFe.d.ts} +1 -1
- package/dist/{replay-BsOyTrdV.js → replay-Du1tJjG7.js} +2 -1
- package/dist/request-context-BTRTG7OT.js +71 -0
- package/dist/request-context-C2_1lchh.d.ts +5 -0
- package/dist/request-schema-CMreVuFM.js +148 -0
- package/dist/resend/index.d.ts +126 -0
- package/dist/resend/index.js +379 -0
- package/dist/resource-relations-D_jw0BFx.js +243 -0
- package/dist/retire-CALjIQ7e.js +240 -0
- package/dist/{revocations-Cy06JNx2.d.ts → revocations-R07lFBnX.d.ts} +2 -0
- package/dist/rls-BA8an5Ap.js +336 -0
- package/dist/{rls-DiinlRML.js → rls-j6t43t7n.js} +1066 -1068
- package/dist/role-builder-CXbis5-X.js +623 -0
- package/dist/{rpc-DL9Sqvb1.js → rpc-aPyNi6tA.js} +18 -8
- package/dist/run-CNsApDpd.js +1 -0
- package/dist/run-DOfMtc9V.js +723 -0
- package/dist/run-ticket-BjhTOi6u.d.ts +124 -0
- package/dist/run-ticket-sxFI6LAk.js +337 -0
- package/dist/{runtime-CB8gQFvS.js → runtime-D3VTAiCA.js} +1 -1
- package/dist/{saas-DhpJjnBA.js → saas-FO-Q8oj0.js} +18 -15
- package/dist/scan-BOI5tJ-6.js +29 -0
- package/dist/{schema-D3MnDMxa.js → schema-B4v0Qrac.js} +106 -10
- package/dist/schema-yLuBWWsh.js +130 -0
- package/dist/scim/index.d.ts +2 -2
- package/dist/scim/index.js +1 -2
- package/dist/{scim-BFGBBAqR.js → scim-ClHtpyV3.js} +213 -87
- package/dist/{scopes-CVdPrWN-.js → scopes-CUPSjo9q.js} +20 -7
- package/dist/server/index.d.ts +13 -134
- package/dist/server/index.js +13 -10
- package/dist/server-DqCT4CgZ.js +453 -0
- package/dist/{create-B1d519XK.d.ts → server-types-BLd4MnBX.d.ts} +89 -70
- package/dist/{sha256-BO0swRXL.js → sha256-D9ihqmvd.js} +8 -1
- package/dist/shared-CD11nBbC.js +304 -0
- package/dist/{shared-DRu8VFVM.js → shared-DvvFzYXe.js} +8 -9
- package/dist/signals-D3NcTKUS.js +32 -0
- package/dist/sink-BEZSlMS_.js +957 -0
- package/dist/sink-Bj_lDUDq.d.ts +225 -0
- package/dist/{skills-Biq5uup3.js → skills-B6lVdD_W.js} +16 -8
- package/dist/skills-CTYwkl44.js +51 -0
- package/dist/snapshot-CXUWfsNy.js +269 -0
- package/dist/{snapshot-cache-D6jLelln.js → snapshot-cache-DZHQ0KF6.js} +11 -5
- package/dist/{snapshot-cache-B-LxUahj.d.ts → snapshot-cache-DqK9eDmM.d.ts} +7 -5
- package/dist/solid/index.d.ts +24 -25
- package/dist/solid/index.js +41 -11
- package/dist/solid-start/index.d.ts +52 -0
- package/dist/solid-start/index.js +49 -0
- package/dist/{sources-BdOYLw9j.d.ts → sources-BV9j0DeZ.d.ts} +11 -13
- package/dist/{sources-4p0-4xQm.js → sources-vs5dGOsS.js} +147 -142
- package/dist/sql-B5T1IL83.js +55 -0
- package/dist/src-DLfUWFAI.js +1851 -0
- package/dist/ssf/index.d.ts +4 -4
- package/dist/ssf/index.js +440 -106
- package/dist/standard-webhooks-6lg8v_is.d.ts +88 -0
- package/dist/standard-webhooks-DgFFD-Ga.js +228 -0
- package/dist/storage-C2bWdvJH.js +132 -0
- package/dist/{store-DMAWwAJV.js → store-4u_hxjWa.js} +42 -55
- package/dist/{store-options-ByhZq1jV.js → store-options-BqEakYRa.js} +38 -24
- package/dist/{stores-BT2pSCub.js → stores-BbsD4fAR.js} +7 -3
- package/dist/stores-ClZUgeoP.d.ts +30 -0
- package/dist/{stream-D1RXubw2.d.ts → stream-7-xmnf3U.d.ts} +2 -2
- package/dist/{stream-DDpvynSB.js → stream-CvdUS9V1.js} +10 -2
- package/dist/style-DiKWnAvn.js +1 -0
- package/dist/{style-CTm1AXDT.js → style-Uao76wO7.js} +3 -2
- package/dist/subject-BGoM5o8B.js +17 -0
- package/dist/{subject-settings-BwBmCdTR.js → subject-settings-CkEwrw3W.js} +23 -5
- package/dist/supabase/index.d.ts +23 -106
- package/dist/supabase/index.js +5 -4
- package/dist/supabase/middleware.d.ts +13 -6
- package/dist/supabase/middleware.js +16 -11
- package/dist/supabase-9pqI57pW.js +92 -0
- package/dist/{supabase-C0qESOa-.js → supabase-Dxlp8A94.js} +124 -247
- package/dist/supabase-hook-CXcGpHqq.js +1 -0
- package/dist/{supabase-hook-ntETYCQu.js → supabase-hook-DdDQhMlw.js} +1659 -819
- package/dist/{supautils-u8jXTGrt.js → supautils-B6HYL9eL.js} +2 -2
- package/dist/support-session-C6xJQYut.js +158 -0
- package/dist/svelte/Protected.svelte +11 -4
- package/dist/svelte/index.d.ts +7 -7
- package/dist/svelte/index.js +26 -12
- package/dist/svelte/runtime.d.ts +10 -3
- package/dist/svelte/runtime.js +4 -3
- package/dist/svelte/source.d.ts +7 -7
- package/dist/svelte/source.js +5 -5
- package/dist/sveltekit/index.d.ts +51 -0
- package/dist/sveltekit/index.js +27 -0
- package/dist/tanstack-start/index.d.ts +51 -0
- package/dist/tanstack-start/index.js +40 -0
- package/dist/target-Bw37TFNA.js +51 -0
- package/dist/{validity-uOp8UpYn.js → tenancy-DN2QAx9z.js} +6 -42
- package/dist/terminal/index.d.ts +11 -9
- package/dist/terminal/index.js +36 -316
- package/dist/testing/index.d.ts +391 -106
- package/dist/testing/index.js +4574 -1286
- package/dist/testing/saas/index.d.ts +9 -8
- package/dist/testing/saas/index.js +2 -2
- package/dist/testing/saas/permissions.d.ts +1 -1
- package/dist/testing/saas/permissions.js +1 -2
- package/dist/text-BMFRfBqc.js +8 -0
- package/dist/{text-diff-BdkkYSbi.js → text-diff-BQcUapOb.js} +1 -1
- package/dist/thenable-yD7SabqG.js +31 -0
- package/dist/time-DkWjdL98.js +71 -0
- package/dist/{token-CIWxJOCh.js → token-BLZcjQgt.js} +15 -6
- package/dist/tool-refusal-CMLN5xhn.js +41 -0
- package/dist/trpc/index.d.ts +12 -9
- package/dist/trpc/index.js +18 -17
- package/dist/{types-DbjRN55U.d.ts → types-5Ut_pbKy.d.ts} +141 -13
- package/dist/types-BNORmDM8.d.ts +172 -0
- package/dist/types-BjV-fqcA.d.ts +57 -0
- package/dist/{types-QCuYJh4q.d.ts → types-BqAKcRNW.d.ts} +2 -1
- package/dist/types-C8-KNsFf.d.ts +107 -0
- package/dist/{types-aqOHTHcp.d.ts → types-CCpc2Dcv.d.ts} +77 -17
- package/dist/{types-Dnemwd77.d.ts → types-CZTnPFzM.d.ts} +50 -11
- package/dist/{types-C97IskBw.d.ts → types-CdlxsYQh.d.ts} +23 -11
- package/dist/{types-DxiCGmmd.d.ts → types-ClZaWzfb.d.ts} +9 -6
- package/dist/types-DX0LaKTb.d.ts +157 -0
- package/dist/types-DiQjupG2.d.ts +332 -0
- package/dist/types-DqzsnlSA.js +67 -0
- package/dist/types-_sHy8BQf.d.ts +65 -0
- package/dist/types-fbZ7JEXr.d.ts +89 -0
- package/dist/types-tIgIeIKJ.d.ts +66 -0
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +2 -2
- package/dist/usage-CHOtwL19.js +1 -0
- package/dist/usage-DHtE8j4E.js +32 -0
- package/dist/{usage-ItS7nLcl.js → usage-T5mXq98v.js} +56 -13
- package/dist/{validation-error-Ba264OaJ.d.ts → validation-error-Bg5Tpluk.d.ts} +1 -1
- package/dist/{validation-error-CnjZ4t92.js → validation-error-ZfUHbKvf.js} +1 -1
- package/dist/validity-CZ7-y0Cj.js +79 -0
- package/dist/{verifier-BxBo6I44.js → verifier-DHuh-okk.js} +68 -21
- package/dist/verify-DbCL9bnB.js +1770 -0
- package/dist/{version-BvacVTZR.js → version-CEbQ5UeM.js} +4 -3
- package/dist/version-DXkYUISx.js +1 -0
- package/dist/{views-Soe7bGSC.js → views-DTIIO-oQ.js} +41 -2
- package/dist/{permissions-DttnqqxC.d.ts → vocabulary-D6lPdb4Z.d.ts} +120 -29
- package/dist/vue/index.d.ts +25 -21
- package/dist/vue/index.js +25 -9
- package/dist/waiter-BGUtGYoU.js +67 -0
- package/dist/waiter-CKy4MQSY.d.ts +36 -0
- package/dist/watch-Cb-NcaUw.js +1 -0
- package/dist/{watch-DVBJ9cBq.js → watch-CszoTJMq.js} +47 -8
- package/dist/webmcp/index.d.ts +2 -2
- package/dist/webmcp/index.js +13 -37
- package/dist/where-scope-Dv-WTP-w.js +306 -0
- package/dist/who-can-D0QoYbEb.js +364 -0
- package/dist/wire-delegation-Cv3W2eaM.js +36 -0
- package/dist/wire-denial-C7PaVYEM.js +27 -0
- package/dist/workflow/index.d.ts +5 -0
- package/dist/workflow/index.js +223 -0
- package/dist/workflow-sdk/index.d.ts +56 -0
- package/dist/workflow-sdk/index.js +78 -0
- package/dist/wrap-Bd1Tejur.d.ts +15 -0
- package/dist/wrap-gX61EtpB.js +27 -0
- package/package.json +140 -41
- package/schemas/access-event-v1.json +118 -0
- package/schemas/approval-request-v1.json +34 -1
- package/schemas/approval-signature-v1.json +94 -0
- package/schemas/automation-event-v1.json +113 -0
- package/schemas/capability-v1.json +84 -0
- package/schemas/catalog-event-v1.json +87 -0
- package/schemas/catalog-v1.json +129 -12
- package/schemas/cli-commands-v1.json +164 -0
- package/schemas/cli-result-v1.json +96 -0
- package/schemas/cloud-api-v1.json +5407 -0
- package/schemas/connector-v1.json +408 -0
- package/schemas/credential-event-v1.json +81 -0
- package/schemas/credential-v1.json +134 -0
- package/schemas/decision-event-v1.json +288 -0
- package/schemas/delivery-event-v1.json +117 -0
- package/schemas/directory-event-v1.json +85 -0
- package/schemas/evidence-export-v1.json +54 -0
- package/schemas/membership-event-v1.json +93 -0
- package/schemas/policy-v1.json +68 -0
- package/schemas/pushed-policy-v1.json +236 -0
- package/schemas/run-v1.json +162 -0
- package/schemas/snapshot-v1.json +138 -0
- package/schemas/supabase-claims-v1.json +4 -4
- package/schemas/supabase-manifest-v1.json +5 -1
- package/schemas/support-session-v1.json +111 -0
- package/skills/permdock/SKILL.md +16 -12
- package/skills/permdock-agents/SKILL.md +40 -23
- package/skills/permdock-agents/references/operations-automations-chat.md +221 -0
- package/skills/permdock-agents/references/runtimes.md +22 -18
- package/skills/permdock-approvals/SKILL.md +29 -13
- package/skills/permdock-approvals/references/delivery-and-waiters.md +172 -0
- package/skills/permdock-approvals/references/stores-and-resume.md +21 -7
- package/skills/permdock-audit/SKILL.md +3 -3
- package/skills/permdock-credentials/SKILL.md +5 -5
- package/skills/permdock-credentials/references/tokens-keys-links.md +19 -10
- package/skills/permdock-data/SKILL.md +6 -6
- package/skills/permdock-data/references/queries-and-rls.md +13 -8
- package/skills/permdock-data/references/relationships.md +3 -3
- package/skills/permdock-tenancy/SKILL.md +20 -7
- package/skills/permdock-tenancy/references/contacts-and-support-sessions.md +122 -0
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +6 -4
- package/skills/permdock-wire/SKILL.md +18 -12
- package/skills/permdock-wire/references/adapters.md +146 -50
- package/skills/permdock-wire/references/policy-options.md +15 -6
- package/skills/permdock-wire/references/presets-and-recipes.md +58 -0
- package/dist/approvals-DbYAuNkG.js +0 -224
- package/dist/arazzo-C9chp3ST.js +0 -54
- package/dist/bind-C_ob3LKa.d.ts +0 -25
- package/dist/catalog-CRW5Mx_B.js +0 -2
- package/dist/catalog-CYj-mX2O.js +0 -48
- package/dist/catalog-DWF5cYqB.js +0 -55
- package/dist/cloud-CfwZ39Rl.js +0 -50
- package/dist/cloud-DWLXO2af.js +0 -118
- package/dist/collect-CHB22Sx4.js +0 -83
- package/dist/collect-DSWOk19R.js +0 -2
- package/dist/commands-BeaGNj_o.js +0 -97
- package/dist/config-ir40y8m0.js +0 -36
- package/dist/create-CMwIl-w2.js +0 -253
- package/dist/delegation-D8pUEuce.js +0 -103
- package/dist/diff-C9RDjjhs.js +0 -48
- package/dist/doctor-Djh6JDEk.js +0 -53
- package/dist/doctor-DvH0IQff.js +0 -1194
- package/dist/doctor-collect-CjdO0wQX.js +0 -665
- package/dist/duration-xK2jGFVc.js +0 -25
- package/dist/errors-CWfoNg9N.js +0 -47
- package/dist/errors-DRnGZHzF.js +0 -30
- package/dist/evaluation-items-CfCCejQd.js +0 -40
- package/dist/expiry-BoBJ8Tvc.js +0 -7
- package/dist/fields-BMl1RxoX.js +0 -26
- package/dist/grantee-Cv5Sogfv.js +0 -602
- package/dist/headers-BZSDieNT.js +0 -6
- package/dist/headers-Cf-zWvsO.d.ts +0 -6
- package/dist/ids-DC4V4CFu.js +0 -18
- package/dist/index-0nNqHspG.d.ts +0 -6
- package/dist/index-BNc7Wer_.d.ts +0 -483
- package/dist/index-C7Tw7MaW.d.ts +0 -201
- package/dist/instance-options-Dhhcnm3y.js +0 -22
- package/dist/load-DwJUafYN.js +0 -2
- package/dist/manifest-iaoBXHKc.js +0 -783
- package/dist/map-AcxK9o_D.js +0 -147
- package/dist/may-use-DndQ5tQ-.js +0 -77
- package/dist/openapi-CQTsgKoB.js +0 -164
- package/dist/permdock-CbgvLnuo.js +0 -3479
- package/dist/permissions-DVoF6dMt.js +0 -662
- package/dist/policy-xyWg7QdR.js +0 -1122
- package/dist/powersync-CrBX8hY6.js +0 -2
- package/dist/powersync-DE19b9dT.js +0 -62
- package/dist/protected-BdnIEFkY.d.ts +0 -27
- package/dist/protected-xAr24FEC.d.ts +0 -40
- package/dist/relations-cjOL01hZ.js +0 -505
- package/dist/rls-P-BeBx0n.js +0 -238
- package/dist/rls-graph-CHwx0V8q.js +0 -435
- package/dist/rls-ownership-DcYlZ09B.js +0 -843
- package/dist/rls-shared-Cewd_-zI.js +0 -495
- package/dist/rls-verify-CMv9H3wV.js +0 -746
- package/dist/run-BWc9qqvE.js +0 -174
- package/dist/server-DlZ28Oz5.js +0 -268
- package/dist/sink-B1fZzIMf.d.ts +0 -104
- package/dist/sink-Bd9PSyfq.js +0 -141
- package/dist/skills-C5CbhhpG.js +0 -56
- package/dist/snapshot-Enxd0n-s.js +0 -975
- package/dist/sql-xdg5f4Fi.js +0 -27
- package/dist/src-BDwEZWrZ.js +0 -568
- package/dist/store-jOBYpiXC.d.ts +0 -36
- package/dist/stores-C0IMQrGI.d.ts +0 -52
- package/dist/subject-C6dLxqHU.js +0 -24
- package/dist/supabase-config-Bj3iDH2I.js +0 -472
- package/dist/supabase-hook-gd3s8bxB.js +0 -2
- package/dist/supabase-s4o9s1O1.js +0 -83
- package/dist/thenable-okc2xDsj.js +0 -10
- package/dist/types-BnIEz1sU.d.ts +0 -48
- package/dist/types-Bvc4oWT6.d.ts +0 -9
- package/dist/types-CKNSyIf_.d.ts +0 -52
- package/dist/types-Cq_H8N_X.d.ts +0 -197
- package/dist/usage-B0YuTQRO.js +0 -42
- package/dist/usage-DorAJiU_.js +0 -2
- package/dist/vocabulary-DA8a8zif.d.ts +0 -56
- package/dist/watch-BwxLTYMZ.js +0 -2
package/dist/mcp/index.js
CHANGED
|
@@ -1,83 +1,28 @@
|
|
|
1
|
-
import { t as compact } from "../compact-
|
|
1
|
+
import { r as isRecord, t as compact } from "../compact-CAf557ZB.js";
|
|
2
2
|
import { n as freezeDeep } from "../freeze-CrU8nQeX.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { i as stepUpOf } from "../problem-details-cn5X30gZ.js";
|
|
4
|
+
import { t as describe } from "../describe-BybMRY7A.js";
|
|
5
|
+
import { m as annotationsFor } from "../permission-registry-Br4jSNVi.js";
|
|
6
|
+
import { t as actorMayCallTool } from "../delegation-DaXVdDhM.js";
|
|
7
7
|
import { n as resourceRef } from "../resource-ref-CaS9yVPi.js";
|
|
8
|
-
import {
|
|
9
|
-
import { t as
|
|
10
|
-
import {
|
|
8
|
+
import { a as hasScope, c as withApp, i as challengeScope, o as scopesReaching } from "../permdock-B9JxkBwC.js";
|
|
9
|
+
import { t as anonymousSubject } from "../subject-BGoM5o8B.js";
|
|
10
|
+
import { t as composeWraps } from "../wrap-gX61EtpB.js";
|
|
11
|
+
import { l as protectedResourceMetadataUrl, r as bearerChallenge } from "../problem-CTviyH5L.js";
|
|
11
12
|
import { t as clientNameOf } from "../clients-DjU5ABMy.js";
|
|
12
|
-
import { n as mapClaimsToSubject } from "../map-claims-
|
|
13
|
-
import {
|
|
14
|
-
import { n as createAgentKernel } from "../kernel-
|
|
13
|
+
import { n as mapClaimsToSubject } from "../map-claims-D3oRmTk0.js";
|
|
14
|
+
import { r as instanceOptions } from "../build-instance-BMnAudHn.js";
|
|
15
|
+
import { n as createAgentKernel, r as refusalText } from "../kernel-5JatXyND.js";
|
|
15
16
|
import { t as boundedMap } from "../lru-8q4WZjBV.js";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
function mcpActorKind(kind) {
|
|
20
|
-
if (kind === void 0) return DEFAULT_MCP_ACTOR_KIND;
|
|
21
|
-
return typeof kind === "string" && kind !== "" ? kind : void 0;
|
|
22
|
-
}
|
|
23
|
-
function isRecord$1(value) {
|
|
24
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Maps the `AuthInfo` the MCP SDK's bearer verification produced to a
|
|
28
|
-
* `Subject`: the principal from the verified claims in `extra`, the client
|
|
29
|
-
* as an actor of kind `actorKind` (`mcp-client` by default), the granted
|
|
30
|
-
* scopes as the delegation. Never verifies and never throws; anything
|
|
31
|
-
* unusable, including an `actorKind` that is not a non-empty string, is
|
|
32
|
-
* the anonymous subject.
|
|
33
|
-
*/
|
|
34
|
-
function subjectFromMcp(authInfo, options = {}) {
|
|
35
|
-
try {
|
|
36
|
-
const kind = mcpActorKind(options.actorKind);
|
|
37
|
-
if (authInfo === void 0 || !isRecord$1(authInfo.extra) || kind === void 0) return anonymousSubject();
|
|
38
|
-
const claims = compact({
|
|
39
|
-
...authInfo.extra,
|
|
40
|
-
authorization_details: authInfo.extra["authorizationDetails"] ?? authInfo.extra["authorization_details"],
|
|
41
|
-
scope: authInfo.scopes?.join(" "),
|
|
42
|
-
client_id: authInfo.clientId,
|
|
43
|
-
exp: authInfo.expiresAt
|
|
44
|
-
});
|
|
45
|
-
const mapped = mapClaimsToSubject(claims, options);
|
|
46
|
-
if (mapped.invalidClaims || mapped.invalidChain || mapped.subject.principal === null) return anonymousSubject();
|
|
47
|
-
const clientId = authInfo.clientId;
|
|
48
|
-
return freezeDeep(compact({
|
|
49
|
-
...mapped.subject,
|
|
50
|
-
actor: typeof clientId === "string" && clientId !== "" ? compact({
|
|
51
|
-
id: clientId,
|
|
52
|
-
kind,
|
|
53
|
-
client: clientNameOf(options.clients, clientId)
|
|
54
|
-
}) : mapped.subject.actor
|
|
55
|
-
}));
|
|
56
|
-
} catch {
|
|
57
|
-
return anonymousSubject();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/mcp/create.ts
|
|
17
|
+
import { t as delegationFrom } from "../delegation-input-FTxMK3ji.js";
|
|
18
|
+
import { n as deniedToolRefusal, r as toolErrorResult, t as approvalToolRefusal } from "../tool-refusal-CMLN5xhn.js";
|
|
19
|
+
//#region src/mcp/mcp-auth.ts
|
|
62
20
|
/** `_meta` key on `tools/call`, `resources/read` and `prompts/get` carrying an approval token. */
|
|
63
21
|
const APPROVAL_META_KEY = "dev.permdock/approval";
|
|
64
|
-
const SESSIONS_PER_SERVER = 1e3;
|
|
65
22
|
const CLIENT_CAPABILITIES = "io.modelcontextprotocol/clientCapabilities";
|
|
66
23
|
const PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion";
|
|
67
24
|
/** The first protocol revision whose list results define `ttlMs` and `cacheScope`. */
|
|
68
25
|
const CACHEABLE_LISTS_SINCE = "2026-07-28";
|
|
69
|
-
/** What a completion re-check still accepts after the handler ran. */
|
|
70
|
-
function stillAllowed(decision, approved) {
|
|
71
|
-
switch (decision.outcome) {
|
|
72
|
-
case "granted": return true;
|
|
73
|
-
case "approval-required": return approved !== void 0 && decision.token === approved;
|
|
74
|
-
case "denied": return decision.denials.length > 0 && decision.denials.every((denial) => denial.reason === "limit");
|
|
75
|
-
default: return decision;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
function isRecord(value) {
|
|
79
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
80
|
-
}
|
|
81
26
|
function contextOf(value) {
|
|
82
27
|
return isRecord(value) ? value : {};
|
|
83
28
|
}
|
|
@@ -94,19 +39,6 @@ function approvalTokenOf(context) {
|
|
|
94
39
|
const fromAuth = context.http?.authInfo?.extra?.["approval"];
|
|
95
40
|
return typeof fromAuth === "string" && fromAuth !== "" ? fromAuth : void 0;
|
|
96
41
|
}
|
|
97
|
-
function authorizationDetailsOf(authInfo) {
|
|
98
|
-
const details = authInfo.extra?.["authorizationDetails"] ?? authInfo.extra?.["authorization_details"];
|
|
99
|
-
return Array.isArray(details) ? details : void 0;
|
|
100
|
-
}
|
|
101
|
-
function delegationOf(authInfo) {
|
|
102
|
-
return compact({
|
|
103
|
-
scopes: authInfo.scopes,
|
|
104
|
-
authorizationDetails: authorizationDetailsOf(authInfo)
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
function hasScope(authInfo, scopes) {
|
|
108
|
-
return scopes.some((scope) => (authInfo.scopes ?? []).includes(scope));
|
|
109
|
-
}
|
|
110
42
|
function resourceMetadataOf(authInfo) {
|
|
111
43
|
if (authInfo.resourceMetadataUrl !== void 0) return authInfo.resourceMetadataUrl;
|
|
112
44
|
const resource = authInfo.resource;
|
|
@@ -129,6 +61,41 @@ function definesCacheScope(context) {
|
|
|
129
61
|
const version = context.mcpReq?.envelope?.[PROTOCOL_VERSION];
|
|
130
62
|
return typeof version === "string" && version >= CACHEABLE_LISTS_SINCE;
|
|
131
63
|
}
|
|
64
|
+
function tenantOf(tenant) {
|
|
65
|
+
if (typeof tenant !== "function") return tenant;
|
|
66
|
+
return (call) => tenant(call.authInfo ?? {});
|
|
67
|
+
}
|
|
68
|
+
function sessionKey(context) {
|
|
69
|
+
return context.sessionId ?? "";
|
|
70
|
+
}
|
|
71
|
+
function declaredScopes(name, value) {
|
|
72
|
+
if (value === void 0) return;
|
|
73
|
+
const scopes = Array.isArray(value) ? value : [];
|
|
74
|
+
const names = scopes.filter((scope) => typeof scope === "string" && scope !== "");
|
|
75
|
+
const [first, ...rest] = names;
|
|
76
|
+
if (first === void 0 || names.length !== scopes.length) throw new TypeError(`permdock/mcp: tool ${name} sets oauthScopes, which must be a non-empty list of scope names.`);
|
|
77
|
+
return Object.freeze([first, ...rest]);
|
|
78
|
+
}
|
|
79
|
+
function challengeFor(own, reaching, challenged) {
|
|
80
|
+
return async (context) => {
|
|
81
|
+
const first = await own?.(context);
|
|
82
|
+
if (first !== void 0) return first;
|
|
83
|
+
const authInfo = context.authInfo;
|
|
84
|
+
if (authInfo === void 0 || hasScope(authInfo.scopes, reaching)) return;
|
|
85
|
+
return { scopes: [challenged] };
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/mcp/refusals.ts
|
|
90
|
+
/** What a completion re-check still accepts after the handler ran. */
|
|
91
|
+
function stillAllowed(decision, approved) {
|
|
92
|
+
switch (decision.outcome) {
|
|
93
|
+
case "granted": return true;
|
|
94
|
+
case "approval-required": return approved !== void 0 && decision.token === approved;
|
|
95
|
+
case "denied": return decision.denials.length > 0 && decision.denials.every((denial) => denial.reason === "limit");
|
|
96
|
+
default: return decision;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
132
99
|
function acceptsUrlElicitation(context, fallback) {
|
|
133
100
|
const fromEnvelope = context.mcpReq?.envelope?.[CLIENT_CAPABILITIES];
|
|
134
101
|
const capabilities = isRecord(fromEnvelope) ? fromEnvelope : fallback?.();
|
|
@@ -160,30 +127,10 @@ function urlElicitation(key, message, url, requestState) {
|
|
|
160
127
|
});
|
|
161
128
|
}
|
|
162
129
|
function deniedRefusal(decision, permission, data) {
|
|
163
|
-
|
|
164
|
-
const resource = resourceRef(permission, data);
|
|
165
|
-
return {
|
|
166
|
-
text: `Denied: ${resource.id === void 0 ? permission.key : `${permission.key} on ${resource.id}`}.${alternatives.length === 0 ? "" : ` You may: ${alternatives.join(", ")}.`}`,
|
|
167
|
-
structured: {
|
|
168
|
-
outcome: "denied",
|
|
169
|
-
permission: permission.key,
|
|
170
|
-
resource,
|
|
171
|
-
denials: wireDenials(decision.denials),
|
|
172
|
-
alternatives,
|
|
173
|
-
detail: describe(decision).detail
|
|
174
|
-
}
|
|
175
|
-
};
|
|
130
|
+
return deniedToolRefusal(decision, permission, resourceRef(permission, data));
|
|
176
131
|
}
|
|
177
132
|
function approvalRefusal(decision, permission, data) {
|
|
178
|
-
return
|
|
179
|
-
text: describe(decision).detail,
|
|
180
|
-
structured: {
|
|
181
|
-
outcome: "approval-required",
|
|
182
|
-
permission: permission.key,
|
|
183
|
-
resource: resourceRef(permission, data),
|
|
184
|
-
token: decision.token
|
|
185
|
-
}
|
|
186
|
-
};
|
|
133
|
+
return approvalToolRefusal(decision, permission, resourceRef(permission, data));
|
|
187
134
|
}
|
|
188
135
|
function plainRefusal(permission, text, extra) {
|
|
189
136
|
return {
|
|
@@ -197,10 +144,6 @@ function plainRefusal(permission, text, extra) {
|
|
|
197
144
|
}
|
|
198
145
|
};
|
|
199
146
|
}
|
|
200
|
-
function tenantOf(tenant) {
|
|
201
|
-
if (typeof tenant !== "function") return tenant;
|
|
202
|
-
return (call) => tenant(call.authInfo ?? {});
|
|
203
|
-
}
|
|
204
147
|
function failedRefusal(permission, failure) {
|
|
205
148
|
switch (failure) {
|
|
206
149
|
case "load-failed": return plainRefusal(permission, `Denied: ${permission.key} failed closed.`, { denials: [{
|
|
@@ -216,388 +159,473 @@ function failedRefusal(permission, failure) {
|
|
|
216
159
|
}
|
|
217
160
|
}
|
|
218
161
|
function toolRefusal(refusal) {
|
|
219
|
-
|
|
220
|
-
return {
|
|
221
|
-
isError: true,
|
|
222
|
-
content: [{
|
|
223
|
-
type: "text",
|
|
224
|
-
text: refusal.text
|
|
225
|
-
}],
|
|
226
|
-
structuredContent: refusal.structured
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
function requirePermission(kind, name, config) {
|
|
230
|
-
const permission = isRecord(config) ? config["permission"] : void 0;
|
|
231
|
-
if (!isRecord(permission) || typeof permission["key"] !== "string") throw new TypeError(`permdock/mcp: ${kind} ${name} has no permission; every guarded registration needs one.`);
|
|
232
|
-
return permission;
|
|
233
|
-
}
|
|
234
|
-
function sessionKey(context) {
|
|
235
|
-
return context.sessionId ?? "";
|
|
162
|
+
return refusal.inputRequired ?? toolErrorResult(refusal);
|
|
236
163
|
}
|
|
237
164
|
function throwRefusal(refusal) {
|
|
238
165
|
if (refusal.inputRequired !== void 0) return refusal.inputRequired;
|
|
239
166
|
throw new Error(refusal.text);
|
|
240
167
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
if (
|
|
247
|
-
|
|
168
|
+
/** The MRTR URL elicitation that sends the user to `options.approval.at`, when the client accepts one. */
|
|
169
|
+
async function approvalInput(options, decision, handlerContext, context, capabilities) {
|
|
170
|
+
const at = options.approval?.at;
|
|
171
|
+
if (at === void 0 || !acceptsUrlElicitation(context, capabilities)) return;
|
|
172
|
+
const url = withParams(at, { token: decision.token });
|
|
173
|
+
if (url === void 0) return;
|
|
174
|
+
const requestState = options.requestState === void 0 ? decision.token : await options.requestState.mint(decision.token, handlerContext);
|
|
175
|
+
return urlElicitation("approval", options.approval?.hint ?? describe(decision).detail, url, requestState);
|
|
248
176
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
177
|
+
/** A step-up denial: the RFC 9470 challenge, and a URL elicitation to `stepUpAt` when the client accepts one. */
|
|
178
|
+
function stepUpRefusal(stepUpAt, decision, permission, data, context, capabilities) {
|
|
179
|
+
const base = deniedRefusal(decision, permission, data);
|
|
180
|
+
const { acrValues, maxAge } = stepUpOf(decision);
|
|
181
|
+
const url = stepUpAt === void 0 || !acceptsUrlElicitation(context, capabilities) ? void 0 : withParams(stepUpAt, {
|
|
182
|
+
acr_values: acrValues?.join(" "),
|
|
183
|
+
max_age: maxAge === void 0 ? void 0 : String(maxAge)
|
|
184
|
+
});
|
|
185
|
+
return compact({
|
|
186
|
+
text: base.text,
|
|
187
|
+
structured: compact({
|
|
188
|
+
...base.structured,
|
|
189
|
+
error: "insufficient_user_authentication",
|
|
190
|
+
acr_values: acrValues?.join(" "),
|
|
191
|
+
max_age: maxAge,
|
|
192
|
+
www_authenticate: bearerChallenge(compact({
|
|
193
|
+
error: "insufficient_user_authentication",
|
|
194
|
+
acrValues,
|
|
195
|
+
maxAge
|
|
196
|
+
}))
|
|
197
|
+
}),
|
|
198
|
+
inputRequired: url === void 0 ? void 0 : urlElicitation("step_up", `Sign in again to use ${permission.key}.`, url, void 0)
|
|
199
|
+
});
|
|
269
200
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
subject: (call) => options.subject(call.authInfo ?? {}),
|
|
275
|
-
actor: (call) => {
|
|
276
|
-
const clientId = call.authInfo?.clientId;
|
|
277
|
-
return typeof clientId === "string" && clientId !== "" ? compact({
|
|
278
|
-
id: clientId,
|
|
279
|
-
kind: actorKind,
|
|
280
|
-
client: clientNameOf(options.clients, clientId)
|
|
281
|
-
}) : void 0;
|
|
282
|
-
},
|
|
283
|
-
delegation: (call) => call.authInfo === void 0 ? void 0 : delegationOf(call.authInfo),
|
|
284
|
-
tenant: tenantOf(options.tenant),
|
|
285
|
-
store: options.store,
|
|
286
|
-
adapter: "mcp",
|
|
287
|
-
boundary: "mcp-args",
|
|
288
|
-
wrap: options.otel,
|
|
289
|
-
...instanceOptions(options)
|
|
290
|
-
}));
|
|
291
|
-
const forThisServer = (authInfo) => options.resource === void 0 || sameResource(options.resource, authInfo.resource);
|
|
292
|
-
const reachOf = (permission, declared) => declared === void 0 ? {
|
|
201
|
+
//#endregion
|
|
202
|
+
//#region src/mcp/call-check.ts
|
|
203
|
+
function reachOf(policy, permission, declared) {
|
|
204
|
+
return declared === void 0 ? {
|
|
293
205
|
scopes: scopesReaching(policy, permission),
|
|
294
206
|
challenge: challengeScope(policy, permission)
|
|
295
207
|
} : {
|
|
296
208
|
scopes: declared,
|
|
297
209
|
challenge: declared[0]
|
|
298
210
|
};
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
211
|
+
}
|
|
212
|
+
function forThisServer(checks, authInfo) {
|
|
213
|
+
return checks.options.resource === void 0 || sameResource(checks.options.resource, authInfo.resource);
|
|
214
|
+
}
|
|
215
|
+
function reachable(checks, authInfo, reach) {
|
|
216
|
+
return authInfo === void 0 ? checks.options.requireAuthInfo !== true : forThisServer(checks, authInfo) && hasScope(authInfo.scopes, reach.scopes);
|
|
217
|
+
}
|
|
218
|
+
/** The refusal a token earns before any decision: none, the wrong resource, or a missing scope. */
|
|
219
|
+
function credentialRefusal(checks, permission, reach, authInfo) {
|
|
220
|
+
if (authInfo === void 0) return checks.options.requireAuthInfo === true ? plainRefusal(permission, "Denied: no verified credentials.", { error: "invalid_token" }) : void 0;
|
|
221
|
+
if (!forThisServer(checks, authInfo)) return plainRefusal(permission, "Denied: the token was not issued for this server.", { error: "invalid_token" });
|
|
222
|
+
if (hasScope(authInfo.scopes, reach.scopes)) return;
|
|
223
|
+
const resourceMetadata = resourceMetadataOf(authInfo);
|
|
224
|
+
const challenged = reach.challenge;
|
|
225
|
+
return plainRefusal(permission, `Denied: ${permission.key} needs the ${challenged} scope.`, compact({
|
|
226
|
+
error: "insufficient_scope",
|
|
227
|
+
scope: challenged,
|
|
228
|
+
resource_metadata: resourceMetadata,
|
|
229
|
+
www_authenticate: bearerChallenge(compact({
|
|
230
|
+
error: "insufficient_scope",
|
|
231
|
+
scopes: [challenged],
|
|
232
|
+
resourceMetadata
|
|
233
|
+
}))
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
/** The completion re-check of a long-running tool: the call must still be allowed, or approved with the same token. */
|
|
237
|
+
async function recheck(checks, binding, args, call, permission, approved, tool) {
|
|
238
|
+
const rechecked = await checks.kernel.check(binding, args, call, compact({
|
|
239
|
+
simulate: true,
|
|
240
|
+
tool
|
|
241
|
+
}));
|
|
242
|
+
if (!rechecked.ok) return {
|
|
243
|
+
ok: false,
|
|
244
|
+
refusal: failedRefusal(permission, rechecked.failure)
|
|
307
245
|
};
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
})
|
|
316
|
-
return compact({
|
|
317
|
-
text: base.text,
|
|
318
|
-
structured: compact({
|
|
319
|
-
...base.structured,
|
|
320
|
-
error: "insufficient_user_authentication",
|
|
321
|
-
acr_values: acrValues?.join(" "),
|
|
322
|
-
max_age: maxAge,
|
|
323
|
-
www_authenticate: bearerChallenge(compact({
|
|
324
|
-
error: "insufficient_user_authentication",
|
|
325
|
-
acrValues,
|
|
326
|
-
maxAge
|
|
327
|
-
}))
|
|
328
|
-
}),
|
|
329
|
-
inputRequired: url === void 0 ? void 0 : urlElicitation("step_up", `Sign in again to use ${permission.key}.`, url, void 0)
|
|
330
|
-
});
|
|
246
|
+
if (stillAllowed(rechecked.raw, approved)) return { ok: true };
|
|
247
|
+
return {
|
|
248
|
+
ok: false,
|
|
249
|
+
refusal: rechecked.raw.outcome === "denied" ? {
|
|
250
|
+
...deniedRefusal(rechecked.raw, permission, rechecked.data),
|
|
251
|
+
decision: rechecked.raw,
|
|
252
|
+
permdock: rechecked.permdock
|
|
253
|
+
} : plainRefusal(permission, `Denied: ${permission.key} was revoked before the call completed.`, {})
|
|
331
254
|
};
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
255
|
+
}
|
|
256
|
+
async function decideCall(checks, permission, reach, args, load, context, handlerContext, capabilities, completion, tool) {
|
|
257
|
+
const authInfo = context.http?.authInfo;
|
|
258
|
+
const refused = credentialRefusal(checks, permission, reach, authInfo);
|
|
259
|
+
if (refused !== void 0) return {
|
|
260
|
+
ok: false,
|
|
261
|
+
refusal: refused
|
|
262
|
+
};
|
|
263
|
+
const binding = compact({
|
|
264
|
+
permission,
|
|
265
|
+
data: load === void 0 ? void 0 : () => load()
|
|
266
|
+
});
|
|
267
|
+
const call = compact({ authInfo });
|
|
268
|
+
if (completion !== void 0) return recheck(checks, binding, args, call, permission, completion.approved, tool);
|
|
269
|
+
const checked = await checks.kernel.check(binding, args, call, compact({
|
|
270
|
+
resumeToken: approvalTokenOf(context),
|
|
271
|
+
tool
|
|
272
|
+
}));
|
|
273
|
+
if (!checked.ok) return {
|
|
274
|
+
ok: false,
|
|
275
|
+
refusal: failedRefusal(permission, checked.failure)
|
|
276
|
+
};
|
|
277
|
+
const { raw, decision, data } = checked;
|
|
278
|
+
switch (decision.outcome) {
|
|
279
|
+
case "granted": return raw.outcome === "approval-required" ? {
|
|
280
|
+
ok: true,
|
|
281
|
+
approved: raw.token
|
|
282
|
+
} : { ok: true };
|
|
283
|
+
case "denied": return {
|
|
339
284
|
ok: false,
|
|
340
|
-
refusal:
|
|
285
|
+
refusal: {
|
|
286
|
+
...decision.denials.some((denial) => denial.reason === "insufficient-user-authentication") ? stepUpRefusal(checks.options.stepUp?.at, decision, permission, data, context, capabilities) : deniedRefusal(decision, permission, data),
|
|
287
|
+
decision,
|
|
288
|
+
permdock: checked.permdock
|
|
289
|
+
}
|
|
341
290
|
};
|
|
342
|
-
|
|
343
|
-
const resourceMetadata = resourceMetadataOf(authInfo);
|
|
344
|
-
const challenged = reach.challenge;
|
|
291
|
+
case "approval-required": try {
|
|
345
292
|
return {
|
|
346
293
|
ok: false,
|
|
347
|
-
refusal:
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
scopes: [challenged],
|
|
354
|
-
resourceMetadata
|
|
355
|
-
}))
|
|
356
|
-
}))
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
const binding = compact({
|
|
360
|
-
permission,
|
|
361
|
-
data: load === void 0 ? void 0 : () => load()
|
|
362
|
-
});
|
|
363
|
-
const call = compact({ authInfo });
|
|
364
|
-
if (completion !== void 0) {
|
|
365
|
-
const rechecked = await kernel.check(binding, void 0, call, { simulate: true });
|
|
366
|
-
if (!rechecked.ok) return {
|
|
367
|
-
ok: false,
|
|
368
|
-
refusal: failedRefusal(permission, rechecked.failure)
|
|
294
|
+
refusal: compact({
|
|
295
|
+
...approvalRefusal(decision, permission, data),
|
|
296
|
+
decision,
|
|
297
|
+
permdock: checked.permdock,
|
|
298
|
+
inputRequired: await approvalInput(checks.options, decision, handlerContext, context, capabilities)
|
|
299
|
+
})
|
|
369
300
|
};
|
|
370
|
-
|
|
301
|
+
} catch {
|
|
371
302
|
return {
|
|
372
303
|
ok: false,
|
|
373
|
-
refusal:
|
|
304
|
+
refusal: failedRefusal(permission, "failed")
|
|
374
305
|
};
|
|
375
306
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
inputRequired: await approvalInput(decision, handlerContext, context, capabilities)
|
|
397
|
-
})
|
|
398
|
-
};
|
|
399
|
-
} catch {
|
|
400
|
-
return {
|
|
401
|
-
ok: false,
|
|
402
|
-
refusal: failedRefusal(permission, "failed")
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
default: return decision;
|
|
307
|
+
default: return decision;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** `decideCall` with the refusal text replaced by `deniedText`'s. */
|
|
311
|
+
async function checkCall(checks, permission, reach, args, load, context, handlerContext, capabilities, completion, tool) {
|
|
312
|
+
const checked = await decideCall(checks, permission, reach, args, load, context, handlerContext, capabilities, completion, tool);
|
|
313
|
+
const { deniedText } = checks.options;
|
|
314
|
+
if (checked.ok || deniedText === void 0) return checked;
|
|
315
|
+
const { refusal } = checked;
|
|
316
|
+
return {
|
|
317
|
+
ok: false,
|
|
318
|
+
refusal: {
|
|
319
|
+
...refusal,
|
|
320
|
+
text: refusalText(deniedText, {
|
|
321
|
+
decision: refusal.decision ?? null,
|
|
322
|
+
permission,
|
|
323
|
+
text: refusal.text
|
|
324
|
+
}, (error) => {
|
|
325
|
+
checks.kernel.report(refusal.permdock, error);
|
|
326
|
+
})
|
|
406
327
|
}
|
|
407
328
|
};
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* The keys a list shows: unguarded ones, and guarded ones the token reaches and the subject may use.
|
|
332
|
+
* With `tools`, a guarded key is also a tool name an `agent` actor's `tools` list must name.
|
|
333
|
+
*/
|
|
334
|
+
async function visible(checks, context, permissionOf, keys, declaredOf = () => void 0, tools = false) {
|
|
335
|
+
const authInfo = context.http?.authInfo;
|
|
336
|
+
const shown = /* @__PURE__ */ new Set();
|
|
337
|
+
const guarded = [];
|
|
338
|
+
for (const key of keys) {
|
|
339
|
+
const permission = permissionOf(key);
|
|
340
|
+
if (permission === void 0) shown.add(key);
|
|
341
|
+
else if (reachable(checks, authInfo, reachOf(checks.policy, permission, declaredOf(key)))) guarded.push({
|
|
342
|
+
key,
|
|
343
|
+
permission
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
if (guarded.length === 0) return shown;
|
|
347
|
+
let permdock;
|
|
348
|
+
try {
|
|
349
|
+
permdock = await checks.kernel.instance(compact({ authInfo }));
|
|
350
|
+
} catch {
|
|
428
351
|
return shown;
|
|
429
|
-
}
|
|
430
|
-
const
|
|
352
|
+
}
|
|
353
|
+
for (const entry of guarded) if ((!tools || actorMayCallTool(permdock.subject.actor, entry.key)) && permdock.mayUse(entry.permission)) shown.add(entry.key);
|
|
354
|
+
return shown;
|
|
355
|
+
}
|
|
356
|
+
/** `handler` behind the call check; a refusal goes to `onRefusal` instead. */
|
|
357
|
+
function guard(checks, permission, load, handler, dataArgs, onRefusal, extra = {}) {
|
|
358
|
+
return async (...params) => {
|
|
431
359
|
const raw = params.at(-1);
|
|
432
360
|
const context = contextOf(raw);
|
|
433
|
-
const
|
|
434
|
-
const
|
|
435
|
-
const
|
|
361
|
+
const args = dataArgs(params);
|
|
362
|
+
const loader = load === void 0 ? void 0 : () => load(...args);
|
|
363
|
+
const reach = extra.reach ?? reachOf(checks.policy, permission, void 0);
|
|
364
|
+
const tool = extra.tool?.();
|
|
365
|
+
const checked = await checkCall(checks, permission, reach, args, loader, context, raw, extra.capabilities, void 0, tool);
|
|
436
366
|
let result;
|
|
437
367
|
if (checked.ok) {
|
|
438
368
|
result = await handler(...params);
|
|
439
369
|
if (extra.longRunning === true) {
|
|
440
|
-
const again = await
|
|
370
|
+
const again = await checkCall(checks, permission, reach, args, loader, context, raw, extra.capabilities, { approved: checked.approved }, tool);
|
|
441
371
|
if (!again.ok) result = onRefusal(again.refusal);
|
|
442
372
|
}
|
|
443
373
|
} else result = onRefusal(checked.refusal);
|
|
444
374
|
await extra.after?.(context);
|
|
445
375
|
return result;
|
|
446
376
|
};
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
if (!isRecord(result) || !Array.isArray(result[field])) return result;
|
|
465
|
-
const context = contextOf(rawContext);
|
|
466
|
-
const entries = result[field];
|
|
467
|
-
const shown = await visible(context, permissionOf, entries.map(keyOf), remember ? toolDeclared : void 0);
|
|
468
|
-
const kept = entries.filter((entry) => shown.has(keyOf(entry)));
|
|
469
|
-
if (remember) lastListed.set(sessionKey(context), [...shown].toSorted().join(","));
|
|
470
|
-
return definesCacheScope(context) ? {
|
|
471
|
-
...result,
|
|
472
|
-
[field]: kept,
|
|
473
|
-
cacheScope: "private"
|
|
474
|
-
} : {
|
|
475
|
-
...result,
|
|
476
|
-
[field]: kept
|
|
477
|
-
};
|
|
478
|
-
};
|
|
479
|
-
const filters = {
|
|
480
|
-
"tools/list": listFilter("tools", (entry) => entry.name, toolPermission, true),
|
|
481
|
-
"prompts/list": listFilter("prompts", (entry) => entry.name, promptPermission, false),
|
|
482
|
-
"resources/list": listFilter("resources", (entry) => entry.uri, resourcePermission, false),
|
|
483
|
-
"resources/templates/list": listFilter("resourceTemplates", (entry) => entry.uriTemplate, templatePermission, false)
|
|
484
|
-
};
|
|
485
|
-
const inner = server.server;
|
|
486
|
-
const capabilities = () => inner.getClientCapabilities?.();
|
|
487
|
-
const set = inner.setRequestHandler.bind(inner);
|
|
488
|
-
inner.setRequestHandler = (method, ...rest) => {
|
|
489
|
-
const filter = Object.hasOwn(filters, method) ? filters[method] : void 0;
|
|
490
|
-
const [handler] = rest;
|
|
491
|
-
if (filter !== void 0 && rest.length === 1 && typeof handler === "function") {
|
|
492
|
-
set(method, async (request, context) => filter(await handler(request, context), context));
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
set(method, ...rest);
|
|
496
|
-
};
|
|
497
|
-
for (const method of Object.keys(filters)) {
|
|
498
|
-
const existing = inner._getRequestHandler?.(method);
|
|
499
|
-
if (existing !== void 0) {
|
|
500
|
-
inner.removeRequestHandler(method);
|
|
501
|
-
inner.setRequestHandler(method, (request, context) => existing(request, context));
|
|
502
|
-
}
|
|
377
|
+
}
|
|
378
|
+
//#endregion
|
|
379
|
+
//#region src/mcp/protect-server.ts
|
|
380
|
+
const SESSIONS_PER_SERVER = 1e3;
|
|
381
|
+
function requirePermission(kind, name, config) {
|
|
382
|
+
const permission = isRecord(config) ? config["permission"] : void 0;
|
|
383
|
+
if (!isRecord(permission) || typeof permission["key"] !== "string") throw new TypeError(`permdock/mcp: ${kind} ${name} has no permission; every guarded registration needs one.`);
|
|
384
|
+
return permission;
|
|
385
|
+
}
|
|
386
|
+
function guardUpdates(registered, wrap, rename, currentName) {
|
|
387
|
+
const update = registered.update.bind(registered);
|
|
388
|
+
registered.update = (updates) => {
|
|
389
|
+
const next = { ...updates };
|
|
390
|
+
if (typeof updates["callback"] === "function") next["callback"] = wrap(updates["callback"]);
|
|
391
|
+
if (rename !== void 0 && currentName !== void 0) {
|
|
392
|
+
const to = updates["name"];
|
|
393
|
+
if (typeof to === "string" || to === null) rename(currentName(), to);
|
|
503
394
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
395
|
+
update(next);
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function protectServer(checks, server, enforcement) {
|
|
399
|
+
const tools = /* @__PURE__ */ new Map();
|
|
400
|
+
const toolScopes = /* @__PURE__ */ new Map();
|
|
401
|
+
const prompts = /* @__PURE__ */ new Map();
|
|
402
|
+
const resources = /* @__PURE__ */ new Map();
|
|
403
|
+
const templates = [];
|
|
404
|
+
const lastListed = boundedMap(SESSIONS_PER_SERVER);
|
|
405
|
+
const toolPermission = (name) => tools.get(name);
|
|
406
|
+
const toolDeclared = (name) => toolScopes.get(name);
|
|
407
|
+
const promptPermission = (name) => prompts.get(name);
|
|
408
|
+
const resourcePermission = (uri) => {
|
|
409
|
+
const direct = resources.get(uri);
|
|
410
|
+
if (direct !== void 0) return direct;
|
|
411
|
+
return templates.find((entry) => entry.template.uriTemplate.match(uri) !== null)?.permission;
|
|
412
|
+
};
|
|
413
|
+
const templatePermission = (uriTemplate) => templates.find((entry) => entry.template.uriTemplate.toString() === uriTemplate)?.permission;
|
|
414
|
+
const listFilter = (field, keyOf, permissionOf, remember) => async (result, rawContext) => {
|
|
415
|
+
if (!isRecord(result) || !Array.isArray(result[field])) return result;
|
|
416
|
+
const context = contextOf(rawContext);
|
|
417
|
+
const entries = result[field];
|
|
418
|
+
const shown = await visible(checks, context, permissionOf, entries.map(keyOf), remember ? toolDeclared : void 0, remember);
|
|
419
|
+
const kept = entries.filter((entry) => shown.has(keyOf(entry)));
|
|
420
|
+
if (remember) lastListed.set(sessionKey(context), [...shown].toSorted().join(","));
|
|
421
|
+
return definesCacheScope(context) ? {
|
|
422
|
+
...result,
|
|
423
|
+
[field]: kept,
|
|
424
|
+
cacheScope: "private"
|
|
425
|
+
} : {
|
|
426
|
+
...result,
|
|
427
|
+
[field]: kept
|
|
514
428
|
};
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
429
|
+
};
|
|
430
|
+
const filters = {
|
|
431
|
+
"tools/list": listFilter("tools", (entry) => entry.name, toolPermission, true),
|
|
432
|
+
"prompts/list": listFilter("prompts", (entry) => entry.name, promptPermission, false),
|
|
433
|
+
"resources/list": listFilter("resources", (entry) => entry.uri, resourcePermission, false),
|
|
434
|
+
"resources/templates/list": listFilter("resourceTemplates", (entry) => entry.uriTemplate, templatePermission, false)
|
|
435
|
+
};
|
|
436
|
+
const inner = server.server;
|
|
437
|
+
const capabilities = () => inner.getClientCapabilities?.();
|
|
438
|
+
const set = inner.setRequestHandler.bind(inner);
|
|
439
|
+
inner.setRequestHandler = (method, ...rest) => {
|
|
440
|
+
const filter = Object.hasOwn(filters, method) ? filters[method] : void 0;
|
|
441
|
+
const [handler] = rest;
|
|
442
|
+
if (filter !== void 0 && rest.length === 1 && typeof handler === "function") {
|
|
443
|
+
set(method, async (request, context) => filter(await handler(request, context), context));
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
set(method, ...rest);
|
|
447
|
+
};
|
|
448
|
+
for (const method of Object.keys(filters)) {
|
|
449
|
+
const existing = inner._getRequestHandler?.(method);
|
|
450
|
+
if (existing !== void 0) {
|
|
451
|
+
inner.removeRequestHandler(method);
|
|
452
|
+
inner.setRequestHandler(method, (request, context) => existing(request, context));
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const announce = async (context) => {
|
|
456
|
+
const key = sessionKey(context);
|
|
457
|
+
const before = lastListed.get(key);
|
|
458
|
+
if (before === void 0) return;
|
|
459
|
+
const after = [...await visible(checks, context, toolPermission, [...tools.keys()], toolDeclared, true)].toSorted().join(",");
|
|
460
|
+
if (after === before) return;
|
|
461
|
+
lastListed.set(key, after);
|
|
462
|
+
try {
|
|
463
|
+
await (context.mcpReq?.notify?.({ method: "notifications/tools/list_changed" }) ?? inner.sendToolListChanged?.());
|
|
464
|
+
} catch {}
|
|
465
|
+
};
|
|
466
|
+
const guardTool = (tool, permission, reach, load, handler, longRunning) => guard(checks, permission, load, handler, (params) => params.length >= 2 ? [params[0]] : [void 0], toolRefusal, {
|
|
467
|
+
after: announce,
|
|
468
|
+
longRunning,
|
|
469
|
+
capabilities,
|
|
470
|
+
reach,
|
|
471
|
+
tool
|
|
472
|
+
});
|
|
473
|
+
const originalTool = server.registerTool.bind(server);
|
|
474
|
+
const toolPermissionOf = (name, config) => {
|
|
475
|
+
if (enforcement === void 0 || config["permission"] !== void 0) return requirePermission("tool", name, config);
|
|
476
|
+
for (const field of ["data", "longRunning"]) if (config[field] !== void 0) throw new TypeError(`permdock/mcp: tool ${name} sets ${field}, but with enforce: 'procedure' its procedure decides.`);
|
|
477
|
+
return requirePermission("tool", name, { permission: enforcement.permissionFor(name) });
|
|
478
|
+
};
|
|
479
|
+
/** With `enforce: 'procedure'` the handler runs undecided: the procedure it calls decides. */
|
|
480
|
+
const wrapTool = (tool, permission, reach, load, handler, longRunning) => enforcement === void 0 ? guardTool(tool, permission, reach, load, handler, longRunning) : async (...params) => {
|
|
481
|
+
const result = await handler(...params);
|
|
482
|
+
await announce(contextOf(params.at(-1)));
|
|
483
|
+
return result;
|
|
484
|
+
};
|
|
485
|
+
const registerTool = (name, config, handler) => {
|
|
486
|
+
const permission = toolPermissionOf(name, config);
|
|
487
|
+
const { permission: _permission, data, scopeChallenge, longRunning: rawLongRunning, oauthScopes: rawScopes, ...passthrough } = config;
|
|
488
|
+
const load = data;
|
|
489
|
+
const longRunning = rawLongRunning === true;
|
|
490
|
+
const declared = declaredScopes(name, rawScopes === void 0 ? enforcement?.oauthScopesFor?.(name) : rawScopes);
|
|
491
|
+
const reach = reachOf(checks.policy, permission, declared);
|
|
492
|
+
let current = name;
|
|
493
|
+
const tool = () => current;
|
|
494
|
+
const registered = originalTool(name, {
|
|
495
|
+
...passthrough,
|
|
496
|
+
annotations: {
|
|
497
|
+
...annotationsFor(permission),
|
|
498
|
+
...passthrough["annotations"]
|
|
499
|
+
},
|
|
500
|
+
scopeChallenge: challengeFor(scopeChallenge, reach.scopes, reach.challenge)
|
|
501
|
+
}, wrapTool(tool, permission, reach, load, handler, longRunning));
|
|
502
|
+
tools.set(name, permission);
|
|
503
|
+
if (declared !== void 0) toolScopes.set(name, declared);
|
|
504
|
+
guardUpdates(registered, (callback) => wrapTool(tool, permission, reach, load, callback, longRunning), (from, to) => {
|
|
505
|
+
tools.delete(from);
|
|
506
|
+
toolScopes.delete(from);
|
|
507
|
+
if (to !== null) {
|
|
508
|
+
tools.set(to, permission);
|
|
509
|
+
if (declared !== void 0) toolScopes.set(to, declared);
|
|
510
|
+
current = to;
|
|
511
|
+
}
|
|
512
|
+
}, () => current);
|
|
513
|
+
return registered;
|
|
514
|
+
};
|
|
515
|
+
const originalPrompt = server.registerPrompt.bind(server);
|
|
516
|
+
const registerPrompt = (name, config, handler) => {
|
|
517
|
+
const permission = requirePermission("prompt", name, config);
|
|
518
|
+
const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
|
|
519
|
+
const load = data;
|
|
520
|
+
const wrap = (callback) => guard(checks, permission, load, callback, (params) => params.length >= 2 ? [params[0]] : [void 0], throwRefusal, { capabilities });
|
|
521
|
+
const registered = originalPrompt(name, {
|
|
522
|
+
...passthrough,
|
|
523
|
+
scopeChallenge: challengeFor(scopeChallenge, scopesReaching(checks.policy, permission), challengeScope(checks.policy, permission))
|
|
524
|
+
}, wrap(handler));
|
|
525
|
+
prompts.set(name, permission);
|
|
526
|
+
guardUpdates(registered, wrap);
|
|
527
|
+
return registered;
|
|
528
|
+
};
|
|
529
|
+
const originalResource = server.registerResource.bind(server);
|
|
530
|
+
const registerResource = (name, uriOrTemplate, config, read) => {
|
|
531
|
+
const permission = requirePermission("resource", name, config);
|
|
532
|
+
const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
|
|
533
|
+
const load = data;
|
|
534
|
+
const wrap = (callback) => guard(checks, permission, load, callback, (params) => params.slice(0, -1), throwRefusal, { capabilities });
|
|
535
|
+
const registered = originalResource(name, uriOrTemplate, {
|
|
536
|
+
...passthrough,
|
|
537
|
+
scopeChallenge: challengeFor(scopeChallenge, scopesReaching(checks.policy, permission), challengeScope(checks.policy, permission))
|
|
538
|
+
}, wrap(read));
|
|
539
|
+
if (typeof uriOrTemplate === "string") resources.set(uriOrTemplate, permission);
|
|
540
|
+
else templates.push({
|
|
541
|
+
template: uriOrTemplate,
|
|
542
|
+
permission
|
|
520
543
|
});
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
544
|
+
guardUpdates(registered, wrap);
|
|
545
|
+
return registered;
|
|
546
|
+
};
|
|
547
|
+
const guarded = server;
|
|
548
|
+
guarded["registerTool"] = registerTool;
|
|
549
|
+
guarded["registerPrompt"] = registerPrompt;
|
|
550
|
+
guarded["registerResource"] = registerResource;
|
|
551
|
+
return server;
|
|
552
|
+
}
|
|
553
|
+
//#endregion
|
|
554
|
+
//#region src/mcp/subject.ts
|
|
555
|
+
const DEFAULT_MCP_ACTOR_KIND = "mcp-client";
|
|
556
|
+
/** `kind`, or the default when absent; `undefined` for a kind that is not a non-empty string. */
|
|
557
|
+
function mcpActorKind(kind) {
|
|
558
|
+
if (kind === void 0) return DEFAULT_MCP_ACTOR_KIND;
|
|
559
|
+
return typeof kind === "string" && kind !== "" ? kind : void 0;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Maps the `AuthInfo` the MCP SDK's bearer verification produced to a
|
|
563
|
+
* `Subject`: the principal from the verified claims in `extra`, the client
|
|
564
|
+
* as an actor of kind `actorKind` (`mcp-client` by default), the granted
|
|
565
|
+
* scopes as the delegation. Never verifies and never throws; anything
|
|
566
|
+
* unusable, including an `actorKind` that is not a non-empty string, is
|
|
567
|
+
* the anonymous subject.
|
|
568
|
+
*/
|
|
569
|
+
function subjectFromMcp(authInfo, options = {}) {
|
|
570
|
+
try {
|
|
571
|
+
const kind = mcpActorKind(options.actorKind);
|
|
572
|
+
if (authInfo === void 0 || !isRecord(authInfo.extra) || kind === void 0) return anonymousSubject();
|
|
573
|
+
const claims = compact({
|
|
574
|
+
...authInfo.extra,
|
|
575
|
+
authorization_details: authInfo.extra["authorizationDetails"] ?? authInfo.extra["authorization_details"],
|
|
576
|
+
scope: authInfo.scopes?.join(" "),
|
|
577
|
+
client_id: authInfo.clientId,
|
|
578
|
+
exp: authInfo.expiresAt
|
|
579
|
+
});
|
|
580
|
+
const mapped = mapClaimsToSubject(claims, options);
|
|
581
|
+
if (mapped.invalidClaims || mapped.invalidChain || mapped.subject.principal === null) return anonymousSubject();
|
|
582
|
+
const clientId = authInfo.clientId;
|
|
583
|
+
return freezeDeep(compact({
|
|
584
|
+
...mapped.subject,
|
|
585
|
+
actor: typeof clientId === "string" && clientId !== "" ? compact({
|
|
586
|
+
id: clientId,
|
|
587
|
+
kind,
|
|
588
|
+
client: clientNameOf(options.clients, clientId)
|
|
589
|
+
}) : mapped.subject.actor
|
|
590
|
+
}));
|
|
591
|
+
} catch {
|
|
592
|
+
return anonymousSubject();
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
//#endregion
|
|
596
|
+
//#region src/mcp/create.ts
|
|
597
|
+
function createPermDock(policy, given) {
|
|
598
|
+
const options = withApp(policy, given);
|
|
599
|
+
const actorKind = mcpActorKind(options.actorKind);
|
|
600
|
+
if (actorKind === void 0) throw new TypeError("permdock/mcp: actorKind must be a non-empty string");
|
|
601
|
+
const checks = {
|
|
602
|
+
policy,
|
|
603
|
+
options,
|
|
604
|
+
kernel: createAgentKernel(policy, compact({
|
|
605
|
+
subject: (call) => options.subject(call.authInfo ?? {}),
|
|
606
|
+
actor: (call) => {
|
|
607
|
+
if (options.actor !== void 0) return options.actor(call.authInfo ?? {});
|
|
608
|
+
const clientId = call.authInfo?.clientId;
|
|
609
|
+
return typeof clientId === "string" && clientId !== "" ? compact({
|
|
610
|
+
id: clientId,
|
|
611
|
+
kind: actorKind,
|
|
612
|
+
client: clientNameOf(options.clients, clientId)
|
|
613
|
+
}) : void 0;
|
|
614
|
+
},
|
|
615
|
+
delegation: (call) => {
|
|
616
|
+
if (options.delegation !== void 0) return options.delegation(call.authInfo ?? {});
|
|
617
|
+
return call.authInfo === void 0 ? void 0 : delegationFrom(call.authInfo.scopes, call.authInfo.extra);
|
|
618
|
+
},
|
|
619
|
+
tenant: tenantOf(options.tenant),
|
|
620
|
+
store: options.store,
|
|
621
|
+
adapter: "mcp",
|
|
622
|
+
boundary: "mcp-args",
|
|
623
|
+
wrap: composeWraps(options.otel, options.wrap),
|
|
624
|
+
context: options.context === void 0 ? void 0 : (call) => options.context?.(call.authInfo ?? {}),
|
|
625
|
+
...instanceOptions(options)
|
|
626
|
+
}))
|
|
599
627
|
};
|
|
600
|
-
return { protectServer };
|
|
628
|
+
return { protectServer: ((server, enforcement) => protectServer(checks, server, enforcement)) };
|
|
601
629
|
}
|
|
602
630
|
//#endregion
|
|
603
631
|
export { APPROVAL_META_KEY, createPermDock, subjectFromMcp };
|