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
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as RoleTree, i as RoleMeta, n as PlanTree, r as Role, t as Plan } from "./vocabulary-DA8a8zif.js";
|
|
3
|
-
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
1
|
+
import { E as PermissionTree, H as AppDataSchema, N as ResourceNode, T as PermissionKind, U as MetaValue, V as AppData, a as RoleTree, i as RoleMeta, n as PlanTree, r as Role, t as Plan, w as Permission } from "./vocabulary-D6lPdb4Z.js";
|
|
4
2
|
//#region src/conditions/ast.d.ts
|
|
5
3
|
type ConditionRef = {
|
|
6
4
|
readonly ref: string;
|
|
@@ -133,6 +131,54 @@ declare function isCondition(value: unknown): value is Condition;
|
|
|
133
131
|
declare function isSqlFunctionField(value: unknown): value is SqlFunctionField;
|
|
134
132
|
declare function hasConditionOp(condition: Condition | undefined, op: Condition["op"]): boolean;
|
|
135
133
|
//#endregion
|
|
134
|
+
//#region src/conditions/normalize.d.ts
|
|
135
|
+
type FieldOperator = {
|
|
136
|
+
readonly eq?: unknown;
|
|
137
|
+
readonly ne?: unknown;
|
|
138
|
+
readonly gt?: unknown;
|
|
139
|
+
readonly gte?: unknown;
|
|
140
|
+
readonly lt?: unknown;
|
|
141
|
+
readonly lte?: unknown;
|
|
142
|
+
readonly contains?: unknown;
|
|
143
|
+
readonly in?: unknown;
|
|
144
|
+
readonly notIn?: unknown;
|
|
145
|
+
readonly isNull?: boolean;
|
|
146
|
+
};
|
|
147
|
+
type WhereShorthand<T = Record<string, unknown>> = {
|
|
148
|
+
readonly and?: readonly WhereShorthand<T>[];
|
|
149
|
+
readonly or?: readonly WhereShorthand<T>[];
|
|
150
|
+
readonly not?: WhereShorthand<T>;
|
|
151
|
+
} & ("subject" extends keyof T ? { readonly [K in keyof T as Exclude<K, "subject">]?: FieldWhere<T[K]>; } & {
|
|
152
|
+
readonly subject?: SubjectWhere | FieldWhere<T["subject"]>;
|
|
153
|
+
} : { readonly [K in keyof T]?: FieldWhere<T[K]>; } & {
|
|
154
|
+
/** Holds only when the resolver checked the session live (`liveSession: true`). */
|
|
155
|
+
readonly subject?: SubjectWhere;
|
|
156
|
+
});
|
|
157
|
+
type SubjectWhere = {
|
|
158
|
+
readonly session: {
|
|
159
|
+
readonly live: true;
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
type FieldWhere<V> = V | FieldOperator | {
|
|
163
|
+
readonly ref: string;
|
|
164
|
+
};
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/core/open-union.d.ts
|
|
167
|
+
/**
|
|
168
|
+
* A string union that stays open: the listed values autocomplete, and an
|
|
169
|
+
* integrator may pass its own. Only for ids that core compares for equality,
|
|
170
|
+
* where an unknown value can only fail to match. A union whose members core
|
|
171
|
+
* interprets one by one (denial reasons, approval modes, condition operators,
|
|
172
|
+
* credential kinds, delivery channels) stays closed.
|
|
173
|
+
*/
|
|
174
|
+
type OpenUnion<T extends string> = T | (string & NonNullable<unknown>);
|
|
175
|
+
/** `actor.kind`: the values PermDock's adapters set, or an integrator's own; a policy delegation matches it by equality. */
|
|
176
|
+
type ActorKind = OpenUnion<"mcp-client" | "oauth-client" | "support" | "impersonation" | "ai-sdk" | "claude-agent" | "openai-agent" | "eve" | "terminal" | "web-bot-auth" | "a2a-agent" | "automation" | "job" | "caller" | "workload">;
|
|
177
|
+
/** The adapter a decision event names: a PermDock entry, or an integrator's own adapter. */
|
|
178
|
+
type AdapterId = OpenUnion<"server" | "next" | "hono" | "express" | "fastify" | "elysia" | "nest" | "node" | "h3" | "sveltekit" | "astro" | "solid-start" | "tanstack-start" | "trpc" | "orpc" | "supabase-middleware" | "convex" | "authzen" | "mcp" | "a2a" | "agent" | "ai-sdk" | "claude-agent" | "openai" | "eve" | "terminal" | "webmcp" | "workflow" | "chat" | "delivery">;
|
|
179
|
+
/** How a membership was obtained (`membership.via`); `viaOnly` and support rules match it by equality. */
|
|
180
|
+
type MembershipVia = OpenUnion<"direct" | "contact" | "credential" | "elevated" | "feed" | "link" | "share" | "support" | "support-session" | "scim">;
|
|
181
|
+
//#endregion
|
|
136
182
|
//#region src/core/subject.d.ts
|
|
137
183
|
type JsonWebKeyLike = {
|
|
138
184
|
readonly kty?: string;
|
|
@@ -177,13 +223,13 @@ type Membership = {
|
|
|
177
223
|
readonly roles: readonly string[];
|
|
178
224
|
/** Roles the holder may activate here but does not hold; `permdock.activate` writes an elevated membership. */
|
|
179
225
|
readonly eligible?: readonly string[];
|
|
180
|
-
readonly via?:
|
|
226
|
+
readonly via?: MembershipVia;
|
|
181
227
|
readonly expiresAt?: number;
|
|
182
228
|
/** The principal id that wrote this membership: who elevated, consented to or granted the access. */
|
|
183
229
|
readonly grantedBy?: string;
|
|
184
230
|
/** Free text recording why the membership was written: the activation or consent justification. */
|
|
185
231
|
readonly reason?: string;
|
|
186
|
-
/** A subgroup the holder belongs to inside the instance (`vendor-support`); a `
|
|
232
|
+
/** A subgroup the holder belongs to inside the instance (`vendor-support`); a `junctionMembershipSource` group column fills it. */
|
|
187
233
|
readonly member?: {
|
|
188
234
|
readonly group: string;
|
|
189
235
|
};
|
|
@@ -197,6 +243,13 @@ type Membership = {
|
|
|
197
243
|
* Every other grant, allow or deny, ignores it, and so do role listings.
|
|
198
244
|
*/
|
|
199
245
|
readonly keep?: readonly string[];
|
|
246
|
+
/**
|
|
247
|
+
* Data the application owns about this membership (a department, a seat
|
|
248
|
+
* label). Plain JSON from a trusted membership source, checked by
|
|
249
|
+
* `definePolicy(…, { x: { membership } })`. Never read in evaluation,
|
|
250
|
+
* conditions or RLS, and never written into token claims.
|
|
251
|
+
*/
|
|
252
|
+
readonly x?: AppData;
|
|
200
253
|
/** Input only: an instance of the first scope. */
|
|
201
254
|
readonly tenant?: string;
|
|
202
255
|
/** Input only: an instance of the second scope, inside `tenant`. */
|
|
@@ -216,7 +269,12 @@ type CustomRoleBody = {
|
|
|
216
269
|
readonly name: string;
|
|
217
270
|
readonly includes?: readonly string[];
|
|
218
271
|
readonly grants?: readonly CustomRoleGrant[];
|
|
219
|
-
|
|
272
|
+
/**
|
|
273
|
+
* Display text and app data, carried onto the role leaf
|
|
274
|
+
* `assignableRoles()` returns. `x` is checked by the role tree's
|
|
275
|
+
* `defineRoles(…, { x })` schema; an invalid `x` is dropped, not the role.
|
|
276
|
+
*/
|
|
277
|
+
readonly meta?: RoleMeta;
|
|
220
278
|
};
|
|
221
279
|
/** A role a tenant defines, held on memberships inside that tenant. */
|
|
222
280
|
type TenantCustomRole = CustomRoleBody & {
|
|
@@ -244,7 +302,13 @@ type CustomRole = TenantCustomRole | GlobalCustomRole;
|
|
|
244
302
|
type Principal = {
|
|
245
303
|
readonly id: string;
|
|
246
304
|
readonly issuer?: string;
|
|
247
|
-
|
|
305
|
+
/**
|
|
306
|
+
* `contact`: an external person (a customer contact, a portal user). Only
|
|
307
|
+
* its `{ on }` memberships count; it never approves, creates keys or
|
|
308
|
+
* publishes, and is read-only unless a role whose `for` lists `contact`
|
|
309
|
+
* grants the write.
|
|
310
|
+
*/
|
|
311
|
+
readonly kind?: "user" | "service" | "workload" | "link" | "feed" | "contact";
|
|
248
312
|
readonly roles?: readonly string[];
|
|
249
313
|
readonly plans?: readonly string[];
|
|
250
314
|
readonly memberships?: readonly Membership[];
|
|
@@ -259,9 +323,9 @@ type Principal = {
|
|
|
259
323
|
};
|
|
260
324
|
type Actor = {
|
|
261
325
|
readonly id: string;
|
|
262
|
-
readonly kind:
|
|
326
|
+
readonly kind: ActorKind;
|
|
263
327
|
readonly binding?: Binding;
|
|
264
|
-
/** `true`
|
|
328
|
+
/** `true` denies every permission without `readOnlyHint` (`not-delegated`), with or without a policy delegation. */
|
|
265
329
|
readonly readOnly?: boolean;
|
|
266
330
|
/** The stable name the application gives this OAuth client (`ClientNames`), set by the subject resolver from the verified client id; policy delegations match it with `to: { kind, client }`. */
|
|
267
331
|
readonly client?: string;
|
|
@@ -296,98 +360,26 @@ type Subject<TPrincipal extends Principal = Principal> = {
|
|
|
296
360
|
readonly liveSession?: true;
|
|
297
361
|
};
|
|
298
362
|
//#endregion
|
|
299
|
-
//#region src/core/
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
readonly
|
|
363
|
+
//#region src/core/decision.d.ts
|
|
364
|
+
type DenialReason = "no-grant" | "condition" | "deny" | "inactive-grant" | "closure-error" | "opaque-condition" | "server-only" | "anonymous" | "not-delegated" | "no-delegation" | "agent-tool-not-delegated" | "insufficient-user-authentication" | "not-entitled" | "purpose" | "reason-required" | "actor-required" | "limit" | "limit-unavailable" | "relation-depth" | "relation-unavailable" | "validation" | "tenant-mismatch" | "no-membership" | "scope" | "expired-membership" | "stale-credentials" | "unknown-role" | "last-holder" | "max-holders" | "transfer-only" | "not-assignable-by" | "self-demotion" | "externally-managed" | "not-allowed-for-membership" | "conflicting-role" | "approval" | "stale-approval" | "pdp-denied" | "pdp-unavailable" | "pdp-invalid-response" | "undocumented" | "unsupported" | "exceeds-creator" | "credential-policy";
|
|
365
|
+
/** The `detail` each denial reason carries, where PermDock sets a structured one. */
|
|
366
|
+
type DenialDetails = {
|
|
367
|
+
readonly limit: LimitDetail;
|
|
368
|
+
/** The window the inactive allow applies in. */
|
|
369
|
+
readonly "inactive-grant": WireValidity;
|
|
370
|
+
/** The matching deny's declared `name`. */
|
|
371
|
+
readonly deny: {
|
|
372
|
+
readonly name?: string;
|
|
373
|
+
};
|
|
304
374
|
};
|
|
305
|
-
type PolicyScopesInput = Readonly<Record<string, ScopeDeclaration>>;
|
|
306
375
|
/**
|
|
307
|
-
*
|
|
308
|
-
*
|
|
376
|
+
* Why a candidate grant did not apply. `Denial<"limit">` types `detail` for a
|
|
377
|
+
* reason in `DenialDetails`; any other reason's detail is `unknown`.
|
|
309
378
|
*/
|
|
310
|
-
type
|
|
311
|
-
readonly name: string;
|
|
312
|
-
readonly key?: string;
|
|
313
|
-
readonly within?: string;
|
|
314
|
-
};
|
|
315
|
-
/** The names `role(..., { on })`, `memberOf` and memberships may use: declared names plus the aliases. */
|
|
316
|
-
type ScopeNames<S> = [S] extends [PolicyScopesInput] ? string extends keyof S ? string : (keyof S & string) | "tenant" | "team" : string;
|
|
317
|
-
//#endregion
|
|
318
|
-
//#region src/core/grantee.d.ts
|
|
319
|
-
type RoleGrantee = {
|
|
320
|
-
readonly kind: "role";
|
|
321
|
-
readonly role: string;
|
|
322
|
-
/** `'global'`, a scope name, or one resource. */
|
|
323
|
-
readonly scope: string | {
|
|
324
|
-
readonly resource: string;
|
|
325
|
-
};
|
|
326
|
-
};
|
|
327
|
-
type AnyoneGrantee = {
|
|
328
|
-
readonly kind: "anyone";
|
|
329
|
-
};
|
|
330
|
-
type AuthenticatedGrantee = {
|
|
331
|
-
readonly kind: "authenticated";
|
|
332
|
-
};
|
|
333
|
-
type RelationGrantee = {
|
|
334
|
-
readonly kind: "relation";
|
|
335
|
-
readonly resource: string;
|
|
336
|
-
readonly relation: string;
|
|
337
|
-
/**
|
|
338
|
-
* `'parent'`: follow the row's `parent` chain upward to `resource`, then its
|
|
339
|
-
* own parents. A list of link names: follow those to-one links from the row
|
|
340
|
-
* to `resource`, then walk its parents only when `depth` is set.
|
|
341
|
-
*/
|
|
342
|
-
readonly through?: "parent" | readonly string[];
|
|
343
|
-
/** Parent hops walked above the first `resource` instance; absent means `DEFAULT_RELATION_DEPTH` for `'parent'` and `0` for links. */
|
|
344
|
-
readonly depth?: number;
|
|
345
|
-
};
|
|
346
|
-
type PlanGrantee = {
|
|
347
|
-
readonly kind: "plan";
|
|
348
|
-
readonly plan: string;
|
|
349
|
-
};
|
|
350
|
-
type ActorGrantee = {
|
|
351
|
-
readonly kind: "actor";
|
|
352
|
-
readonly actor: string;
|
|
353
|
-
};
|
|
354
|
-
type AssuranceGrantee = {
|
|
355
|
-
readonly kind: "assurance";
|
|
356
|
-
readonly acr?: readonly string[];
|
|
357
|
-
readonly amr?: readonly string[];
|
|
358
|
-
readonly maxAge?: number;
|
|
359
|
-
};
|
|
360
|
-
type InheritGrantee = {
|
|
361
|
-
readonly kind: "inherit";
|
|
362
|
-
readonly permission: string;
|
|
363
|
-
readonly resource: string;
|
|
364
|
-
readonly through: "parent" | readonly string[];
|
|
365
|
-
};
|
|
366
|
-
type Grantee = RoleGrantee | InheritGrantee | AnyoneGrantee | AuthenticatedGrantee | RelationGrantee | PlanGrantee | ActorGrantee | AssuranceGrantee;
|
|
367
|
-
type GranteeInput = Grantee | Role | Plan | string | readonly GranteeInput[];
|
|
368
|
-
declare function anyone(): AnyoneGrantee;
|
|
369
|
-
declare function authenticated(): AuthenticatedGrantee;
|
|
370
|
-
declare function relation(resource: Permission | PermissionTree, name: string, options?: {
|
|
371
|
-
readonly through?: "parent" | readonly string[];
|
|
372
|
-
readonly depth?: number;
|
|
373
|
-
}): RelationGrantee;
|
|
374
|
-
declare function inherit(permission: Permission, options: {
|
|
375
|
-
readonly through: "parent" | readonly string[];
|
|
376
|
-
}): InheritGrantee;
|
|
377
|
-
declare function plan(name: Plan | string): PlanGrantee;
|
|
378
|
-
declare function actor(kind: string): ActorGrantee;
|
|
379
|
-
declare function assurance(options: {
|
|
380
|
-
readonly acr?: string | readonly string[];
|
|
381
|
-
readonly amr?: string | readonly string[];
|
|
382
|
-
readonly maxAge?: number;
|
|
383
|
-
}): AssuranceGrantee;
|
|
384
|
-
//#endregion
|
|
385
|
-
//#region src/core/decision.d.ts
|
|
386
|
-
type DenialReason = "no-grant" | "condition" | "deny" | "inactive-grant" | "closure-error" | "opaque-condition" | "server-only" | "anonymous" | "not-delegated" | "no-delegation" | "insufficient-user-authentication" | "not-entitled" | "purpose" | "reason-required" | "actor-required" | "limit" | "limit-unavailable" | "relation-depth" | "relation-unavailable" | "validation" | "tenant-mismatch" | "no-membership" | "scope" | "expired-membership" | "stale-credentials" | "unknown-role" | "last-holder" | "max-holders" | "transfer-only" | "not-assignable-by" | "self-demotion" | "externally-managed" | "not-allowed-for-membership" | "conflicting-role" | "approval" | "stale-approval" | "pdp-denied" | "pdp-unavailable" | "pdp-invalid-response" | "undocumented" | "unsupported" | "exceeds-creator" | "credential-policy";
|
|
387
|
-
type Denial = {
|
|
379
|
+
type Denial<R extends DenialReason = DenialReason> = {
|
|
388
380
|
readonly role: string | null;
|
|
389
|
-
readonly reason:
|
|
390
|
-
readonly detail?: unknown;
|
|
381
|
+
readonly reason: R;
|
|
382
|
+
readonly detail?: [R] extends [keyof DenialDetails] ? DenialDetails[R] : unknown;
|
|
391
383
|
readonly to?: Grantee | readonly Grantee[];
|
|
392
384
|
};
|
|
393
385
|
type MatchedGrant = {
|
|
@@ -395,6 +387,8 @@ type MatchedGrant = {
|
|
|
395
387
|
readonly permission: string;
|
|
396
388
|
/** The grant's declared `name`, when it has one. */
|
|
397
389
|
readonly name?: string;
|
|
390
|
+
/** The grant's declared `meta`, when it has one; PermDock never reads it. */
|
|
391
|
+
readonly meta?: GrantMeta;
|
|
398
392
|
readonly to?: Grantee | readonly Grantee[];
|
|
399
393
|
readonly where?: Grant["where"];
|
|
400
394
|
readonly check?: Grant["check"];
|
|
@@ -410,26 +404,35 @@ type MatchedGrant = {
|
|
|
410
404
|
* `limit` was past its count; `near-limit`: usage reached `alertAt`.
|
|
411
405
|
* `notify` / `review`: a break-glass grant's declared follow-ups.
|
|
412
406
|
* `justify`: the break-glass reason, carried so audit records why.
|
|
407
|
+
* `app`: a follow-up the application declared on the grant
|
|
408
|
+
* (`allow(p, { obligations })`); PermDock carries it and never acts on it.
|
|
413
409
|
*/
|
|
414
410
|
type Obligation = {
|
|
415
411
|
readonly kind: "over-limit" | "near-limit" | "notify" | "review";
|
|
416
412
|
} | {
|
|
417
413
|
readonly kind: "justify";
|
|
418
414
|
readonly reason: string;
|
|
415
|
+
} | AppObligation;
|
|
416
|
+
/** An obligation the application declares on an allow and handles itself. */
|
|
417
|
+
type AppObligation = {
|
|
418
|
+
readonly kind: "app";
|
|
419
|
+
/** Lower case letters, digits, `_` and `-`, starting with a letter. */
|
|
420
|
+
readonly name: string;
|
|
421
|
+
readonly detail?: MetaValue;
|
|
419
422
|
};
|
|
420
|
-
/** What is left of the `limit` that applied; `resetsAt` is
|
|
423
|
+
/** What is left of the `limit` that applied; `resetsAt` is RFC 3339. */
|
|
421
424
|
type Quota = {
|
|
422
425
|
readonly remaining: number;
|
|
423
|
-
readonly resetsAt:
|
|
426
|
+
readonly resetsAt: string;
|
|
424
427
|
};
|
|
425
428
|
/**
|
|
426
|
-
* The `detail` of a `limit` denial: the grant's `count`, its window
|
|
427
|
-
* seconds and when the window resets (
|
|
429
|
+
* The `detail` of a `limit` denial: the grant's `count`, its `per` window
|
|
430
|
+
* in seconds and when the window resets (RFC 3339).
|
|
428
431
|
*/
|
|
429
432
|
type LimitDetail = {
|
|
430
433
|
readonly count: number;
|
|
431
|
-
readonly
|
|
432
|
-
readonly resetsAt:
|
|
434
|
+
readonly per: number;
|
|
435
|
+
readonly resetsAt: string;
|
|
433
436
|
};
|
|
434
437
|
/**
|
|
435
438
|
* Why a candidate grant for the permission was passed over before its
|
|
@@ -479,6 +482,11 @@ type GrantedDecision = {
|
|
|
479
482
|
};
|
|
480
483
|
type DeniedDecision = {
|
|
481
484
|
readonly outcome: "denied";
|
|
485
|
+
/**
|
|
486
|
+
* The key of the permission that was checked. Absent on a denial for a
|
|
487
|
+
* check that named no declared permission.
|
|
488
|
+
*/
|
|
489
|
+
readonly permission?: string;
|
|
482
490
|
readonly denials: readonly Denial[];
|
|
483
491
|
readonly alternatives: readonly Permission[];
|
|
484
492
|
/** Present only with `explain: true`. */
|
|
@@ -498,527 +506,619 @@ type ExplainedDecision = Decision & {
|
|
|
498
506
|
};
|
|
499
507
|
type Decision = GrantedDecision | DeniedDecision | ApprovalRequiredDecision;
|
|
500
508
|
//#endregion
|
|
501
|
-
//#region src/core/
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
*/
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
readonly
|
|
515
|
-
|
|
516
|
-
|
|
509
|
+
//#region src/core/grantee.d.ts
|
|
510
|
+
type RoleGrantee = {
|
|
511
|
+
readonly kind: "role";
|
|
512
|
+
readonly role: string;
|
|
513
|
+
/** `'global'`, a scope name, or one resource. */
|
|
514
|
+
readonly scope: string | {
|
|
515
|
+
readonly resource: string;
|
|
516
|
+
};
|
|
517
|
+
};
|
|
518
|
+
type AnyoneGrantee = {
|
|
519
|
+
readonly kind: "anyone";
|
|
520
|
+
};
|
|
521
|
+
type AuthenticatedGrantee = {
|
|
522
|
+
readonly kind: "authenticated";
|
|
523
|
+
};
|
|
524
|
+
type RelationGrantee = {
|
|
525
|
+
readonly kind: "relation";
|
|
526
|
+
readonly resource: string;
|
|
527
|
+
readonly relation: string;
|
|
517
528
|
/**
|
|
518
|
-
*
|
|
519
|
-
*
|
|
529
|
+
* `'parent'`: follow the row's `parent` chain upward to `resource`, then its
|
|
530
|
+
* own parents. A list of link names: follow those to-one links from the row
|
|
531
|
+
* to `resource`, then walk its parents only when `depth` is set.
|
|
520
532
|
*/
|
|
521
|
-
readonly
|
|
533
|
+
readonly through?: "parent" | readonly string[];
|
|
534
|
+
/** Parent hops walked above the first `resource` instance; absent means `DEFAULT_RELATION_DEPTH` for `'parent'` and `0` for links. */
|
|
535
|
+
readonly depth?: number;
|
|
522
536
|
};
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
* tenant always apply). A throw, a rejected promise or an invalid entry
|
|
527
|
-
* denies every call an allow would otherwise permit.
|
|
528
|
-
*/
|
|
529
|
-
type ApprovalPolicySource = {
|
|
530
|
-
approvalPoliciesFor(query: {
|
|
531
|
-
readonly tenants: readonly string[];
|
|
532
|
-
}): readonly ApprovalPolicy[] | Promise<readonly ApprovalPolicy[]>;
|
|
533
|
-
};
|
|
534
|
-
/** The denial detail when an `ApprovalPolicySource` fails: every call an allow would grant denies with reason `approval`. */
|
|
535
|
-
declare const APPROVAL_POLICY_UNAVAILABLE = "approval-policy-unavailable";
|
|
536
|
-
declare function memoryApprovalPolicies(policies: readonly ApprovalPolicy[]): ApprovalPolicySource;
|
|
537
|
-
/**
|
|
538
|
-
* Why an `ApprovalPolicy` entry does not load. `unknown-permission`: the
|
|
539
|
-
* policy declares no such key (the entry applies to nothing). `invalid`: a
|
|
540
|
-
* field has the wrong shape or the approval option does not normalise.
|
|
541
|
-
* `where-on-collection`: `where` reads a row, which a collection action
|
|
542
|
-
* never has, so the entry could never match; use `check` over the input.
|
|
543
|
-
* `stale-on-without-version`: `staleOn` needs an instance permission whose
|
|
544
|
-
* resource declares `version`.
|
|
545
|
-
*/
|
|
546
|
-
type ApprovalPolicyProblem = "unknown-permission" | "invalid" | "where-on-collection" | "stale-on-without-version";
|
|
547
|
-
type ApprovalPolicyValidation = {
|
|
548
|
-
readonly ok: true;
|
|
549
|
-
} | {
|
|
550
|
-
readonly ok: false;
|
|
551
|
-
readonly problem: ApprovalPolicyProblem;
|
|
537
|
+
type PlanGrantee = {
|
|
538
|
+
readonly kind: "plan";
|
|
539
|
+
readonly plan: string;
|
|
552
540
|
};
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
readonly
|
|
565
|
-
readonly
|
|
566
|
-
readonly
|
|
567
|
-
|
|
568
|
-
type ArazzoStepResult = {
|
|
569
|
-
readonly stepId: string;
|
|
570
|
-
/** The nested workflow that owns the step, when it is not the plan's workflow. */
|
|
571
|
-
readonly workflowId?: string;
|
|
572
|
-
readonly operationId?: string;
|
|
573
|
-
readonly permissions: readonly Permission[];
|
|
574
|
-
readonly decision: Decision;
|
|
575
|
-
readonly provisional?: true;
|
|
576
|
-
};
|
|
577
|
-
type ArazzoPlan = {
|
|
578
|
-
readonly workflowId: string;
|
|
579
|
-
readonly outcome: Decision["outcome"];
|
|
580
|
-
readonly steps: readonly ArazzoStepResult[];
|
|
581
|
-
};
|
|
582
|
-
type ArazzoFinding = {
|
|
583
|
-
readonly stepId: string;
|
|
584
|
-
readonly workflowId: string;
|
|
585
|
-
readonly reason: "undocumented" | "unsupported" | "validation" | "unknown-key";
|
|
586
|
-
readonly detail: string;
|
|
587
|
-
};
|
|
588
|
-
declare function arazzoFindings(input: ArazzoSimulateInput, tree: PermissionTree | undefined): readonly ArazzoFinding[];
|
|
589
|
-
declare function simulateArazzo(input: ArazzoSimulateInput, tree: PermissionTree | undefined, decide: (permission: Permission, data: unknown) => Decision): ArazzoPlan;
|
|
590
|
-
//#endregion
|
|
591
|
-
//#region src/core/elevated.d.ts
|
|
592
|
-
/**
|
|
593
|
-
* The only deny override: a break-glass grant overrides deny grants whose
|
|
594
|
-
* `name` it lists, and nothing else. It is an allow that stays non-portable
|
|
595
|
-
* (RLS never compiles it) and grants only once its `requires` are met.
|
|
596
|
-
*/
|
|
597
|
-
declare function breakGlass<T>(permission: Permission<string, T> | readonly Permission<string, T>[], options?: BreakGlassOptions): Omit<Grant, "role" | "scope"> | Omit<Grant, "role" | "scope">[];
|
|
598
|
-
/**
|
|
599
|
-
* Support access with tenant consent: a role a vendor holds only through a
|
|
600
|
-
* consented, time-bound `via: 'support'` membership. `actorRequired` denies
|
|
601
|
-
* every decision under it without an `act`; `forbid` compiles to deny grants
|
|
602
|
-
* scoped to `via: 'support'`.
|
|
603
|
-
*/
|
|
604
|
-
declare function supportAccess<const S extends string>(options: SupportAccessOptions<S> & {
|
|
605
|
-
readonly on: S;
|
|
606
|
-
}): RoleBinding<S>;
|
|
607
|
-
/** Support access held in the `tenant` scope. */
|
|
608
|
-
declare function supportAccess(options: SupportAccessOptions<never>): RoleBinding<"tenant">;
|
|
609
|
-
type ActivateInput = {
|
|
610
|
-
readonly role: string | Role;
|
|
611
|
-
/** The scope the activation applies in (a declared name or the `tenant` / `team` alias). */
|
|
612
|
-
readonly scope: string;
|
|
613
|
-
readonly id: string;
|
|
614
|
-
/** Ancestor scope ids, keyed by scope name, for a nested-scope activation. */
|
|
615
|
-
readonly within?: Readonly<Record<string, string>>;
|
|
616
|
-
/** How long the elevation lasts; capped at the role's `maxDuration`. */
|
|
617
|
-
readonly duration?: string;
|
|
618
|
-
readonly reason?: string;
|
|
541
|
+
type ActorGrantee = {
|
|
542
|
+
readonly kind: "actor";
|
|
543
|
+
readonly actor: string;
|
|
544
|
+
};
|
|
545
|
+
type AssuranceGrantee = {
|
|
546
|
+
readonly kind: "assurance";
|
|
547
|
+
readonly acr?: readonly string[];
|
|
548
|
+
readonly amr?: readonly string[];
|
|
549
|
+
readonly maxAge?: number;
|
|
550
|
+
};
|
|
551
|
+
type InheritGrantee = {
|
|
552
|
+
readonly kind: "inherit";
|
|
553
|
+
readonly permission: string;
|
|
554
|
+
readonly resource: string;
|
|
555
|
+
readonly through: "parent" | readonly string[];
|
|
619
556
|
};
|
|
557
|
+
type Grantee = RoleGrantee | InheritGrantee | AnyoneGrantee | AuthenticatedGrantee | RelationGrantee | PlanGrantee | ActorGrantee | AssuranceGrantee;
|
|
558
|
+
type GranteeInput = Grantee | Role | Plan | string | readonly GranteeInput[];
|
|
559
|
+
declare function anyone(): AnyoneGrantee;
|
|
560
|
+
declare function authenticated(): AuthenticatedGrantee;
|
|
561
|
+
declare function relation(resource: Permission | PermissionTree, name: string, options?: {
|
|
562
|
+
readonly through?: "parent" | readonly string[];
|
|
563
|
+
readonly depth?: number;
|
|
564
|
+
}): RelationGrantee;
|
|
565
|
+
declare function inherit(permission: Permission, options: {
|
|
566
|
+
readonly through: "parent" | readonly string[];
|
|
567
|
+
}): InheritGrantee;
|
|
568
|
+
declare function plan(name: Plan | string): PlanGrantee;
|
|
569
|
+
declare function actor(kind: string): ActorGrantee;
|
|
570
|
+
declare function assurance(options: {
|
|
571
|
+
readonly acr?: string | readonly string[];
|
|
572
|
+
readonly amr?: string | readonly string[];
|
|
573
|
+
readonly maxAge?: number;
|
|
574
|
+
}): AssuranceGrantee;
|
|
620
575
|
//#endregion
|
|
621
|
-
//#region src/core/
|
|
622
|
-
/**
|
|
623
|
-
type
|
|
576
|
+
//#region src/core/approvers.d.ts
|
|
577
|
+
/** One named approver, by principal id. */
|
|
578
|
+
type UserApprover = {
|
|
579
|
+
readonly kind: "user";
|
|
624
580
|
readonly id: string;
|
|
625
|
-
/** The kind of the target's membership in the instance (`staff`, `contact`, ...). */
|
|
626
|
-
readonly via?: string;
|
|
627
|
-
/** The roles the target holds in the instance now. */
|
|
628
|
-
readonly roles?: readonly string[];
|
|
629
|
-
/** `idp` when the identity provider owns the target's membership: the application cannot change it. */
|
|
630
|
-
readonly managedBy?: "idp";
|
|
631
|
-
};
|
|
632
|
-
type RoleChangeBase = {
|
|
633
|
-
readonly kind: "assign" | "revoke" | "transfer";
|
|
634
|
-
readonly role: string | Role;
|
|
635
|
-
/** Ids of the instance's ancestor scopes; a holder there may assign here. */
|
|
636
|
-
readonly within?: Readonly<Record<string, string>>;
|
|
637
|
-
readonly target: RoleChangeTarget;
|
|
638
|
-
/**
|
|
639
|
-
* How many principals hold `role` in the instance now, from the
|
|
640
|
-
* application's store. Without it a role with `min`, `max` or
|
|
641
|
-
* `transferOnly` is denied.
|
|
642
|
-
*/
|
|
643
|
-
readonly holders?: number;
|
|
644
581
|
};
|
|
645
582
|
/**
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
*
|
|
583
|
+
* Whoever holds `permission` in the request's tenant, through any role,
|
|
584
|
+
* custom roles included. Checked only through verdict facts
|
|
585
|
+
* (`ApprovalVerdict.permissions`) that the handler computes from the
|
|
586
|
+
* approver's own instance.
|
|
649
587
|
*/
|
|
650
|
-
type
|
|
651
|
-
|
|
652
|
-
readonly
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
readonly
|
|
657
|
-
readonly
|
|
658
|
-
}
|
|
588
|
+
type PermissionApprover = {
|
|
589
|
+
readonly kind: "permission";
|
|
590
|
+
readonly permission: string;
|
|
591
|
+
};
|
|
592
|
+
/** An approver who matches at least one item; an item that is a list matches when every entry does. */
|
|
593
|
+
type AnyOfApprover = {
|
|
594
|
+
readonly kind: "any-of";
|
|
595
|
+
readonly of: readonly (Approver | readonly Approver[])[];
|
|
596
|
+
};
|
|
659
597
|
/**
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
*
|
|
598
|
+
* Who may approve: a subject-only grantee, a `relation()` the approver holds
|
|
599
|
+
* on the requested row (checked when the verdict is given), `user(id)`,
|
|
600
|
+
* `holder(permission)`, or `anyOf(...)`. A list (or `allOf(...)`) matches an
|
|
601
|
+
* approver who satisfies every item.
|
|
663
602
|
*/
|
|
664
|
-
type
|
|
665
|
-
|
|
666
|
-
readonly
|
|
667
|
-
readonly
|
|
668
|
-
} |
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
603
|
+
type Approver = Grantee | UserApprover | PermissionApprover | AnyOfApprover;
|
|
604
|
+
type ApproverInput = GranteeInput | UserApprover | PermissionApprover | {
|
|
605
|
+
readonly kind: "any-of";
|
|
606
|
+
readonly of: readonly ApproverInput[];
|
|
607
|
+
} | readonly ApproverInput[];
|
|
608
|
+
/** Approves when the approver holds `permission` in the request's tenant (any role, custom roles included). */
|
|
609
|
+
declare function holder(permission: Permission): PermissionApprover;
|
|
610
|
+
/** Approves when the approver matches any one of `items`. */
|
|
611
|
+
declare function anyOf(...items: readonly ApproverInput[]): {
|
|
612
|
+
readonly kind: "any-of";
|
|
613
|
+
readonly of: readonly ApproverInput[];
|
|
672
614
|
};
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
615
|
+
/** Approves when the approver matches every one of `items`; the same as a list. */
|
|
616
|
+
declare function allOf(...items: readonly ApproverInput[]): readonly ApproverInput[];
|
|
617
|
+
/** A named approver for `approval.by`, matched on the approver's principal id. */
|
|
618
|
+
declare function user(id: string): UserApprover;
|
|
619
|
+
//#endregion
|
|
620
|
+
//#region src/core/scopes.d.ts
|
|
621
|
+
/** One entry of `definePolicy({ scopes })`: the row field holding the scope id, and its parent scope. */
|
|
622
|
+
type ScopeDeclaration = {
|
|
623
|
+
readonly key: string;
|
|
624
|
+
readonly within?: string;
|
|
625
|
+
};
|
|
626
|
+
type PolicyScopesInput = Readonly<Record<string, ScopeDeclaration>>;
|
|
627
|
+
/**
|
|
628
|
+
* A declared scope, in declaration order. `key` is absent only on the
|
|
629
|
+
* implicit `tenant` / `team` pair of a policy that declares no scopes.
|
|
630
|
+
*/
|
|
631
|
+
type Scope = {
|
|
632
|
+
readonly name: string;
|
|
633
|
+
readonly key?: string;
|
|
634
|
+
readonly within?: string;
|
|
681
635
|
};
|
|
636
|
+
/** The names `role(..., { on })`, `memberOf` and memberships may use: declared names plus the aliases. */
|
|
637
|
+
type ScopeNames<S> = [S] extends [PolicyScopesInput] ? string extends keyof S ? string : (keyof S & string) | "tenant" | "team" : string;
|
|
682
638
|
//#endregion
|
|
683
|
-
//#region src/core/
|
|
684
|
-
|
|
639
|
+
//#region src/core/wire-delegation.d.ts
|
|
640
|
+
/**
|
|
641
|
+
* A delegation as every PermDock wire form carries it: OAuth `scope`
|
|
642
|
+
* (RFC 6749, space-separated) and RFC 9396 `authorization_details`. An empty
|
|
643
|
+
* `scope` is an empty scope list, which delegates nothing.
|
|
644
|
+
*/
|
|
645
|
+
type WireDelegation = {
|
|
646
|
+
readonly scope?: string;
|
|
647
|
+
readonly authorization_details?: readonly AuthorizationDetail[];
|
|
648
|
+
readonly access?: readonly GnapAccess[];
|
|
649
|
+
};
|
|
685
650
|
//#endregion
|
|
686
|
-
//#region src/core/
|
|
687
|
-
/**
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
readonly
|
|
695
|
-
readonly
|
|
696
|
-
|
|
697
|
-
readonly
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
readonly
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
651
|
+
//#region src/core/wire-denial.d.ts
|
|
652
|
+
/**
|
|
653
|
+
* A denial as it leaves the process: in a decision event, a Problem Details
|
|
654
|
+
* body, an MCP or WebMCP refusal and the decision endpoint. `detail` is a
|
|
655
|
+
* JSON value (a string, or `LimitDetail` on `limit`); what a closure threw
|
|
656
|
+
* and a validation error stay in process.
|
|
657
|
+
*/
|
|
658
|
+
type WireDenial = {
|
|
659
|
+
readonly role: string | null;
|
|
660
|
+
readonly reason: DenialReason;
|
|
661
|
+
readonly to?: Grantee | readonly Grantee[];
|
|
662
|
+
readonly detail?: unknown;
|
|
663
|
+
};
|
|
664
|
+
/** A `Decision` whose denials are `WireDenial`s, as the decision endpoint sends it. */
|
|
665
|
+
type WireDecision = GrantedDecision | ApprovalRequiredDecision | (Omit<DeniedDecision, "denials"> & {
|
|
666
|
+
readonly denials: readonly WireDenial[];
|
|
667
|
+
});
|
|
668
|
+
//#endregion
|
|
669
|
+
//#region src/core/event-types.d.ts
|
|
670
|
+
type DirectoryEvent = {
|
|
671
|
+
readonly type: "directory";
|
|
672
|
+
readonly at: string;
|
|
673
|
+
/** `scim`, or an integrator's own directory sync. */
|
|
674
|
+
readonly source: OpenUnion<"scim">;
|
|
675
|
+
readonly operation: "create" | "replace" | "patch" | "delete";
|
|
676
|
+
readonly tenant: string;
|
|
677
|
+
readonly resource: {
|
|
678
|
+
readonly type: "User" | "Group";
|
|
679
|
+
readonly id: string;
|
|
680
|
+
};
|
|
681
|
+
readonly credential: {
|
|
682
|
+
readonly kind: "token";
|
|
683
|
+
} | {
|
|
684
|
+
readonly kind: "jwt";
|
|
685
|
+
readonly iss?: string;
|
|
686
|
+
};
|
|
687
|
+
readonly active?: boolean;
|
|
688
|
+
/** The application's own data, set where the event is built; plain JSON, never read by a decision. */
|
|
689
|
+
readonly x?: AppData;
|
|
706
690
|
};
|
|
707
|
-
type
|
|
691
|
+
type MembershipEvent = {
|
|
692
|
+
readonly type: "membership";
|
|
693
|
+
readonly at: string;
|
|
694
|
+
readonly source: string;
|
|
695
|
+
readonly operation: "added" | "removed" | "changed";
|
|
708
696
|
readonly principal: {
|
|
709
697
|
readonly id: string;
|
|
710
698
|
};
|
|
711
|
-
|
|
699
|
+
/** A declared scope name, or the `tenant` / `team` alias; absent for a global role change. */
|
|
700
|
+
readonly scope?: string;
|
|
701
|
+
/** The scope instance; present exactly when `scope` is. */
|
|
702
|
+
readonly id?: string;
|
|
703
|
+
/** The id of every ancestor scope, keyed by scope name. */
|
|
704
|
+
readonly within?: Readonly<Record<string, string>>;
|
|
705
|
+
readonly via?: MembershipVia;
|
|
706
|
+
/** When the membership lapses, an RFC 3339 instant. */
|
|
707
|
+
readonly expiresAt?: string;
|
|
708
|
+
readonly roles: {
|
|
709
|
+
readonly added: readonly string[];
|
|
710
|
+
readonly removed: readonly string[];
|
|
711
|
+
};
|
|
712
|
+
readonly by?: {
|
|
713
|
+
readonly id: string;
|
|
714
|
+
readonly kind: string;
|
|
715
|
+
};
|
|
716
|
+
/** The application's own data, set where the event is built; plain JSON, never read by a decision. */
|
|
717
|
+
readonly x?: AppData;
|
|
712
718
|
};
|
|
713
719
|
/**
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
* an unavailable relation): holders may be missing, so check with `decide`.
|
|
720
|
+
* An API key's lifecycle: `created`, `rotated` and `revoked` from the
|
|
721
|
+
* application or a credential store, `used` from `subjectFromApiKey`. A
|
|
722
|
+
* `used` event carries `sample`, the fraction of uses reported.
|
|
718
723
|
*/
|
|
719
|
-
type
|
|
724
|
+
type CredentialEvent = {
|
|
725
|
+
readonly type: "credential";
|
|
726
|
+
readonly at: string;
|
|
727
|
+
readonly source: string;
|
|
728
|
+
readonly operation: "created" | "used" | "rotated" | "revoked";
|
|
729
|
+
readonly credential: {
|
|
730
|
+
readonly id: string;
|
|
731
|
+
readonly kind: CredentialKind;
|
|
732
|
+
};
|
|
733
|
+
readonly principal: {
|
|
734
|
+
readonly id: string;
|
|
735
|
+
};
|
|
736
|
+
readonly tenant?: string;
|
|
737
|
+
/** When the key expires, an RFC 3339 instant. */
|
|
738
|
+
readonly expiresAt?: string;
|
|
739
|
+
readonly by?: {
|
|
740
|
+
readonly id: string;
|
|
741
|
+
readonly kind: string;
|
|
742
|
+
};
|
|
743
|
+
readonly sample?: number;
|
|
744
|
+
/** The application's own data, set where the event is built; plain JSON, never read by a decision. */
|
|
745
|
+
readonly x?: AppData;
|
|
746
|
+
};
|
|
747
|
+
/**
|
|
748
|
+
* An automation's lifecycle: `published`, `changed` (a new version) and
|
|
749
|
+
* `revoked` from the application, `run` when a run starts. It records the
|
|
750
|
+
* delegation for access review; it never decides.
|
|
751
|
+
*/
|
|
752
|
+
type AutomationEvent = {
|
|
753
|
+
readonly type: "automation";
|
|
754
|
+
readonly at: string;
|
|
755
|
+
readonly source: string;
|
|
756
|
+
readonly operation: "published" | "changed" | "revoked" | "run";
|
|
757
|
+
readonly automation: {
|
|
758
|
+
readonly id: string;
|
|
759
|
+
readonly version: number | string;
|
|
760
|
+
readonly mode: "publisher" | "service";
|
|
761
|
+
readonly name?: string;
|
|
762
|
+
};
|
|
763
|
+
/** The principal each run acts as. */
|
|
764
|
+
readonly principal: {
|
|
765
|
+
readonly id: string;
|
|
766
|
+
};
|
|
767
|
+
readonly publishedBy: string;
|
|
768
|
+
readonly tenant?: string;
|
|
769
|
+
readonly roles?: readonly string[];
|
|
770
|
+
/** The delegated permission keys. */
|
|
771
|
+
readonly permissions: readonly string[];
|
|
772
|
+
/** Set on `run` events only. */
|
|
773
|
+
readonly run?: {
|
|
774
|
+
readonly id: string;
|
|
775
|
+
};
|
|
776
|
+
readonly by?: {
|
|
777
|
+
readonly id: string;
|
|
778
|
+
readonly kind: string;
|
|
779
|
+
};
|
|
780
|
+
/** The application's own data, set where the event is built; plain JSON, never read by a decision. */
|
|
781
|
+
readonly x?: AppData;
|
|
782
|
+
};
|
|
783
|
+
type SinkEvent = DecisionEvent | DirectoryEvent | MembershipEvent | CredentialEvent | AccessEvent | AutomationEvent | DeliveryEvent;
|
|
784
|
+
/** A delivery channel: an email, a chat message or an outbound webhook. */
|
|
785
|
+
type DeliveryChannel = "email" | "chat" | "webhook";
|
|
786
|
+
/** What an email is for; only `notification` mail carries `List-Unsubscribe`. */
|
|
787
|
+
type EmailCategory = "transactional" | "notification" | "security" | "approval";
|
|
788
|
+
/**
|
|
789
|
+
* Why a delivery failed. `denied` and `unlinked` are the router's refusals of
|
|
790
|
+
* a recipient; the rest come from a transport or a provider webhook.
|
|
791
|
+
*/
|
|
792
|
+
type DeliveryFailureCause = "denied" | "unlinked" | "no-transport" | "no-message" | "invalid-recipient" | "invalid-message" | "rate-limited" | "quota-exceeded" | "unauthorized" | "unavailable" | "suppressed" | "rejected";
|
|
793
|
+
/**
|
|
794
|
+
* One recipient's delivery: `sent` when a transport accepted it, then
|
|
795
|
+
* `delivered`, `bounced` or `complained` from the provider, or `failed`.
|
|
796
|
+
* It carries no address, only the principal the router checked.
|
|
797
|
+
*/
|
|
798
|
+
type DeliveryEvent = {
|
|
799
|
+
readonly type: "delivery";
|
|
800
|
+
readonly at: string;
|
|
801
|
+
readonly source: string;
|
|
802
|
+
readonly operation: "sent" | "delivered" | "bounced" | "complained" | "failed";
|
|
803
|
+
readonly channel: DeliveryChannel;
|
|
804
|
+
/** The delivery's id and this recipient's key, sent as the `Idempotency-Key`. */
|
|
805
|
+
readonly delivery: {
|
|
806
|
+
readonly id: string;
|
|
807
|
+
readonly key: string;
|
|
808
|
+
};
|
|
809
|
+
/** The checked principal, or `trusted` for an address the server loaded itself. */
|
|
810
|
+
readonly recipient?: {
|
|
811
|
+
readonly principal?: {
|
|
812
|
+
readonly id: string;
|
|
813
|
+
};
|
|
814
|
+
readonly trusted?: true;
|
|
815
|
+
};
|
|
816
|
+
/** The permission the recipient was checked for. */
|
|
817
|
+
readonly permission?: string;
|
|
818
|
+
readonly tenant?: string;
|
|
819
|
+
readonly category?: EmailCategory;
|
|
820
|
+
/** The approval request a prompt was delivered for. */
|
|
821
|
+
readonly approval?: string;
|
|
822
|
+
/** The transport or provider, and its message id. */
|
|
823
|
+
readonly provider?: {
|
|
824
|
+
readonly name: string;
|
|
825
|
+
readonly id?: string;
|
|
826
|
+
};
|
|
827
|
+
/** Set on `failed` only. */
|
|
828
|
+
readonly cause?: DeliveryFailureCause;
|
|
829
|
+
/** Set on `failed` only: whether a retry with the same key may succeed. */
|
|
830
|
+
readonly retryable?: boolean;
|
|
831
|
+
/** The denial reason when `cause` is `denied`. */
|
|
832
|
+
readonly reason?: string;
|
|
833
|
+
/** The application's own data, set where the event is built; plain JSON, never read by a decision. */
|
|
834
|
+
readonly x?: AppData;
|
|
835
|
+
};
|
|
836
|
+
/**
|
|
837
|
+
* A support-access session lifecycle event: a tenant consented to vendor
|
|
838
|
+
* support (`started`), the session lapsed (`ended`), or the tenant pulled
|
|
839
|
+
* consent early (`revoked`). It never decides; it records what happened for
|
|
840
|
+
* audit and revocation.
|
|
841
|
+
*/
|
|
842
|
+
type AccessEvent = {
|
|
843
|
+
readonly type: "access";
|
|
844
|
+
readonly at: string;
|
|
845
|
+
readonly source: string;
|
|
846
|
+
readonly operation: "started" | "ended" | "revoked";
|
|
847
|
+
readonly tenant: string;
|
|
848
|
+
readonly principal: {
|
|
849
|
+
readonly id: string;
|
|
850
|
+
};
|
|
851
|
+
/** The membership kind the session runs under (`support`). */
|
|
852
|
+
readonly via: MembershipVia;
|
|
853
|
+
readonly roles: readonly string[];
|
|
854
|
+
readonly member?: {
|
|
855
|
+
readonly group: string;
|
|
856
|
+
};
|
|
857
|
+
/** When the session lapses, an RFC 3339 instant. */
|
|
858
|
+
readonly expiresAt?: string;
|
|
859
|
+
/** The tenant principal that consented. */
|
|
860
|
+
readonly grantedBy?: string;
|
|
861
|
+
readonly reason?: string;
|
|
862
|
+
readonly actor?: {
|
|
863
|
+
readonly id: string;
|
|
864
|
+
readonly kind: string;
|
|
865
|
+
};
|
|
866
|
+
/** A `SupportSession`: its id and the principal the staff member views as. */
|
|
867
|
+
readonly session?: {
|
|
868
|
+
readonly id: string;
|
|
869
|
+
readonly principal: string;
|
|
870
|
+
};
|
|
871
|
+
/** A `SupportSession`'s permission keys. */
|
|
872
|
+
readonly permissions?: readonly string[];
|
|
873
|
+
/** The application's own data, set where the event is built; plain JSON, never read by a decision. */
|
|
874
|
+
readonly x?: AppData;
|
|
875
|
+
};
|
|
876
|
+
type DecisionEvent = {
|
|
877
|
+
readonly type: "decision";
|
|
878
|
+
/** An RFC 3339 instant. */
|
|
879
|
+
readonly at: string;
|
|
880
|
+
readonly outcome: "granted" | "denied" | "approval-required";
|
|
720
881
|
readonly permission: string;
|
|
721
|
-
readonly
|
|
722
|
-
readonly
|
|
882
|
+
readonly scope: string;
|
|
883
|
+
readonly resource: {
|
|
884
|
+
readonly type: string;
|
|
885
|
+
readonly id?: string;
|
|
886
|
+
};
|
|
887
|
+
readonly subject: {
|
|
888
|
+
readonly principal: {
|
|
889
|
+
readonly id: string;
|
|
890
|
+
readonly roles: readonly string[];
|
|
891
|
+
readonly tenant?: string;
|
|
892
|
+
} | null;
|
|
893
|
+
readonly actor?: {
|
|
894
|
+
readonly id: string;
|
|
895
|
+
readonly kind: string;
|
|
896
|
+
};
|
|
897
|
+
/** OAuth `scope` and RFC 9396 `authorization_details`, as every wire form carries a delegation. */
|
|
898
|
+
readonly delegation?: WireDelegation;
|
|
899
|
+
/** The API key the subject came from. */
|
|
900
|
+
readonly credential?: {
|
|
901
|
+
readonly id: string;
|
|
902
|
+
readonly kind: CredentialKind;
|
|
903
|
+
};
|
|
904
|
+
/** The support session the subject came from: the `id` its `access` events carry as `session.id`. */
|
|
905
|
+
readonly supportSession?: {
|
|
906
|
+
readonly id: string;
|
|
907
|
+
};
|
|
908
|
+
};
|
|
909
|
+
readonly tenant?: string;
|
|
910
|
+
/** The membership that answered, with `expiresAt` as an RFC 3339 instant. */
|
|
911
|
+
readonly membership?: Omit<Membership, "expiresAt"> & {
|
|
912
|
+
readonly expiresAt?: string;
|
|
913
|
+
};
|
|
914
|
+
readonly via?: string | null;
|
|
915
|
+
readonly matched?: {
|
|
916
|
+
readonly role: string | null;
|
|
917
|
+
readonly permission: string;
|
|
918
|
+
/** The grant's declared `name`. */
|
|
919
|
+
readonly name?: string;
|
|
920
|
+
/** The grant's declared `meta`; PermDock never reads it. */
|
|
921
|
+
readonly meta?: GrantMeta;
|
|
922
|
+
readonly to?: Grantee | readonly Grantee[];
|
|
923
|
+
readonly hosted?: HostedGrantRef;
|
|
924
|
+
readonly breakGlass?: true;
|
|
925
|
+
};
|
|
926
|
+
/** What a granted decision owes, as on `GrantedDecision.obligations`. */
|
|
927
|
+
readonly obligations?: readonly Obligation[];
|
|
928
|
+
/** Purposes of use the caller asserted (`context.purpose`); present when any was. */
|
|
929
|
+
readonly purpose?: readonly string[];
|
|
930
|
+
/** The justification the caller supplied (`context.reason`); present when set. */
|
|
931
|
+
readonly reason?: string;
|
|
932
|
+
readonly denials?: readonly WireDenial[];
|
|
933
|
+
readonly alternatives?: readonly string[];
|
|
934
|
+
readonly token?: string;
|
|
935
|
+
readonly trusted: boolean;
|
|
936
|
+
/** The call that produced the decision. */
|
|
937
|
+
readonly call: "can" | "decide" | "assert" | "filter" | "endpoint" | "adapter" | "approval" | "simulate" | "explain";
|
|
938
|
+
readonly adapter?: AdapterId;
|
|
939
|
+
/** The model id the agent model gate decided, or the model that drove the call. */
|
|
940
|
+
readonly model?: string;
|
|
941
|
+
/** Set on an approval lifecycle event (`com.permdock.approval.<phase>`). */
|
|
942
|
+
readonly phase?: "requested" | "resolved" | "expired" | "cancelled";
|
|
943
|
+
readonly counts?: {
|
|
944
|
+
readonly granted: number;
|
|
945
|
+
readonly denied: number;
|
|
946
|
+
readonly approvalRequired: number;
|
|
947
|
+
};
|
|
948
|
+
/** The application's own data, set where the event is built; plain JSON, never read by a decision. */
|
|
949
|
+
readonly x?: AppData;
|
|
950
|
+
};
|
|
951
|
+
type AuthEvent = {
|
|
952
|
+
readonly reason: "invalid-token" | "schema" | "unknown-role" | "groups-overflow" | "source-threw";
|
|
953
|
+
readonly cause?: string;
|
|
954
|
+
readonly source: string;
|
|
955
|
+
/** The `name` of the source that threw, when it has one. */
|
|
956
|
+
readonly name?: string;
|
|
957
|
+
readonly kid?: string;
|
|
958
|
+
readonly alg?: string;
|
|
959
|
+
readonly typ?: string;
|
|
960
|
+
readonly issuer?: string;
|
|
961
|
+
readonly requestId?: string;
|
|
723
962
|
};
|
|
724
963
|
//#endregion
|
|
725
|
-
//#region src/core/
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
964
|
+
//#region src/core/snapshot-types.d.ts
|
|
965
|
+
type Snapshot = {
|
|
966
|
+
readonly v: 1;
|
|
967
|
+
/** RFC 3339. The epoch for a snapshot built without a clock. Signed, it is the token's `iat`. */
|
|
968
|
+
readonly issuedAt: string;
|
|
969
|
+
readonly subject: {
|
|
970
|
+
readonly principal: {
|
|
971
|
+
readonly id: string;
|
|
972
|
+
readonly roles: readonly string[];
|
|
973
|
+
readonly plans?: readonly string[];
|
|
974
|
+
readonly tenant?: string;
|
|
975
|
+
readonly memberships?: readonly Membership[];
|
|
976
|
+
} | null;
|
|
977
|
+
/** OAuth `scope` and RFC 9396 `authorization_details`, as the token carried them. */
|
|
978
|
+
readonly delegation?: WireDelegation;
|
|
979
|
+
readonly context: Readonly<Record<string, unknown>>;
|
|
980
|
+
};
|
|
981
|
+
/** Roles held in the active tenant, in rank order. */
|
|
982
|
+
readonly roles: readonly string[];
|
|
983
|
+
/** The distinct `meta.audience` values of `roles`, in rank order; absent when none has one. */
|
|
984
|
+
readonly audiences?: readonly string[];
|
|
985
|
+
readonly grants: readonly SnapshotGrant[];
|
|
986
|
+
readonly tenants: readonly string[];
|
|
987
|
+
readonly include?: readonly string[];
|
|
988
|
+
readonly simulated?: true;
|
|
989
|
+
/** RFC 3339. Signed, it is the token's `exp`. */
|
|
990
|
+
readonly expiresAt?: string;
|
|
991
|
+
readonly vocabulary?: {
|
|
992
|
+
readonly roles?: Readonly<Record<string, Role>>;
|
|
993
|
+
readonly plans?: Readonly<Record<string, Plan>>;
|
|
994
|
+
};
|
|
995
|
+
/** The policy's scopes in order, so a client checks the row against each membership's instance. */
|
|
996
|
+
readonly scopes?: readonly SnapshotScope[];
|
|
997
|
+
/** One entry per tenant in `tenants`: what the subject may hand out there. Absent without tenants. */
|
|
998
|
+
readonly assignable?: readonly SnapshotAssignable[];
|
|
999
|
+
/**
|
|
1000
|
+
* Allow grants of held roles that only a plan the subject lacks keeps
|
|
1001
|
+
* from applying; they grant nothing and name the plan a denial asks for.
|
|
1002
|
+
*/
|
|
1003
|
+
readonly notEntitled?: readonly SnapshotNotEntitled[];
|
|
1004
|
+
/**
|
|
1005
|
+
* The row id field per resource whose `id` option is not `id`, for the
|
|
1006
|
+
* grants in `grants`. Absent when every one reads `id`.
|
|
1007
|
+
*/
|
|
1008
|
+
readonly ids?: Readonly<Record<string, string>>;
|
|
1009
|
+
/**
|
|
1010
|
+
* The permission keys the policy's delegations let the actor use for the
|
|
1011
|
+
* principal, sorted; present only when one applies. Outside it a check is
|
|
1012
|
+
* `not-delegated`; inside it a token delegation, when there is one, must
|
|
1013
|
+
* still cover.
|
|
1014
|
+
*/
|
|
1015
|
+
readonly delegated?: readonly string[];
|
|
1016
|
+
};
|
|
1017
|
+
/** A grant the subject would hold on another plan: its permission, role and `to`. */
|
|
1018
|
+
type SnapshotNotEntitled = {
|
|
729
1019
|
readonly permission: string;
|
|
730
|
-
readonly
|
|
1020
|
+
readonly role: string | null;
|
|
1021
|
+
readonly to: Grantee | readonly Grantee[];
|
|
1022
|
+
};
|
|
1023
|
+
/** One declared scope as a snapshot carries it. */
|
|
1024
|
+
type SnapshotScope = {
|
|
1025
|
+
readonly name: string;
|
|
1026
|
+
readonly key: string;
|
|
1027
|
+
readonly within?: string;
|
|
1028
|
+
/** Resources whose rows this scope's key partitions, from their `memberOf` relations. */
|
|
1029
|
+
readonly resources?: readonly string[];
|
|
1030
|
+
/** Resource name to the field holding this scope's id, for a resource whose field is not `key` (its own `id`). */
|
|
1031
|
+
readonly fields?: Readonly<Record<string, string>>;
|
|
1032
|
+
};
|
|
1033
|
+
/** The declared roles and the custom-role ceiling the subject may assign in one tenant. */
|
|
1034
|
+
type SnapshotAssignable = {
|
|
1035
|
+
readonly tenant: string;
|
|
1036
|
+
readonly roles: readonly string[];
|
|
1037
|
+
readonly permissions: readonly Permission[];
|
|
1038
|
+
/** Permission key to the levels the subject may hand out; only permissions whose resource declares levels. */
|
|
1039
|
+
readonly levels?: Readonly<Record<string, readonly string[]>>;
|
|
1040
|
+
};
|
|
1041
|
+
type SnapshotGrant = {
|
|
1042
|
+
readonly permission: string;
|
|
1043
|
+
readonly effect: "allow" | "deny";
|
|
1044
|
+
readonly role: string | null;
|
|
731
1045
|
readonly to: Grantee | readonly Grantee[];
|
|
732
1046
|
readonly where?: Condition;
|
|
733
1047
|
readonly check?: Condition;
|
|
734
1048
|
readonly approval?: "human" | ApprovalRequirement;
|
|
1049
|
+
/** A scope name or one resource; absent for a global grant. */
|
|
1050
|
+
readonly scope?: string | {
|
|
1051
|
+
readonly resource: string;
|
|
1052
|
+
};
|
|
1053
|
+
readonly membership?: Membership;
|
|
1054
|
+
readonly portable?: false;
|
|
735
1055
|
readonly fields?: readonly string[];
|
|
1056
|
+
/** When the grant applies (RFC 3339, `from` inclusive, `until` exclusive); absent means always. */
|
|
1057
|
+
readonly validity?: WireValidity;
|
|
1058
|
+
/** The grant's declared `name`. */
|
|
1059
|
+
readonly name?: string;
|
|
1060
|
+
/** The grant's declared `meta`; visible to the client that holds the snapshot. */
|
|
1061
|
+
readonly meta?: GrantMeta;
|
|
1062
|
+
/** The app obligations an allow declares, emitted on a granted decision. */
|
|
1063
|
+
readonly obligations?: readonly AppObligation[];
|
|
736
1064
|
};
|
|
737
|
-
/**
|
|
738
|
-
|
|
1065
|
+
/**
|
|
1066
|
+
* What a policy grants, as JSON a client builds snapshots from without the
|
|
1067
|
+
* policy: `localSnapshotManifest(policy)` writes it, `localSnapshot` in
|
|
1068
|
+
* `permdock/react-native` reads it.
|
|
1069
|
+
*/
|
|
1070
|
+
type LocalSnapshotManifest = {
|
|
739
1071
|
readonly v: 1;
|
|
740
|
-
readonly
|
|
741
|
-
readonly
|
|
742
|
-
/**
|
|
743
|
-
readonly
|
|
744
|
-
|
|
745
|
-
readonly
|
|
1072
|
+
readonly scopes?: readonly SnapshotScope[];
|
|
1073
|
+
readonly vocabulary?: Snapshot["vocabulary"];
|
|
1074
|
+
/** Declared role names; a custom role cannot take one. */
|
|
1075
|
+
readonly roles: readonly string[];
|
|
1076
|
+
/** Declared role names in rank order, when an `assigns` graph ranks them. */
|
|
1077
|
+
readonly rank?: readonly string[];
|
|
1078
|
+
/** Every declared grant, without a membership. */
|
|
1079
|
+
readonly grants: readonly SnapshotGrant[];
|
|
1080
|
+
/** Per custom-role scope (`global` for platform roles): the grants each entry resolves to. */
|
|
1081
|
+
readonly custom: Readonly<Record<string, LocalCustomRoleTable>>;
|
|
746
1082
|
};
|
|
1083
|
+
/** Grants a custom role entry resolves to, held by a placeholder role the client renames. */
|
|
1084
|
+
type LocalCustomRoleTable = {
|
|
1085
|
+
/** `{ permission }` per permission key, and `{ permission, level }` per declared level. */
|
|
1086
|
+
readonly permissions: Readonly<Record<string, {
|
|
1087
|
+
readonly all: readonly SnapshotGrant[];
|
|
1088
|
+
readonly levels?: Readonly<Record<string, readonly SnapshotGrant[]>>;
|
|
1089
|
+
}>>;
|
|
1090
|
+
/** `includes: [role]` per declared role. */
|
|
1091
|
+
readonly includes: Readonly<Record<string, readonly SnapshotGrant[]>>;
|
|
1092
|
+
};
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region src/core/time.d.ts
|
|
747
1095
|
/**
|
|
748
|
-
* The
|
|
749
|
-
* the
|
|
1096
|
+
* The one time rule: NumericDate (whole seconds) for JWT registered claims
|
|
1097
|
+
* and the claims SQL reads, RFC 3339 for every other JSON field, integer
|
|
1098
|
+
* seconds for durations, and an `Instant` for every runtime `now`.
|
|
750
1099
|
*/
|
|
751
|
-
type PolicySource = {
|
|
752
|
-
current(): PolicyDocument | null;
|
|
753
|
-
refresh(): Promise<void>;
|
|
754
|
-
};
|
|
755
|
-
type HostedGrantDropReason = "not-hostable" | "unknown-permission" | "unknown-grantee" | "non-portable" | "weaker-approval" | "invalid";
|
|
756
|
-
/** Reported through `on('error')` when a hosted grant is not merged; never thrown. */
|
|
757
|
-
type HostedGrantDropped = {
|
|
758
|
-
readonly kind: "hosted-grant-dropped";
|
|
759
|
-
readonly document: string;
|
|
760
|
-
readonly grant: string;
|
|
761
|
-
readonly reason: HostedGrantDropReason;
|
|
762
|
-
};
|
|
763
|
-
declare function memoryPolicySource(document?: PolicyDocument | null): PolicySource;
|
|
764
|
-
/** Validates the document envelope; per-grant checks happen at merge time. */
|
|
765
|
-
declare function parsePolicyDocument(json: unknown): PolicyDocument;
|
|
766
|
-
/** True for the portable subset only: no `opaque`, no `sqlFunction`, no unknown op. */
|
|
767
|
-
declare function isPortableCondition(value: unknown): value is Condition;
|
|
768
1100
|
/**
|
|
769
|
-
* The
|
|
770
|
-
*
|
|
771
|
-
*
|
|
1101
|
+
* The part of a `Temporal.Instant` PermDock reads. Public options take it
|
|
1102
|
+
* structurally so their declarations compile under a TypeScript lib without
|
|
1103
|
+
* `Temporal` (5.9); every `Temporal.Instant` satisfies it.
|
|
772
1104
|
*/
|
|
773
|
-
|
|
774
|
-
readonly
|
|
775
|
-
readonly dropped: readonly HostedGrantDropped[];
|
|
1105
|
+
type Instant = {
|
|
1106
|
+
readonly epochMilliseconds: number;
|
|
776
1107
|
};
|
|
777
1108
|
//#endregion
|
|
778
|
-
//#region src/core/
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
/** Decision clock in Unix seconds, for expiries and limits. Defaults to the current time. */
|
|
785
|
-
readonly now?: number;
|
|
786
|
-
/** The call that produced the decision, reported on the decision event. Defaults to `'decide'`. */
|
|
787
|
-
readonly source?: DecisionEvent["source"];
|
|
788
|
-
/** The adapter that made the call, reported on the decision event. */
|
|
789
|
-
readonly adapter?: string;
|
|
790
|
-
/** Per-call unauthorized handler for `assert`; runs before instance and policy handlers. */
|
|
791
|
-
readonly onDenied?: (decision: Decision) => never | void;
|
|
792
|
-
/** The field being read or written; only grants whose `fields` cover it match. */
|
|
793
|
-
readonly field?: string;
|
|
794
|
-
/** `true` attaches a `trace` to the decision: the grants evaluated, matched and skipped. Off by default and free when off. */
|
|
795
|
-
readonly explain?: boolean;
|
|
796
|
-
/**
|
|
797
|
-
* A declared scope name: only memberships of that scope answer the check.
|
|
798
|
-
* Naming the first scope keeps nested memberships out of a tenant-level
|
|
799
|
-
* guard on a collection action. Global roles still apply; resource roles
|
|
800
|
-
* and memberships of other scopes are skipped with reason `scope`.
|
|
801
|
-
*/
|
|
802
|
-
readonly scope?: string;
|
|
803
|
-
};
|
|
804
|
-
type SimulateOptions = {
|
|
805
|
-
/** Decision clock in Unix seconds for the whole batch: grant validity, membership expiry and limits are read as of this instant. Defaults to the current time. */
|
|
806
|
-
readonly now?: number;
|
|
807
|
-
};
|
|
808
|
-
type RowPair<T> = {
|
|
809
|
-
readonly current: T;
|
|
810
|
-
readonly next: T;
|
|
811
|
-
};
|
|
812
|
-
type WhereResult = {
|
|
813
|
-
readonly condition: Condition | {
|
|
814
|
-
readonly op: "or";
|
|
815
|
-
readonly conditions: readonly [];
|
|
816
|
-
};
|
|
817
|
-
readonly partial: boolean;
|
|
818
|
-
/**
|
|
819
|
-
* The subject `where()` was built for. `toWhere` reads its memberships for
|
|
820
|
-
* `memberOf` when no `subject` option is passed. Not enumerable, so it never
|
|
821
|
-
* serialises with the result.
|
|
822
|
-
*/
|
|
823
|
-
readonly subject?: Subject;
|
|
824
|
-
/** The policy's scopes, for `memberOf`; not enumerable either. */
|
|
825
|
-
readonly scopes?: readonly Scope[];
|
|
826
|
-
/** The policy's resource graph, for `related`; not enumerable either. */
|
|
827
|
-
readonly resources?: ReadonlyMap<string, ResourceNode>;
|
|
828
|
-
};
|
|
829
|
-
type SnapshotOptions = {
|
|
830
|
-
readonly include?: readonly (Permission | {
|
|
831
|
-
readonly [key: string]: unknown;
|
|
832
|
-
})[];
|
|
833
|
-
readonly tenants?: "all";
|
|
834
|
-
readonly signer?: TokenSigner;
|
|
835
|
-
readonly audience?: string | readonly string[];
|
|
836
|
-
};
|
|
837
|
-
type PermDock<V extends PolicyVocabulary = PolicyVocabulary> = {
|
|
838
|
-
readonly can: {
|
|
839
|
-
(permission: Permission<string, unknown, "instance">, data: unknown, options?: DecideOptions): boolean;
|
|
840
|
-
(permission: Permission<string, unknown, "collection">, data?: unknown, options?: DecideOptions): boolean;
|
|
841
|
-
/**
|
|
842
|
-
* A permission held as `Permission` at run time (from a list, a catalog
|
|
843
|
-
* or `findPermission`), whose kind the type does not say: pass `data`,
|
|
844
|
-
* or `undefined` for a check without a row.
|
|
845
|
-
*/
|
|
846
|
-
(permission: Permission, data: unknown, options?: DecideOptions): boolean;
|
|
847
|
-
};
|
|
848
|
-
readonly decide: {
|
|
849
|
-
(permission: Permission<string, unknown, "instance">, data: unknown, options?: DecideOptions): Decision;
|
|
850
|
-
(permission: Permission<string, unknown, "collection">, data?: unknown, options?: DecideOptions): Decision;
|
|
851
|
-
/**
|
|
852
|
-
* A permission held as `Permission` at run time (from a list, a catalog
|
|
853
|
-
* or `findPermission`), whose kind the type does not say: pass `data`,
|
|
854
|
-
* or `undefined` for a check without a row.
|
|
855
|
-
*/
|
|
856
|
-
(permission: Permission, data: unknown, options?: DecideOptions): Decision;
|
|
857
|
-
};
|
|
858
|
-
readonly assert: {
|
|
859
|
-
(permission: Permission<string, unknown, "instance">, data: unknown, options?: DecideOptions): Extract<Decision, {
|
|
860
|
-
readonly outcome: "granted";
|
|
861
|
-
}>;
|
|
862
|
-
(permission: Permission<string, unknown, "collection">, data?: unknown, options?: DecideOptions): Extract<Decision, {
|
|
863
|
-
readonly outcome: "granted";
|
|
864
|
-
}>;
|
|
865
|
-
/**
|
|
866
|
-
* A permission held as `Permission` at run time (from a list, a catalog
|
|
867
|
-
* or `findPermission`), whose kind the type does not say: pass `data`,
|
|
868
|
-
* or `undefined` for a check without a row.
|
|
869
|
-
*/
|
|
870
|
-
(permission: Permission, data: unknown, options?: DecideOptions): Extract<Decision, {
|
|
871
|
-
readonly outcome: "granted";
|
|
872
|
-
}>;
|
|
873
|
-
};
|
|
874
|
-
/**
|
|
875
|
-
* `decide` with `explain: true`: the same decision, with a `trace` that
|
|
876
|
-
* names the grants evaluated, the allows and denies that matched (so a
|
|
877
|
-
* `denied` says which deny won) and the grants passed over. Local
|
|
878
|
-
* computation only; the trace never reaches a `DecisionSink`.
|
|
879
|
-
*/
|
|
880
|
-
readonly explain: {
|
|
881
|
-
(permission: Permission<string, unknown, "instance">, data: unknown, options?: Omit<DecideOptions, "explain">): ExplainedDecision;
|
|
882
|
-
(permission: Permission<string, unknown, "collection">, data?: unknown, options?: Omit<DecideOptions, "explain">): ExplainedDecision;
|
|
883
|
-
(permission: Permission, data: unknown, options?: Omit<DecideOptions, "explain">): ExplainedDecision;
|
|
884
|
-
};
|
|
885
|
-
readonly filter: <T>(permission: Permission<string, T, "instance">, rows: readonly T[], options?: DecideOptions) => T[];
|
|
886
|
-
readonly pick: <T>(permission: Permission<string, T, "instance">, row: T, options?: DecideOptions) => Partial<T>;
|
|
887
|
-
readonly where: (permission: Permission) => WhereResult;
|
|
888
|
-
readonly actions: (resource: Permission | {
|
|
889
|
-
readonly [key: string]: unknown;
|
|
890
|
-
}, data: unknown, options?: DecideOptions) => Permission[];
|
|
891
|
-
readonly simulate: {
|
|
892
|
-
(checks: readonly (readonly [Permission, unknown?])[], options?: SimulateOptions): Decision[];
|
|
893
|
-
(preview: {
|
|
894
|
-
readonly roles?: readonly (string | Role)[];
|
|
895
|
-
readonly memberships?: readonly Membership[];
|
|
896
|
-
readonly tenant?: string;
|
|
897
|
-
}): PermDock<V>;
|
|
898
|
-
(plan: ArazzoSimulateInput): ArazzoPlan;
|
|
899
|
-
};
|
|
900
|
-
readonly snapshot: {
|
|
901
|
-
(options?: SnapshotOptions & {
|
|
902
|
-
readonly signer?: undefined;
|
|
903
|
-
}): Snapshot;
|
|
904
|
-
(options: SnapshotOptions & {
|
|
905
|
-
readonly signer: TokenSigner;
|
|
906
|
-
}): Promise<string>;
|
|
907
|
-
(options?: SnapshotOptions): Snapshot | Promise<string>;
|
|
908
|
-
};
|
|
909
|
-
readonly on: (event: "decision" | "denied" | "approval" | "auth" | "error", handler: (payload: unknown) => void) => () => void;
|
|
910
|
-
readonly tenant: (id: string) => PermDock<V>;
|
|
911
|
-
readonly team: (id: string) => PermDock<V>;
|
|
912
|
-
readonly memberships: () => readonly Membership[];
|
|
913
|
-
readonly tenants: () => readonly string[];
|
|
914
|
-
/**
|
|
915
|
-
* Roles held in a tenant (the active one by default), or only on the
|
|
916
|
-
* memberships of one `scope` (and instance `id`). Ordered by rank: a role
|
|
917
|
-
* comes before the roles its `assigns` lists.
|
|
918
|
-
*/
|
|
919
|
-
readonly heldRoles: (options?: {
|
|
920
|
-
readonly tenant?: string;
|
|
921
|
-
readonly scope?: string;
|
|
922
|
-
readonly id?: string;
|
|
923
|
-
}) => readonly Role[];
|
|
924
|
-
/** The distinct `meta.audience` values of the roles held in the active tenant, in rank order. */
|
|
925
|
-
readonly audiences: () => readonly string[];
|
|
926
|
-
/**
|
|
927
|
-
* The roles the subject may hand out in a tenant (the active one by
|
|
928
|
-
* default), or with `scope: 'global'` the global roles it may hand out. A
|
|
929
|
-
* snapshot answers only the tenant form.
|
|
930
|
-
*/
|
|
931
|
-
readonly assignableRoles: (options?: {
|
|
932
|
-
readonly tenant?: string;
|
|
933
|
-
readonly scope?: "global";
|
|
934
|
-
}) => readonly Role[];
|
|
935
|
-
/**
|
|
936
|
-
* The custom-role ceiling the subject may hand out: in a tenant (empty
|
|
937
|
-
* without one), or with `scope: 'global'` for platform custom roles, the
|
|
938
|
-
* allows of assignable global roles the subject holds. A snapshot answers
|
|
939
|
-
* only the tenant form.
|
|
940
|
-
*/
|
|
941
|
-
readonly assignablePermissions: (options?: {
|
|
942
|
-
readonly tenant?: string;
|
|
943
|
-
readonly scope?: "global";
|
|
944
|
-
}) => readonly Permission[];
|
|
945
|
-
/**
|
|
946
|
-
* The levels of `permission` (`resource(…, { levels })`) the subject may
|
|
947
|
-
* hand out in a custom role: those it holds, or every level with
|
|
948
|
-
* `meta.manageRoles`. Empty when the permission is not assignable.
|
|
949
|
-
*/
|
|
950
|
-
readonly assignableLevels: (permission: Permission, options?: {
|
|
951
|
-
readonly tenant?: string;
|
|
952
|
-
readonly scope?: "global";
|
|
953
|
-
}) => readonly string[];
|
|
954
|
-
/**
|
|
955
|
-
* Whether the subject may assign, revoke or transfer a role in one scope
|
|
956
|
-
* instance: `assigns`, the ceiling, `for`, `exclusiveWith`, `min`, `max`
|
|
957
|
-
* and `transferOnly`. It never writes; the application does, and generated
|
|
958
|
-
* RLS triggers re-check the holder counts at commit. A nested instance's
|
|
959
|
-
* tenant comes from a live membership the subject holds on it, or from
|
|
960
|
-
* `change.within` only with `{ trusted: true }`; otherwise `no-membership`.
|
|
961
|
-
*/
|
|
962
|
-
readonly decideRoleChange: (change: RoleChange, options?: RoleChangeOptions) => RoleChangeDecision;
|
|
963
|
-
/**
|
|
964
|
-
* Loads the relation facts `permission` needs for `rows` into this
|
|
965
|
-
* instance's cache, so `can`, `decide` and `filter` answer synchronously
|
|
966
|
-
* over an async `RelationSource`. It never grants; a failed load leaves
|
|
967
|
-
* the checks denied with `relation-unavailable`.
|
|
968
|
-
*/
|
|
969
|
-
readonly loadRelations: (permission: Permission, rows: readonly unknown[]) => Promise<void>;
|
|
970
|
-
/**
|
|
971
|
-
* Who holds `permission` on `resource` and how (role, relation or share),
|
|
972
|
-
* from `MembershipSource.list` and `RelationSource.related`. It lists and
|
|
973
|
-
* never grants; `complete: false` means some holders could not be listed.
|
|
974
|
-
*/
|
|
975
|
-
readonly whoCan: (permission: Permission<string, unknown, "instance">, resource: unknown) => Promise<WhoCan>;
|
|
976
|
-
/**
|
|
977
|
-
* Requests a just-in-time activation of an eligible role. It never writes:
|
|
978
|
-
* a granted decision carries the elevated membership under `elevation` for
|
|
979
|
-
* the app to write, and `approval-required` comes back first when the
|
|
980
|
-
* role's `activation` sets `approval`.
|
|
981
|
-
*/
|
|
982
|
-
readonly activate: (input: ActivateInput) => Decision;
|
|
983
|
-
readonly roles: V["roles"] extends RoleTree ? V["roles"] : RoleTree;
|
|
984
|
-
readonly plans: V["plans"] extends PlanTree ? V["plans"] : PlanTree;
|
|
985
|
-
readonly permissions: V["permissions"] extends Policy["permissions"] ? V["permissions"] : Policy["permissions"];
|
|
1109
|
+
//#region src/core/internals.d.ts
|
|
1110
|
+
/**
|
|
1111
|
+
* Any instance a feature function accepts: a server `PermDock`, one built
|
|
1112
|
+
* from a snapshot, or an adapter's wrapper such as `PdpPermDock`.
|
|
1113
|
+
*/
|
|
1114
|
+
type InstanceHandle = {
|
|
986
1115
|
readonly subject: Subject;
|
|
987
|
-
/**
|
|
988
|
-
* The same subject, tenant, team, actor, delegation, sink and limits with
|
|
989
|
-
* other sources: `customRoles`, `approvalPolicies` or `relations`. The
|
|
990
|
-
* sources it names are read again for the subject's tenants; the others
|
|
991
|
-
* keep what this instance loaded. Returns a promise when a source it names
|
|
992
|
-
* answers asynchronously.
|
|
993
|
-
*/
|
|
994
|
-
readonly derive: (options: DeriveOptions) => PermDock<V> | Promise<PermDock<V>>;
|
|
995
1116
|
};
|
|
996
|
-
/** What `permdock.derive` may replace: the sources read after the subject is resolved. */
|
|
997
|
-
type DeriveOptions = Pick<PermDockOptions, "customRoles" | "approvalPolicies" | "relations">;
|
|
998
|
-
type PermDockOptions = {
|
|
999
|
-
readonly tenant?: string;
|
|
1000
|
-
/** One source, or several composed with `composeMemberships`. */
|
|
1001
|
-
readonly memberships?: MembershipSource | readonly MembershipSource[];
|
|
1002
|
-
readonly customRoles?: RoleSource | RoleSourceFactory;
|
|
1003
|
-
/** Plans and seats from billing, merged into `principal.plans` for the active tenant. */
|
|
1004
|
-
readonly entitlements?: EntitlementSource;
|
|
1005
|
-
readonly actor?: Actor;
|
|
1006
|
-
readonly delegation?: Delegation;
|
|
1007
|
-
readonly sink?: DecisionSink;
|
|
1008
|
-
readonly limits?: LimitStore;
|
|
1009
|
-
readonly session?: string;
|
|
1010
|
-
readonly expiresAt?: number;
|
|
1011
|
-
/** Hosted grants; `current()` is read once, when the instance is created. */
|
|
1012
|
-
readonly policies?: PolicySource;
|
|
1013
|
-
/** The object graph for `through` and edge-table relations; without it they deny with `relation-unavailable`. */
|
|
1014
|
-
readonly relations?: RelationSource;
|
|
1015
|
-
/** Approval requirements kept as data; they add to the code's and never remove one. A throw denies. */
|
|
1016
|
-
readonly approvalPolicies?: ApprovalPolicySource;
|
|
1017
|
-
};
|
|
1018
|
-
declare function createPermDock<TUser, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary>(policy: Policy<TUser, TPrincipal, V>, user: TUser | Subject | null, options?: PermDockOptions): PermDock<V> | Promise<PermDock<V>>;
|
|
1019
1117
|
//#endregion
|
|
1020
1118
|
//#region src/core/credential.d.ts
|
|
1021
|
-
type CredentialKind = "user" | "service";
|
|
1119
|
+
type CredentialKind = "user" | "service" | "feed";
|
|
1120
|
+
/** A feed id: lowercase, so a mail system that lowercases a local part still matches. At most 16 characters, so `pdfeed_<id>_<secret>` fits an email local part. */
|
|
1121
|
+
declare function isFeedId(value: string): boolean;
|
|
1022
1122
|
/** One permission (a key) a credential may use: on every instance, or only on `ids`. */
|
|
1023
1123
|
type CredentialPermission = {
|
|
1024
1124
|
readonly permission: string;
|
|
@@ -1043,17 +1143,22 @@ type Credential = {
|
|
|
1043
1143
|
* credential, where it keeps only the owner's memberships inside it.
|
|
1044
1144
|
*/
|
|
1045
1145
|
readonly tenant?: string;
|
|
1046
|
-
/** Service
|
|
1146
|
+
/** Service: the roles it holds in `tenant`. Feed: the resource roles it holds on `on`. */
|
|
1047
1147
|
readonly roles?: readonly string[];
|
|
1148
|
+
/** Feed only: the resource instance the roles are held on. */
|
|
1149
|
+
readonly on?: {
|
|
1150
|
+
readonly resource: string;
|
|
1151
|
+
readonly id: string;
|
|
1152
|
+
};
|
|
1048
1153
|
readonly permissions: readonly CredentialPermission[];
|
|
1049
1154
|
readonly createdBy: string;
|
|
1050
|
-
/**
|
|
1051
|
-
readonly createdAt:
|
|
1052
|
-
/**
|
|
1053
|
-
readonly expiresAt?:
|
|
1155
|
+
/** RFC 3339. */
|
|
1156
|
+
readonly createdAt: string;
|
|
1157
|
+
/** RFC 3339; absent only where a credential policy allows it. */
|
|
1158
|
+
readonly expiresAt?: string;
|
|
1054
1159
|
readonly name?: string;
|
|
1055
1160
|
};
|
|
1056
|
-
type
|
|
1161
|
+
type ApiKeyPrincipal = Principal & {
|
|
1057
1162
|
readonly credential: Credential;
|
|
1058
1163
|
};
|
|
1059
1164
|
/**
|
|
@@ -1078,7 +1183,8 @@ type CredentialPermissionInput = Permission | {
|
|
|
1078
1183
|
type CredentialRequestBase = {
|
|
1079
1184
|
readonly id: string;
|
|
1080
1185
|
readonly permissions: readonly CredentialPermissionInput[];
|
|
1081
|
-
|
|
1186
|
+
/** RFC 3339; must be after `now`. */
|
|
1187
|
+
readonly expiresAt?: string;
|
|
1082
1188
|
readonly name?: string;
|
|
1083
1189
|
};
|
|
1084
1190
|
type CredentialRequest = (CredentialRequestBase & {
|
|
@@ -1091,6 +1197,15 @@ type CredentialRequest = (CredentialRequestBase & {
|
|
|
1091
1197
|
readonly principal?: string;
|
|
1092
1198
|
readonly tenant: string;
|
|
1093
1199
|
readonly roles: readonly string[];
|
|
1200
|
+
}) | (CredentialRequestBase & {
|
|
1201
|
+
readonly kind: "feed";
|
|
1202
|
+
readonly on: {
|
|
1203
|
+
readonly resource: Permission | PermissionTree;
|
|
1204
|
+
readonly id: string;
|
|
1205
|
+
};
|
|
1206
|
+
readonly roles: readonly string[];
|
|
1207
|
+
/** A row the server loaded. Each permission must be granted on it. */
|
|
1208
|
+
readonly row: unknown;
|
|
1094
1209
|
});
|
|
1095
1210
|
type CredentialDecision = {
|
|
1096
1211
|
readonly outcome: "granted";
|
|
@@ -1109,8 +1224,8 @@ type DecideCredentialOptions = {
|
|
|
1109
1224
|
readonly settings?: SettingsSource;
|
|
1110
1225
|
/** The `token` of an approval the application consumed for this request. */
|
|
1111
1226
|
readonly approved?: string;
|
|
1112
|
-
/**
|
|
1113
|
-
readonly now?:
|
|
1227
|
+
/** The creation time; defaults to the clock. */
|
|
1228
|
+
readonly now?: Instant;
|
|
1114
1229
|
};
|
|
1115
1230
|
/**
|
|
1116
1231
|
* The first rule of `policy` the credential breaks, or `undefined`. A key
|
|
@@ -1132,20 +1247,6 @@ declare function parseCredential(input: unknown): Credential | undefined;
|
|
|
1132
1247
|
* key is gone delegates nothing and every check is denied.
|
|
1133
1248
|
*/
|
|
1134
1249
|
declare function credentialDelegation(credential: Credential, permissions: PermissionTree): Delegation;
|
|
1135
|
-
/**
|
|
1136
|
-
* The subject a verified credential acts as. A `user` credential is its
|
|
1137
|
-
* owner, passed live as `owner` (roles and memberships as of this request),
|
|
1138
|
-
* with the credential's delegation: every check is the owner's rights
|
|
1139
|
-
* intersected with the key's. One that names a `tenant` makes it the active
|
|
1140
|
-
* tenant, and `createPermDock` then keeps only the owner's memberships
|
|
1141
|
-
* inside it and no global role. A `service` credential is a `service`
|
|
1142
|
-
* principal whose only membership is `roles` in `tenant`. An owner whose id
|
|
1143
|
-
* is not the credential's `principal`, or who is not a user, is anonymous.
|
|
1144
|
-
*/
|
|
1145
|
-
declare function credentialSubject(credential: Credential, options: {
|
|
1146
|
-
readonly permissions: PermissionTree;
|
|
1147
|
-
readonly owner?: Principal;
|
|
1148
|
-
}): Subject<CredentialPrincipal> | Subject;
|
|
1149
1250
|
/**
|
|
1150
1251
|
* Decides whether the subject of `permdock` may create the credential in
|
|
1151
1252
|
* `request`. The creator must be a signed-in user or service that is not
|
|
@@ -1160,25 +1261,113 @@ declare function credentialSubject(credential: Credential, options: {
|
|
|
1160
1261
|
* its token. PermDock never stores the credential; the application does,
|
|
1161
1262
|
* after a `granted` result.
|
|
1162
1263
|
*/
|
|
1163
|
-
|
|
1264
|
+
/**
|
|
1265
|
+
* Decides whether the subject of `permdock` may create the credential in
|
|
1266
|
+
* `request`: the creator's own reach, the `credentials` policy of the key's
|
|
1267
|
+
* tenant (the call's `settings`, else the instance's), and `approval`.
|
|
1268
|
+
* PermDock never stores the credential; the application does, after a
|
|
1269
|
+
* `granted` result. An instance built from a snapshot denies with
|
|
1270
|
+
* `unsupported`.
|
|
1271
|
+
*/
|
|
1272
|
+
declare function decideCredential(permdock: InstanceHandle, request: CredentialRequest, options?: DecideCredentialOptions): Promise<CredentialDecision>;
|
|
1164
1273
|
//#endregion
|
|
1165
|
-
//#region src/core/
|
|
1274
|
+
//#region src/core/support-session.d.ts
|
|
1166
1275
|
/**
|
|
1167
|
-
*
|
|
1168
|
-
*
|
|
1169
|
-
*
|
|
1170
|
-
*
|
|
1276
|
+
* SupportSession v1: a support staff member (`actor`, kind `support`)
|
|
1277
|
+
* viewing the app as `principal` in `tenant`, for a stated `reason`. Each
|
|
1278
|
+
* request in the session acts as `principal` with their live rights,
|
|
1279
|
+
* narrowed to `permissions`.
|
|
1171
1280
|
*/
|
|
1172
|
-
type
|
|
1173
|
-
readonly
|
|
1174
|
-
readonly
|
|
1175
|
-
|
|
1176
|
-
readonly
|
|
1281
|
+
type SupportSession = {
|
|
1282
|
+
readonly v: 1;
|
|
1283
|
+
readonly id: string;
|
|
1284
|
+
/** The person the session views the app as. */
|
|
1285
|
+
readonly principal: string;
|
|
1286
|
+
/** The support staff member running the session. */
|
|
1287
|
+
readonly actor: string;
|
|
1288
|
+
readonly tenant: string;
|
|
1289
|
+
readonly reason: string;
|
|
1290
|
+
/** The delegation: permission keys, read-only unless listed on purpose. */
|
|
1291
|
+
readonly permissions: readonly string[];
|
|
1292
|
+
/** RFC 3339. */
|
|
1293
|
+
readonly startedAt: string;
|
|
1294
|
+
/** RFC 3339. */
|
|
1295
|
+
readonly expiresAt: string;
|
|
1296
|
+
/** Who approved the session; never `actor`. */
|
|
1297
|
+
readonly approvedBy?: string;
|
|
1298
|
+
/** The application's ticket or case id. */
|
|
1299
|
+
readonly reference?: string;
|
|
1300
|
+
};
|
|
1301
|
+
/** A tenant's rules for support sessions. Every field only tightens. */
|
|
1302
|
+
type SupportSessionPolicy = {
|
|
1303
|
+
/** No session may start in this tenant. */
|
|
1304
|
+
readonly disabled?: boolean;
|
|
1305
|
+
/** Longest a session may last, in seconds. */
|
|
1306
|
+
readonly maxTtl?: number;
|
|
1307
|
+
/** Only `readOnlyHint` permissions, whatever the request lists. */
|
|
1308
|
+
readonly readOnly?: boolean;
|
|
1177
1309
|
};
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1310
|
+
type SupportSessionRequest = {
|
|
1311
|
+
readonly id: string;
|
|
1312
|
+
/** The person to view the app as. */
|
|
1313
|
+
readonly principal: string;
|
|
1314
|
+
/** Defaults to the actor's active tenant. */
|
|
1315
|
+
readonly tenant?: string;
|
|
1316
|
+
/** Required: why the session is needed. */
|
|
1317
|
+
readonly reason: string;
|
|
1318
|
+
/** Defaults to every `readOnlyHint` permission the actor can use. */
|
|
1319
|
+
readonly permissions?: readonly Permission[];
|
|
1320
|
+
/** Seconds the session lasts. Defaults to 3600; at most 86400. */
|
|
1321
|
+
readonly expiresIn?: number;
|
|
1322
|
+
readonly reference?: string;
|
|
1323
|
+
};
|
|
1324
|
+
type SupportSessionDecision = {
|
|
1325
|
+
readonly outcome: "granted";
|
|
1326
|
+
readonly session: SupportSession;
|
|
1327
|
+
} | {
|
|
1328
|
+
readonly outcome: "approval-required";
|
|
1329
|
+
readonly session: SupportSession;
|
|
1330
|
+
/** Bound to the request and the actor; pass it as `approved` to resume. */
|
|
1331
|
+
readonly token: string;
|
|
1332
|
+
} | {
|
|
1333
|
+
readonly outcome: "denied";
|
|
1334
|
+
readonly denials: readonly Denial[];
|
|
1335
|
+
};
|
|
1336
|
+
type DecideSupportSessionOptions = {
|
|
1337
|
+
/** Where the tenant's `supportSessions` policy comes from. */
|
|
1338
|
+
readonly settings?: SettingsSource;
|
|
1339
|
+
/** Approval is required unless this is `false`. */
|
|
1340
|
+
readonly approval?: boolean;
|
|
1341
|
+
/** The `token` of an approval the application consumed for this request. */
|
|
1342
|
+
readonly approved?: string;
|
|
1343
|
+
/** The principal id that approved; required with `approved` and never the actor. */
|
|
1344
|
+
readonly approvedBy?: string;
|
|
1345
|
+
/** The start time; defaults to the clock. */
|
|
1346
|
+
readonly now?: Instant;
|
|
1347
|
+
};
|
|
1348
|
+
/**
|
|
1349
|
+
* Validates an untrusted support-session record and returns a frozen copy
|
|
1350
|
+
* with only the v1 fields, or `undefined`.
|
|
1351
|
+
*/
|
|
1352
|
+
declare function parseSupportSession(input: unknown): SupportSession | undefined;
|
|
1353
|
+
/**
|
|
1354
|
+
* Decides whether the subject of `permdock` may start the support session
|
|
1355
|
+
* in `request`. The actor must be a signed-in person acting for themselves
|
|
1356
|
+
* (`exceeds-creator` otherwise), give a `reason` (`reason-required`), be a
|
|
1357
|
+
* member of the tenant (`tenant-mismatch`) and be able to use every
|
|
1358
|
+
* permission (`exceeds-creator`). Without `permissions` the session gets the
|
|
1359
|
+
* actor's read-only permissions. The tenant's `supportSessions` policy then
|
|
1360
|
+
* applies, and the result is `approval-required` until `approved` carries
|
|
1361
|
+
* its token and `approvedBy` names someone other than the actor.
|
|
1362
|
+
*/
|
|
1363
|
+
/**
|
|
1364
|
+
* Decides whether the subject of `permdock` may start the support session
|
|
1365
|
+
* in `request` and returns the record to sign: a stated reason, membership
|
|
1366
|
+
* of the tenant, the actor's own reach, the tenant's `supportSessions`
|
|
1367
|
+
* policy and approval by someone else. An instance built from a snapshot
|
|
1368
|
+
* denies with `unsupported`.
|
|
1369
|
+
*/
|
|
1370
|
+
declare function decideSupportSession(permdock: InstanceHandle, request: SupportSessionRequest, options?: DecideSupportSessionOptions): Promise<SupportSessionDecision>;
|
|
1182
1371
|
//#endregion
|
|
1183
1372
|
//#region src/core/interfaces.d.ts
|
|
1184
1373
|
type DecisionProvider = {
|
|
@@ -1200,9 +1389,11 @@ type DecisionProvider = {
|
|
|
1200
1389
|
readonly subject: Subject;
|
|
1201
1390
|
}): Promise<readonly string[] | null | undefined>;
|
|
1202
1391
|
};
|
|
1203
|
-
type
|
|
1392
|
+
type CustomRoleSource = {
|
|
1393
|
+
/** Names the implementation in errors and events. */
|
|
1394
|
+
readonly name?: string;
|
|
1204
1395
|
/**
|
|
1205
|
-
* The custom roles of one tenant. `
|
|
1396
|
+
* The custom roles of one tenant. `getPermDock` passes `held`, the role
|
|
1206
1397
|
* names the subject's live memberships hold there, declared or not, so a
|
|
1207
1398
|
* source can skip its read when none of them is a custom role.
|
|
1208
1399
|
*/
|
|
@@ -1220,12 +1411,12 @@ type RoleSource = {
|
|
|
1220
1411
|
}): CustomRole[] | Promise<CustomRole[]>;
|
|
1221
1412
|
};
|
|
1222
1413
|
/**
|
|
1223
|
-
* A `
|
|
1414
|
+
* A `CustomRoleSource` built for the subject the instance serves, for an adapter
|
|
1224
1415
|
* option shared by every request: it gets the resolved subject (principal,
|
|
1225
1416
|
* actor and delegation) and returns that subject's source, or `undefined`
|
|
1226
1417
|
* for none. A throw reads no custom roles and reports `source-threw`.
|
|
1227
1418
|
*/
|
|
1228
|
-
type
|
|
1419
|
+
type CustomRoleSourceFactory = (subject: Subject) => CustomRoleSource | undefined;
|
|
1229
1420
|
/** One member of a scope instance, as `MembershipSource.list` returns it. */
|
|
1230
1421
|
type MemberEntry = {
|
|
1231
1422
|
readonly principal: {
|
|
@@ -1234,6 +1425,8 @@ type MemberEntry = {
|
|
|
1234
1425
|
readonly membership: Membership;
|
|
1235
1426
|
};
|
|
1236
1427
|
type MembershipSource = {
|
|
1428
|
+
/** Names the implementation in errors and events. */
|
|
1429
|
+
readonly name?: string;
|
|
1237
1430
|
membershipsFor(principal: {
|
|
1238
1431
|
readonly id: string;
|
|
1239
1432
|
readonly kind?: string;
|
|
@@ -1306,6 +1499,8 @@ type RelationHolder = HolderPeriod & ({
|
|
|
1306
1499
|
* `relation-unavailable`.
|
|
1307
1500
|
*/
|
|
1308
1501
|
type RelationSource = {
|
|
1502
|
+
/** Names the implementation in errors and events. */
|
|
1503
|
+
readonly name?: string;
|
|
1309
1504
|
/**
|
|
1310
1505
|
* With `through: 'parent'`, the parent chain; with a link name, the one
|
|
1311
1506
|
* instance that link points to (`depth` is then 1).
|
|
@@ -1328,13 +1523,14 @@ type RelationSource = {
|
|
|
1328
1523
|
};
|
|
1329
1524
|
/** Plan and seat names a principal holds in a tenant, from billing (Stripe Entitlements, a table). */
|
|
1330
1525
|
type EntitlementSource = {
|
|
1526
|
+
/** Names the implementation in errors and events. */
|
|
1527
|
+
readonly name?: string;
|
|
1331
1528
|
entitlementsFor(principal: {
|
|
1332
1529
|
readonly id: string;
|
|
1333
1530
|
}, options: {
|
|
1334
1531
|
readonly tenant?: string;
|
|
1335
1532
|
}): string[] | Promise<string[]>;
|
|
1336
1533
|
};
|
|
1337
|
-
declare function memoryEntitlementSource(entries: Readonly<Record<string, readonly string[]>>): EntitlementSource;
|
|
1338
1534
|
type JwtClaims = {
|
|
1339
1535
|
readonly iss?: string;
|
|
1340
1536
|
readonly sub?: string;
|
|
@@ -1360,6 +1556,8 @@ type VerificationFailure = {
|
|
|
1360
1556
|
readonly cause: TokenFailureCause;
|
|
1361
1557
|
};
|
|
1362
1558
|
type TokenVerifier<TClaims extends JwtClaims = JwtClaims> = {
|
|
1559
|
+
/** Names the implementation in errors and events. */
|
|
1560
|
+
readonly name?: string;
|
|
1363
1561
|
verify(token: string, expectations: {
|
|
1364
1562
|
readonly typ?: string | readonly string[];
|
|
1365
1563
|
readonly audience?: string | readonly string[];
|
|
@@ -1368,139 +1566,30 @@ type TokenVerifier<TClaims extends JwtClaims = JwtClaims> = {
|
|
|
1368
1566
|
}): Promise<VerifiedToken<TClaims> | VerificationFailure>;
|
|
1369
1567
|
};
|
|
1370
1568
|
type TokenSigner = {
|
|
1569
|
+
/** Names the implementation in errors and events. */
|
|
1570
|
+
readonly name?: string;
|
|
1371
1571
|
sign(payload: Readonly<Record<string, unknown>>, options: {
|
|
1372
|
-
readonly typ: "permdock
|
|
1572
|
+
readonly typ: "vnd.permdock.snapshot+jwt" | "vnd.permdock.approval+jwt" | "vnd.permdock.policy+jwt" | "vnd.permdock.capability+jwt" | "vnd.permdock.run+jwt" | "vnd.permdock.support-session+jwt" | "vnd.permdock.evidence+jwt" | "at+jwt" | "secevent+jwt";
|
|
1573
|
+
/** `aud`; a signer with no default audience refuses to sign without one. */
|
|
1373
1574
|
readonly audience?: string | readonly string[];
|
|
1575
|
+
/** `exp`, a NumericDate; one hour after `iat` when absent. */
|
|
1374
1576
|
readonly expiresAt?: number;
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
readonly
|
|
1379
|
-
}>;
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
}
|
|
1384
|
-
type Snapshot = {
|
|
1385
|
-
readonly v: 1;
|
|
1386
|
-
readonly issuedAt: number;
|
|
1387
|
-
readonly subject: {
|
|
1388
|
-
readonly principal: {
|
|
1389
|
-
readonly id: string;
|
|
1390
|
-
readonly roles: readonly string[];
|
|
1391
|
-
readonly plans?: readonly string[];
|
|
1392
|
-
readonly tenant?: string;
|
|
1393
|
-
readonly memberships?: readonly Membership[];
|
|
1394
|
-
} | null;
|
|
1395
|
-
readonly delegation?: Subject["delegation"];
|
|
1396
|
-
readonly context: Readonly<Record<string, unknown>>;
|
|
1397
|
-
};
|
|
1398
|
-
/** Roles held in the active tenant, in rank order. */
|
|
1399
|
-
readonly roles: readonly string[];
|
|
1400
|
-
/** The distinct `meta.audience` values of `roles`, in rank order; absent when none has one. */
|
|
1401
|
-
readonly audiences?: readonly string[];
|
|
1402
|
-
readonly grants: readonly SnapshotGrant[];
|
|
1403
|
-
readonly tenants: readonly string[];
|
|
1404
|
-
readonly include?: readonly string[];
|
|
1405
|
-
readonly simulated?: true;
|
|
1406
|
-
readonly expiresAt?: number;
|
|
1407
|
-
readonly vocabulary?: {
|
|
1408
|
-
readonly roles?: Readonly<Record<string, Role>>;
|
|
1409
|
-
readonly plans?: Readonly<Record<string, Plan>>;
|
|
1410
|
-
};
|
|
1411
|
-
/** The policy's scopes in order, so a client checks the row against each membership's instance. */
|
|
1412
|
-
readonly scopes?: readonly SnapshotScope[];
|
|
1413
|
-
/** One entry per tenant in `tenants`: what the subject may hand out there. Absent without tenants. */
|
|
1414
|
-
readonly assignable?: readonly SnapshotAssignable[];
|
|
1415
|
-
/**
|
|
1416
|
-
* Allow grants of held roles that only a plan the subject lacks keeps
|
|
1417
|
-
* from applying; they grant nothing and name the plan a denial asks for.
|
|
1418
|
-
*/
|
|
1419
|
-
readonly notEntitled?: readonly SnapshotNotEntitled[];
|
|
1420
|
-
/**
|
|
1421
|
-
* The row id field per resource whose `id` option is not `id`, for the
|
|
1422
|
-
* grants in `grants`. Absent when every one reads `id`.
|
|
1423
|
-
*/
|
|
1424
|
-
readonly ids?: Readonly<Record<string, string>>;
|
|
1425
|
-
/**
|
|
1426
|
-
* The permission keys the policy's delegations let the actor use for the
|
|
1427
|
-
* principal, sorted; present only when one applies. Outside it a check is
|
|
1428
|
-
* `not-delegated`; inside it a token delegation, when there is one, must
|
|
1429
|
-
* still cover.
|
|
1430
|
-
*/
|
|
1431
|
-
readonly delegated?: readonly string[];
|
|
1432
|
-
};
|
|
1433
|
-
/** A grant the subject would hold on another plan: its permission, role and `to`. */
|
|
1434
|
-
type SnapshotNotEntitled = {
|
|
1435
|
-
readonly permission: string;
|
|
1436
|
-
readonly role: string | null;
|
|
1437
|
-
readonly to: Grantee | readonly Grantee[];
|
|
1438
|
-
};
|
|
1439
|
-
/** One declared scope as a snapshot carries it. */
|
|
1440
|
-
type SnapshotScope = {
|
|
1441
|
-
readonly name: string;
|
|
1442
|
-
readonly key: string;
|
|
1443
|
-
readonly within?: string;
|
|
1444
|
-
/** Resources whose rows this scope's key partitions, from their `memberOf` relations. */
|
|
1445
|
-
readonly resources?: readonly string[];
|
|
1446
|
-
/** Resource name to the field holding this scope's id, for a resource whose field is not `key` (its own `id`). */
|
|
1447
|
-
readonly fields?: Readonly<Record<string, string>>;
|
|
1448
|
-
};
|
|
1449
|
-
/** The declared roles and the custom-role ceiling the subject may assign in one tenant. */
|
|
1450
|
-
type SnapshotAssignable = {
|
|
1451
|
-
readonly tenant: string;
|
|
1452
|
-
readonly roles: readonly string[];
|
|
1453
|
-
readonly permissions: readonly Permission[];
|
|
1454
|
-
/** Permission key to the levels the subject may hand out; only permissions whose resource declares levels. */
|
|
1455
|
-
readonly levels?: Readonly<Record<string, readonly string[]>>;
|
|
1456
|
-
};
|
|
1457
|
-
type SnapshotGrant = {
|
|
1458
|
-
readonly permission: string;
|
|
1459
|
-
readonly effect: "allow" | "deny";
|
|
1460
|
-
readonly role: string | null;
|
|
1461
|
-
readonly to: Grantee | readonly Grantee[];
|
|
1462
|
-
readonly where?: Condition;
|
|
1463
|
-
readonly check?: Condition;
|
|
1464
|
-
readonly approval?: "human" | ApprovalRequirement;
|
|
1465
|
-
/** A scope name or one resource; absent for a global grant. */
|
|
1466
|
-
readonly scope?: string | {
|
|
1467
|
-
readonly resource: string;
|
|
1468
|
-
};
|
|
1469
|
-
readonly membership?: Membership;
|
|
1470
|
-
readonly portable?: false;
|
|
1471
|
-
readonly fields?: readonly string[];
|
|
1472
|
-
/** When the grant applies (Unix seconds, `from` inclusive, `until` exclusive); absent means always. */
|
|
1473
|
-
readonly validity?: GrantValidity;
|
|
1474
|
-
};
|
|
1475
|
-
/**
|
|
1476
|
-
* What a policy grants, as JSON a client builds snapshots from without the
|
|
1477
|
-
* policy: `localSnapshotManifest(policy)` writes it, `localSnapshot` in
|
|
1478
|
-
* `permdock/react-native` reads it.
|
|
1479
|
-
*/
|
|
1480
|
-
type LocalSnapshotManifest = {
|
|
1481
|
-
readonly v: 1;
|
|
1482
|
-
readonly scopes?: readonly SnapshotScope[];
|
|
1483
|
-
readonly vocabulary?: Snapshot["vocabulary"];
|
|
1484
|
-
/** Declared role names; a custom role cannot take one. */
|
|
1485
|
-
readonly roles: readonly string[];
|
|
1486
|
-
/** Declared role names in rank order, when an `assigns` graph ranks them. */
|
|
1487
|
-
readonly rank?: readonly string[];
|
|
1488
|
-
/** Every declared grant, without a membership. */
|
|
1489
|
-
readonly grants: readonly SnapshotGrant[];
|
|
1490
|
-
/** Per custom-role scope (`global` for platform roles): the grants each entry resolves to. */
|
|
1491
|
-
readonly custom: Readonly<Record<string, LocalCustomRoleTable>>;
|
|
1492
|
-
};
|
|
1493
|
-
/** Grants a custom role entry resolves to, held by a placeholder role the client renames. */
|
|
1494
|
-
type LocalCustomRoleTable = {
|
|
1495
|
-
/** `{ permission }` per permission key, and `{ permission, level }` per declared level. */
|
|
1496
|
-
readonly permissions: Readonly<Record<string, {
|
|
1497
|
-
readonly all: readonly SnapshotGrant[];
|
|
1498
|
-
readonly levels?: Readonly<Record<string, readonly SnapshotGrant[]>>;
|
|
1499
|
-
}>>;
|
|
1500
|
-
/** `includes: [role]` per declared role. */
|
|
1501
|
-
readonly includes: Readonly<Record<string, readonly SnapshotGrant[]>>;
|
|
1577
|
+
/** `iat`, a NumericDate: the artefact's issue time. The signer's clock when absent. */
|
|
1578
|
+
readonly issuedAt?: number;
|
|
1579
|
+
/** `jti`: the artefact's id. A fresh UUID when absent. */
|
|
1580
|
+
readonly jti?: string;
|
|
1581
|
+
}): Promise<string>;
|
|
1582
|
+
readonly kid?: string;
|
|
1583
|
+
jwks?(): Promise<{
|
|
1584
|
+
readonly keys: readonly JsonWebKeyLike[];
|
|
1585
|
+
}>;
|
|
1502
1586
|
};
|
|
1587
|
+
type SubjectResolver<TInput, TPrincipal extends Principal = Principal> = (input: TInput, options?: {
|
|
1588
|
+
readonly tenant?: string;
|
|
1589
|
+
}) => Subject<TPrincipal> | Promise<Subject<TPrincipal>>;
|
|
1503
1590
|
type SnapshotSource = {
|
|
1591
|
+
/** Names the implementation in errors and events. */
|
|
1592
|
+
readonly name?: string;
|
|
1504
1593
|
get(): Promise<Snapshot | string> | Snapshot | string;
|
|
1505
1594
|
subscribe?(listener: () => void): () => void;
|
|
1506
1595
|
};
|
|
@@ -1509,8 +1598,10 @@ type LimitConsumeInput = {
|
|
|
1509
1598
|
readonly key: string;
|
|
1510
1599
|
readonly subjectId: string;
|
|
1511
1600
|
readonly count: number;
|
|
1512
|
-
|
|
1513
|
-
readonly
|
|
1601
|
+
/** The window in seconds; windows are aligned to the epoch. */
|
|
1602
|
+
readonly per: number;
|
|
1603
|
+
/** The decision clock; the store reads the clock when absent. */
|
|
1604
|
+
readonly now?: Instant;
|
|
1514
1605
|
/** The active tenant; a quota counts per subject and tenant. */
|
|
1515
1606
|
readonly tenant?: string;
|
|
1516
1607
|
};
|
|
@@ -1518,113 +1609,17 @@ type LimitRemaining = {
|
|
|
1518
1609
|
readonly remaining: number;
|
|
1519
1610
|
};
|
|
1520
1611
|
type LimitStore = {
|
|
1612
|
+
/** Names the implementation in errors and events. */
|
|
1613
|
+
readonly name?: string;
|
|
1521
1614
|
consume(input: LimitConsumeInput): Promise<LimitRemaining> | LimitRemaining;
|
|
1522
1615
|
remaining(input: LimitConsumeInput): LimitRemaining | undefined;
|
|
1523
1616
|
};
|
|
1524
1617
|
type DecisionSink = {
|
|
1618
|
+
/** Names the implementation in errors and events. */
|
|
1619
|
+
readonly name?: string;
|
|
1525
1620
|
write(events: readonly SinkEvent[]): Promise<void> | void;
|
|
1526
1621
|
flush?(): Promise<void>;
|
|
1527
1622
|
};
|
|
1528
|
-
type DirectoryEvent = {
|
|
1529
|
-
readonly type: "directory";
|
|
1530
|
-
readonly at: string;
|
|
1531
|
-
readonly source: "scim";
|
|
1532
|
-
readonly operation: "create" | "replace" | "patch" | "delete";
|
|
1533
|
-
readonly tenant: string;
|
|
1534
|
-
readonly resource: {
|
|
1535
|
-
readonly type: "User" | "Group";
|
|
1536
|
-
readonly id: string;
|
|
1537
|
-
};
|
|
1538
|
-
readonly credential: {
|
|
1539
|
-
readonly kind: "token";
|
|
1540
|
-
} | {
|
|
1541
|
-
readonly kind: "jwt";
|
|
1542
|
-
readonly iss?: string;
|
|
1543
|
-
};
|
|
1544
|
-
readonly active?: boolean;
|
|
1545
|
-
};
|
|
1546
|
-
type MembershipEvent = {
|
|
1547
|
-
readonly type: "membership";
|
|
1548
|
-
readonly at: string;
|
|
1549
|
-
readonly source: string;
|
|
1550
|
-
readonly operation: "added" | "removed" | "changed";
|
|
1551
|
-
readonly principal: {
|
|
1552
|
-
readonly id: string;
|
|
1553
|
-
};
|
|
1554
|
-
/** A declared scope name, or the `tenant` / `team` alias; absent for a global role change. */
|
|
1555
|
-
readonly scope?: string;
|
|
1556
|
-
/** The scope instance; present exactly when `scope` is. */
|
|
1557
|
-
readonly id?: string;
|
|
1558
|
-
/** The id of every ancestor scope, keyed by scope name. */
|
|
1559
|
-
readonly within?: Readonly<Record<string, string>>;
|
|
1560
|
-
readonly via?: string;
|
|
1561
|
-
/** When the membership lapses, in seconds since the epoch. */
|
|
1562
|
-
readonly expiresAt?: number;
|
|
1563
|
-
readonly roles: {
|
|
1564
|
-
readonly added: readonly string[];
|
|
1565
|
-
readonly removed: readonly string[];
|
|
1566
|
-
};
|
|
1567
|
-
readonly by?: {
|
|
1568
|
-
readonly id: string;
|
|
1569
|
-
readonly kind: string;
|
|
1570
|
-
};
|
|
1571
|
-
};
|
|
1572
|
-
/**
|
|
1573
|
-
* An API key's lifecycle: `created`, `rotated` and `revoked` from the
|
|
1574
|
-
* application or a credential store, `used` from `subjectFromApiKey`. A
|
|
1575
|
-
* `used` event carries `sample`, the fraction of uses reported.
|
|
1576
|
-
*/
|
|
1577
|
-
type CredentialEvent = {
|
|
1578
|
-
readonly type: "credential";
|
|
1579
|
-
readonly at: string;
|
|
1580
|
-
readonly source: string;
|
|
1581
|
-
readonly operation: "created" | "used" | "rotated" | "revoked";
|
|
1582
|
-
readonly credential: {
|
|
1583
|
-
readonly id: string;
|
|
1584
|
-
readonly kind: CredentialKind;
|
|
1585
|
-
};
|
|
1586
|
-
readonly principal: {
|
|
1587
|
-
readonly id: string;
|
|
1588
|
-
};
|
|
1589
|
-
readonly tenant?: string;
|
|
1590
|
-
readonly expiresAt?: number;
|
|
1591
|
-
readonly by?: {
|
|
1592
|
-
readonly id: string;
|
|
1593
|
-
readonly kind: string;
|
|
1594
|
-
};
|
|
1595
|
-
readonly sample?: number;
|
|
1596
|
-
};
|
|
1597
|
-
type SinkEvent = DecisionEvent | DirectoryEvent | MembershipEvent | CredentialEvent | AccessEvent;
|
|
1598
|
-
/**
|
|
1599
|
-
* A support-access session lifecycle event: a tenant consented to vendor
|
|
1600
|
-
* support (`started`), the session lapsed (`ended`), or the tenant pulled
|
|
1601
|
-
* consent early (`revoked`). It never decides; it records what happened for
|
|
1602
|
-
* audit and revocation.
|
|
1603
|
-
*/
|
|
1604
|
-
type AccessEvent = {
|
|
1605
|
-
readonly type: "access";
|
|
1606
|
-
readonly at: string;
|
|
1607
|
-
readonly source: string;
|
|
1608
|
-
readonly operation: "started" | "ended" | "revoked";
|
|
1609
|
-
readonly tenant: string;
|
|
1610
|
-
readonly principal: {
|
|
1611
|
-
readonly id: string;
|
|
1612
|
-
};
|
|
1613
|
-
/** The membership kind the session runs under (`support`). */
|
|
1614
|
-
readonly via: string;
|
|
1615
|
-
readonly roles: readonly string[];
|
|
1616
|
-
readonly member?: {
|
|
1617
|
-
readonly group: string;
|
|
1618
|
-
};
|
|
1619
|
-
readonly expiresAt?: number;
|
|
1620
|
-
/** The tenant principal that consented. */
|
|
1621
|
-
readonly grantedBy?: string;
|
|
1622
|
-
readonly reason?: string;
|
|
1623
|
-
readonly actor?: {
|
|
1624
|
-
readonly id: string;
|
|
1625
|
-
readonly kind: string;
|
|
1626
|
-
};
|
|
1627
|
-
};
|
|
1628
1623
|
/**
|
|
1629
1624
|
* Looks up the credential an API key stands for. `null` for a key that is
|
|
1630
1625
|
* malformed, unknown, revoked or whose secret does not match; never throws
|
|
@@ -1632,179 +1627,37 @@ type AccessEvent = {
|
|
|
1632
1627
|
* never core's.
|
|
1633
1628
|
*/
|
|
1634
1629
|
type CredentialVerifier = {
|
|
1630
|
+
/** Names the implementation in errors and events. */
|
|
1631
|
+
readonly name?: string;
|
|
1635
1632
|
verify(secret: string): Credential | null | Promise<Credential | null>;
|
|
1636
1633
|
/**
|
|
1637
|
-
* Records a successful use at `at
|
|
1638
|
-
*
|
|
1639
|
-
*
|
|
1634
|
+
* Records a successful use at `at`, for a `lastUsedAt` column. Called
|
|
1635
|
+
* after a key resolved and not awaited; a throw or a rejection is
|
|
1636
|
+
* ignored, so it never changes the subject.
|
|
1640
1637
|
*/
|
|
1641
|
-
touch?(id: string, at:
|
|
1642
|
-
};
|
|
1643
|
-
type DecisionEvent = {
|
|
1644
|
-
readonly type: "decision";
|
|
1645
|
-
readonly at: string;
|
|
1646
|
-
readonly outcome: "granted" | "denied" | "approval-required";
|
|
1647
|
-
readonly permission: string;
|
|
1648
|
-
readonly scope: string;
|
|
1649
|
-
readonly resource: {
|
|
1650
|
-
readonly type: string;
|
|
1651
|
-
readonly id?: string;
|
|
1652
|
-
};
|
|
1653
|
-
readonly subject: {
|
|
1654
|
-
readonly principal: {
|
|
1655
|
-
readonly id: string;
|
|
1656
|
-
readonly roles: readonly string[];
|
|
1657
|
-
readonly tenant?: string;
|
|
1658
|
-
} | null;
|
|
1659
|
-
readonly actor?: {
|
|
1660
|
-
readonly id: string;
|
|
1661
|
-
readonly kind: string;
|
|
1662
|
-
};
|
|
1663
|
-
readonly delegation?: {
|
|
1664
|
-
readonly scopes?: readonly string[];
|
|
1665
|
-
readonly authorizationDetails?: readonly unknown[];
|
|
1666
|
-
};
|
|
1667
|
-
/** The API key the subject came from. */
|
|
1668
|
-
readonly credential?: {
|
|
1669
|
-
readonly id: string;
|
|
1670
|
-
readonly kind: CredentialKind;
|
|
1671
|
-
};
|
|
1672
|
-
};
|
|
1673
|
-
readonly tenant?: string;
|
|
1674
|
-
readonly membership?: Membership;
|
|
1675
|
-
readonly via?: string | null;
|
|
1676
|
-
readonly matched?: {
|
|
1677
|
-
readonly role: string | null;
|
|
1678
|
-
readonly permission: string;
|
|
1679
|
-
readonly to?: Grantee | readonly Grantee[];
|
|
1680
|
-
readonly hosted?: HostedGrantRef;
|
|
1681
|
-
readonly breakGlass?: true;
|
|
1682
|
-
};
|
|
1683
|
-
/** Purposes of use the caller asserted (`context.purpose`); present when any was. */
|
|
1684
|
-
readonly purpose?: readonly string[];
|
|
1685
|
-
/** The justification the caller supplied (`context.reason`); present when set. */
|
|
1686
|
-
readonly reason?: string;
|
|
1687
|
-
readonly denials?: readonly WireDenial[];
|
|
1688
|
-
readonly alternatives?: readonly string[];
|
|
1689
|
-
readonly token?: string;
|
|
1690
|
-
readonly trusted: boolean;
|
|
1691
|
-
readonly source: "can" | "decide" | "assert" | "filter" | "endpoint" | "adapter" | "approval" | "simulate" | "explain";
|
|
1692
|
-
readonly adapter?: string;
|
|
1693
|
-
readonly phase?: "requested" | "resolved";
|
|
1694
|
-
readonly counts?: {
|
|
1695
|
-
readonly granted: number;
|
|
1696
|
-
readonly denied: number;
|
|
1697
|
-
readonly approvalRequired: number;
|
|
1698
|
-
};
|
|
1699
|
-
};
|
|
1700
|
-
type AuthEvent = {
|
|
1701
|
-
readonly reason: "invalid-token" | "schema" | "unknown-role" | "groups-overflow" | "source-threw";
|
|
1702
|
-
readonly cause?: string;
|
|
1703
|
-
readonly source: string;
|
|
1704
|
-
readonly kid?: string;
|
|
1705
|
-
readonly alg?: string;
|
|
1706
|
-
readonly typ?: string;
|
|
1707
|
-
readonly issuer?: string;
|
|
1708
|
-
readonly requestId?: string;
|
|
1638
|
+
touch?(id: string, at: Instant): void | Promise<void>;
|
|
1709
1639
|
};
|
|
1710
1640
|
/** What one tenant configures for itself. Every field only tightens. */
|
|
1711
1641
|
type TenantSettings = {
|
|
1712
1642
|
/** Rules for API keys created in, or used against, this tenant. */
|
|
1713
1643
|
readonly credentials?: CredentialPolicy;
|
|
1644
|
+
/** Rules for support sessions started in this tenant. */
|
|
1645
|
+
readonly supportSessions?: SupportSessionPolicy;
|
|
1714
1646
|
};
|
|
1715
1647
|
/**
|
|
1716
|
-
* Per-tenant settings, a subject input like `
|
|
1648
|
+
* Per-tenant settings, a subject input like `CustomRoleSource`: they tighten what
|
|
1717
1649
|
* a key may be and never grant. A throw denies.
|
|
1718
1650
|
*/
|
|
1719
1651
|
type SettingsSource = {
|
|
1652
|
+
/** Names the implementation in errors and events. */
|
|
1653
|
+
readonly name?: string;
|
|
1720
1654
|
settingsFor(tenant: string): TenantSettings | undefined | Promise<TenantSettings | undefined>;
|
|
1721
1655
|
};
|
|
1722
|
-
declare function memorySettings(settings: Readonly<Record<string, TenantSettings>>): SettingsSource;
|
|
1723
|
-
/** Memberships keyed by principal id; `tenant` is not a filter, as for a database source. */
|
|
1724
|
-
declare function memoryMembershipSource(entries: Readonly<Record<string, readonly Membership[]>>): MembershipSource;
|
|
1725
|
-
/** A snapshot held in memory; `set` replaces it and notifies every subscriber. */
|
|
1726
|
-
declare function memorySnapshotSource(initial: Snapshot | string): SnapshotSource & {
|
|
1727
|
-
set(snapshot: Snapshot | string): void;
|
|
1728
|
-
};
|
|
1729
|
-
declare function memoryRoleSource(customRoles: readonly CustomRole[]): RoleSource;
|
|
1730
|
-
//#endregion
|
|
1731
|
-
//#region src/conditions/normalize.d.ts
|
|
1732
|
-
type FieldOperator = {
|
|
1733
|
-
readonly eq?: unknown;
|
|
1734
|
-
readonly ne?: unknown;
|
|
1735
|
-
readonly gt?: unknown;
|
|
1736
|
-
readonly gte?: unknown;
|
|
1737
|
-
readonly lt?: unknown;
|
|
1738
|
-
readonly lte?: unknown;
|
|
1739
|
-
readonly contains?: unknown;
|
|
1740
|
-
readonly in?: unknown;
|
|
1741
|
-
readonly notIn?: unknown;
|
|
1742
|
-
readonly isNull?: boolean;
|
|
1743
|
-
};
|
|
1744
|
-
type WhereShorthand<T = Record<string, unknown>> = {
|
|
1745
|
-
readonly and?: readonly WhereShorthand<T>[];
|
|
1746
|
-
readonly or?: readonly WhereShorthand<T>[];
|
|
1747
|
-
readonly not?: WhereShorthand<T>;
|
|
1748
|
-
} & ("subject" extends keyof T ? { readonly [K in keyof T as Exclude<K, "subject">]?: FieldWhere<T[K]>; } & {
|
|
1749
|
-
readonly subject?: SubjectWhere | FieldWhere<T["subject"]>;
|
|
1750
|
-
} : { readonly [K in keyof T]?: FieldWhere<T[K]>; } & {
|
|
1751
|
-
/** Holds only when the resolver checked the session live (`liveSession: true`). */
|
|
1752
|
-
readonly subject?: SubjectWhere;
|
|
1753
|
-
});
|
|
1754
|
-
type SubjectWhere = {
|
|
1755
|
-
readonly session: {
|
|
1756
|
-
readonly live: true;
|
|
1757
|
-
};
|
|
1758
|
-
};
|
|
1759
|
-
type FieldWhere<V> = V | FieldOperator | {
|
|
1760
|
-
readonly ref: string;
|
|
1761
|
-
};
|
|
1762
1656
|
//#endregion
|
|
1763
|
-
//#region src/core/
|
|
1764
|
-
|
|
1765
|
-
type UserApprover = {
|
|
1766
|
-
readonly kind: "user";
|
|
1767
|
-
readonly id: string;
|
|
1768
|
-
};
|
|
1769
|
-
/**
|
|
1770
|
-
* Whoever holds `permission` in the request's tenant, through any role,
|
|
1771
|
-
* custom roles included. Checked only through verdict facts
|
|
1772
|
-
* (`ApprovalVerdict.permissions`) that the handler computes from the
|
|
1773
|
-
* approver's own instance.
|
|
1774
|
-
*/
|
|
1775
|
-
type PermissionApprover = {
|
|
1776
|
-
readonly kind: "permission";
|
|
1777
|
-
readonly permission: string;
|
|
1778
|
-
};
|
|
1779
|
-
/** An approver who matches at least one item; an item that is a list matches when every entry does. */
|
|
1780
|
-
type AnyOfApprover = {
|
|
1781
|
-
readonly kind: "any-of";
|
|
1782
|
-
readonly of: readonly (Approver | readonly Approver[])[];
|
|
1783
|
-
};
|
|
1784
|
-
/**
|
|
1785
|
-
* Who may approve: a subject-only grantee, a `relation()` the approver holds
|
|
1786
|
-
* on the requested row (checked when the verdict is given), `user(id)`,
|
|
1787
|
-
* `holder(permission)`, or `anyOf(...)`. A list (or `allOf(...)`) matches an
|
|
1788
|
-
* approver who satisfies every item.
|
|
1789
|
-
*/
|
|
1790
|
-
type Approver = Grantee | UserApprover | PermissionApprover | AnyOfApprover;
|
|
1791
|
-
type ApproverInput = GranteeInput | UserApprover | PermissionApprover | {
|
|
1792
|
-
readonly kind: "any-of";
|
|
1793
|
-
readonly of: readonly ApproverInput[];
|
|
1794
|
-
} | readonly ApproverInput[];
|
|
1795
|
-
/** Approves when the approver holds `permission` in the request's tenant (any role, custom roles included). */
|
|
1796
|
-
declare function holder(permission: Permission): PermissionApprover;
|
|
1797
|
-
/** Approves when the approver matches any one of `items`. */
|
|
1798
|
-
declare function anyOf(...items: readonly ApproverInput[]): {
|
|
1799
|
-
readonly kind: "any-of";
|
|
1800
|
-
readonly of: readonly ApproverInput[];
|
|
1801
|
-
};
|
|
1802
|
-
/** Approves when the approver matches every one of `items`; the same as a list. */
|
|
1803
|
-
declare function allOf(...items: readonly ApproverInput[]): readonly ApproverInput[];
|
|
1804
|
-
/** A named approver for `approval.by`, matched on the approver's principal id. */
|
|
1805
|
-
declare function user(id: string): UserApprover;
|
|
1657
|
+
//#region src/core/policy-fingerprint.d.ts
|
|
1658
|
+
declare const POLICY_X: unique symbol;
|
|
1806
1659
|
//#endregion
|
|
1807
|
-
//#region src/core/policy.d.ts
|
|
1660
|
+
//#region src/core/policy-types.d.ts
|
|
1808
1661
|
type ClosureContext = {
|
|
1809
1662
|
readonly subject: {
|
|
1810
1663
|
readonly principal: Principal | null;
|
|
@@ -1819,8 +1672,8 @@ type ClosureContext = {
|
|
|
1819
1672
|
type ClosureGrantFn<T = unknown> = (data: T, ctx: ClosureContext) => boolean;
|
|
1820
1673
|
/** Who else may approve once a request has waited `after`. */
|
|
1821
1674
|
type ApprovalEscalation = {
|
|
1822
|
-
/**
|
|
1823
|
-
readonly after:
|
|
1675
|
+
/** Seconds from the request's creation. */
|
|
1676
|
+
readonly after: number;
|
|
1824
1677
|
readonly to: Approver | readonly Approver[];
|
|
1825
1678
|
};
|
|
1826
1679
|
/** One group of approvers; `quorum` distinct approvers of `by` complete it. */
|
|
@@ -1850,8 +1703,8 @@ type ApprovalRequirement = {
|
|
|
1850
1703
|
readonly staleOn?: "resource-change";
|
|
1851
1704
|
/** Distinct approvers a request needs before it is approved under `by`; absent means 1. */
|
|
1852
1705
|
readonly quorum?: number;
|
|
1853
|
-
/**
|
|
1854
|
-
readonly ttl?:
|
|
1706
|
+
/** Seconds a request stays open; the store's default when absent, and never longer than it. */
|
|
1707
|
+
readonly ttl?: number;
|
|
1855
1708
|
readonly escalation?: ApprovalEscalation;
|
|
1856
1709
|
};
|
|
1857
1710
|
type ApprovalOption = "human" | {
|
|
@@ -1861,9 +1714,9 @@ type ApprovalOption = "human" | {
|
|
|
1861
1714
|
readonly stages?: readonly {
|
|
1862
1715
|
readonly by: ApproverInput;
|
|
1863
1716
|
readonly quorum?: number;
|
|
1864
|
-
/** After `after
|
|
1717
|
+
/** After `after` seconds, `to` may approve this stage as well as `by`. */
|
|
1865
1718
|
readonly escalation?: {
|
|
1866
|
-
readonly after:
|
|
1719
|
+
readonly after: number;
|
|
1867
1720
|
readonly to: ApproverInput;
|
|
1868
1721
|
};
|
|
1869
1722
|
}[];
|
|
@@ -1877,11 +1730,11 @@ type ApprovalOption = "human" | {
|
|
|
1877
1730
|
readonly staleOn?: "resource-change";
|
|
1878
1731
|
/** Distinct approvers needed (an integer of at least 1); the same approver counts once. Absent means 1. */
|
|
1879
1732
|
readonly quorum?: number;
|
|
1880
|
-
/**
|
|
1881
|
-
readonly ttl?:
|
|
1882
|
-
/** After `after` (`
|
|
1733
|
+
/** Seconds the request stays open (`1800`); caps the approval store's default. */
|
|
1734
|
+
readonly ttl?: number;
|
|
1735
|
+
/** After `after` seconds (`14_400`), `to` may approve as well as `by`, at any open stage; same kinds as `by`. */
|
|
1883
1736
|
readonly escalation?: {
|
|
1884
|
-
readonly after:
|
|
1737
|
+
readonly after: number;
|
|
1885
1738
|
readonly to: ApproverInput;
|
|
1886
1739
|
};
|
|
1887
1740
|
};
|
|
@@ -1892,7 +1745,8 @@ type ApprovalOption = "human" | {
|
|
|
1892
1745
|
*/
|
|
1893
1746
|
type GrantLimit = {
|
|
1894
1747
|
readonly count: number;
|
|
1895
|
-
|
|
1748
|
+
/** The window in seconds (`3600` for an hour), aligned to the epoch. */
|
|
1749
|
+
readonly per: number;
|
|
1896
1750
|
readonly mode?: "hard" | "soft";
|
|
1897
1751
|
readonly alertAt?: number;
|
|
1898
1752
|
};
|
|
@@ -1911,8 +1765,8 @@ type AssuranceRequirement = {
|
|
|
1911
1765
|
* mints the elevated membership to write.
|
|
1912
1766
|
*/
|
|
1913
1767
|
type ActivationOption = {
|
|
1914
|
-
/** The longest an activation may last,
|
|
1915
|
-
readonly maxDuration?:
|
|
1768
|
+
/** The longest an activation may last, in seconds (`14_400`). */
|
|
1769
|
+
readonly maxDuration?: number;
|
|
1916
1770
|
/** `'required'` denies an activation without a reason. */
|
|
1917
1771
|
readonly justification?: "required" | "optional";
|
|
1918
1772
|
/** When set, `activate` returns `approval-required` before the membership can be written. */
|
|
@@ -1921,7 +1775,7 @@ type ActivationOption = {
|
|
|
1921
1775
|
readonly assurance?: AssuranceRequirement;
|
|
1922
1776
|
};
|
|
1923
1777
|
type ActivationSpec = {
|
|
1924
|
-
readonly maxDuration?:
|
|
1778
|
+
readonly maxDuration?: number;
|
|
1925
1779
|
readonly justification: "required" | "optional";
|
|
1926
1780
|
readonly approval?: "human" | ApprovalRequirement;
|
|
1927
1781
|
readonly assurance?: AssuranceRequirement;
|
|
@@ -1938,8 +1792,8 @@ type BreakGlassOptions = {
|
|
|
1938
1792
|
/** Names of the deny grants this override lifts; every other deny still wins. */
|
|
1939
1793
|
readonly overrides?: readonly string[];
|
|
1940
1794
|
readonly requires?: BreakGlassRequirements;
|
|
1941
|
-
/** The longest a break-glass session may last,
|
|
1942
|
-
readonly maxDuration?:
|
|
1795
|
+
/** The longest a break-glass session may last, in seconds. */
|
|
1796
|
+
readonly maxDuration?: number;
|
|
1943
1797
|
/** Follow-ups the grant owes: each becomes an obligation on the decision. */
|
|
1944
1798
|
readonly obligations?: readonly ("notify" | "review")[];
|
|
1945
1799
|
};
|
|
@@ -1949,14 +1803,14 @@ type BreakGlassSpec = {
|
|
|
1949
1803
|
readonly purpose?: readonly string[];
|
|
1950
1804
|
readonly reason: boolean;
|
|
1951
1805
|
readonly assurance?: AssuranceRequirement;
|
|
1952
|
-
readonly maxDuration?:
|
|
1806
|
+
readonly maxDuration?: number;
|
|
1953
1807
|
readonly obligations: readonly ("notify" | "review")[];
|
|
1954
1808
|
};
|
|
1955
1809
|
/** How a tenant consents to support access, and for how long. */
|
|
1956
1810
|
type SupportConsent = {
|
|
1957
1811
|
readonly by: GranteeInput;
|
|
1958
|
-
/** The durations a tenant owner may pick,
|
|
1959
|
-
readonly durations: readonly
|
|
1812
|
+
/** The durations a tenant owner may pick, in seconds. */
|
|
1813
|
+
readonly durations: readonly number[];
|
|
1960
1814
|
};
|
|
1961
1815
|
type SupportAccessOptions<S extends string = string> = {
|
|
1962
1816
|
/** The role a consented support membership holds. */
|
|
@@ -1976,7 +1830,7 @@ type SupportSpec = {
|
|
|
1976
1830
|
readonly actorRequired: boolean;
|
|
1977
1831
|
readonly consent: {
|
|
1978
1832
|
readonly by: Grantee | readonly Grantee[];
|
|
1979
|
-
readonly durations: readonly
|
|
1833
|
+
readonly durations: readonly number[];
|
|
1980
1834
|
};
|
|
1981
1835
|
readonly group: string;
|
|
1982
1836
|
};
|
|
@@ -1988,15 +1842,26 @@ type GrantOptions<T = Record<string, unknown>> = {
|
|
|
1988
1842
|
readonly limit?: GrantLimit;
|
|
1989
1843
|
readonly reason?: string;
|
|
1990
1844
|
readonly fields?: readonly (keyof T & string)[];
|
|
1991
|
-
/**
|
|
1845
|
+
/**
|
|
1846
|
+
* A stable name for the grant. On a deny, a `breakGlass` override may lift
|
|
1847
|
+
* it; on any grant, it is reported on `decision.matched.name` and on
|
|
1848
|
+
* decision events.
|
|
1849
|
+
*/
|
|
1992
1850
|
readonly name?: string;
|
|
1993
1851
|
readonly group?: string;
|
|
1852
|
+
/** Display text and app data for the grant, reported on `decision.matched.meta`; never read in evaluation. */
|
|
1853
|
+
readonly meta?: GrantMeta;
|
|
1854
|
+
/**
|
|
1855
|
+
* Follow-ups the application owes when this allow grants: each becomes a
|
|
1856
|
+
* `{ kind: 'app', name, detail? }` obligation on the decision. Allows only.
|
|
1857
|
+
*/
|
|
1858
|
+
readonly obligations?: readonly ObligationInput[];
|
|
1994
1859
|
/** Purposes of use (`context.purpose`) that make the grant apply; non-portable. */
|
|
1995
1860
|
readonly purpose?: readonly string[];
|
|
1996
|
-
/** The grant applies from this instant on (RFC 3339
|
|
1997
|
-
readonly validFrom?: string |
|
|
1998
|
-
/** The grant stops applying at this instant (exclusive; RFC 3339
|
|
1999
|
-
readonly validUntil?: string |
|
|
1861
|
+
/** The grant applies from this instant on (RFC 3339 or an `Instant`); before it an allow denies with `inactive-grant` and a deny does not apply. */
|
|
1862
|
+
readonly validFrom?: string | Instant;
|
|
1863
|
+
/** The grant stops applying at this instant (exclusive; RFC 3339 or an `Instant`). */
|
|
1864
|
+
readonly validUntil?: string | Instant;
|
|
2000
1865
|
/**
|
|
2001
1866
|
* An allow on an instance action counts only on rows whose scope instance
|
|
2002
1867
|
* (or the whole app, globally) is one where the subject also holds this
|
|
@@ -2004,6 +1869,17 @@ type GrantOptions<T = Record<string, unknown>> = {
|
|
|
2004
1869
|
*/
|
|
2005
1870
|
readonly requires?: Permission | readonly Permission[];
|
|
2006
1871
|
};
|
|
1872
|
+
/** A grant's metadata. PermDock carries it to decisions, events, snapshots and the catalog and never reads `x`. */
|
|
1873
|
+
type GrantMeta = {
|
|
1874
|
+
readonly description?: string;
|
|
1875
|
+
/** Data the application owns. Plain JSON, checked by `definePolicy(…, { x: { grant } })`. */
|
|
1876
|
+
readonly x?: AppData;
|
|
1877
|
+
};
|
|
1878
|
+
/** An app obligation as declared on an allow: its name, or its name and detail. */
|
|
1879
|
+
type ObligationInput = string | {
|
|
1880
|
+
readonly name: string;
|
|
1881
|
+
readonly detail?: MetaValue;
|
|
1882
|
+
};
|
|
2007
1883
|
/**
|
|
2008
1884
|
* When a grant applies, in Unix seconds. `from` is inclusive, `until`
|
|
2009
1885
|
* exclusive; either may be absent. Portable: `where()` drops an inactive
|
|
@@ -2013,13 +1889,18 @@ type GrantValidity = {
|
|
|
2013
1889
|
readonly from?: number;
|
|
2014
1890
|
readonly until?: number;
|
|
2015
1891
|
};
|
|
1892
|
+
/** A grant's validity in JSON (snapshots, catalogs, `inactive-grant` details): RFC 3339 bounds. */
|
|
1893
|
+
type WireValidity = {
|
|
1894
|
+
readonly from?: string;
|
|
1895
|
+
readonly until?: string;
|
|
1896
|
+
};
|
|
2016
1897
|
/**
|
|
2017
1898
|
* The actor a policy delegation is for: an actor kind, narrowed to one id
|
|
2018
1899
|
* when `id` is set, or to one named client when `client` is set (the name
|
|
2019
1900
|
* the subject resolver gives a verified client id through `clients`).
|
|
2020
1901
|
*/
|
|
2021
1902
|
type DelegationTarget = {
|
|
2022
|
-
readonly kind:
|
|
1903
|
+
readonly kind: ActorKind;
|
|
2023
1904
|
readonly id?: string;
|
|
2024
1905
|
readonly client?: string;
|
|
2025
1906
|
};
|
|
@@ -2043,8 +1924,8 @@ type DelegationInput = {
|
|
|
2043
1924
|
readonly to: ActorGrantee | string | DelegationTarget;
|
|
2044
1925
|
/** The leaves or subtrees the actor may use; a deny grant still applies. */
|
|
2045
1926
|
readonly permissions: readonly (Permission | PermissionTree)[];
|
|
2046
|
-
readonly validFrom?: string |
|
|
2047
|
-
readonly validUntil?: string |
|
|
1927
|
+
readonly validFrom?: string | Instant;
|
|
1928
|
+
readonly validUntil?: string | Instant;
|
|
2048
1929
|
};
|
|
2049
1930
|
/** A declared scope name (or the `tenant` / `team` alias), or the resource a role is held on. */
|
|
2050
1931
|
type RoleScope<S extends string = string> = S | Permission | PermissionTree | readonly (Permission | PermissionTree)[];
|
|
@@ -2091,15 +1972,18 @@ type Grant = {
|
|
|
2091
1972
|
readonly limit?: GrantLimit;
|
|
2092
1973
|
readonly fields?: readonly string[];
|
|
2093
1974
|
readonly scope: GrantScope;
|
|
2094
|
-
/**
|
|
1975
|
+
/** The grant's stable name: a `breakGlass` override lifts a named deny, and `decision.matched.name` reports it. */
|
|
2095
1976
|
readonly name?: string;
|
|
2096
1977
|
readonly group?: string;
|
|
1978
|
+
readonly meta?: GrantMeta;
|
|
1979
|
+
/** App obligations an allow adds to its granted decision. */
|
|
1980
|
+
readonly obligations?: readonly AppObligation[];
|
|
2097
1981
|
/** Purposes of use that make the grant apply (`context.purpose`); non-portable. */
|
|
2098
1982
|
readonly purpose?: readonly string[];
|
|
2099
1983
|
/** Set on a break-glass allow: it overrides named denies and carries obligations. */
|
|
2100
1984
|
readonly breakGlass?: BreakGlassSpec;
|
|
2101
1985
|
/** The membership kind (`via`) this grant applies under; others never match it. */
|
|
2102
|
-
readonly viaOnly?:
|
|
1986
|
+
readonly viaOnly?: MembershipVia;
|
|
2103
1987
|
/** Set only on a grant merged from a hosted policy document. */
|
|
2104
1988
|
readonly hosted?: HostedGrantRef;
|
|
2105
1989
|
/** When the grant applies; absent means always. */
|
|
@@ -2158,6 +2042,8 @@ type Policy<TUser = unknown, TPrincipal extends Principal = Principal, V extends
|
|
|
2158
2042
|
readonly onDenied?: (decision: unknown) => never | void;
|
|
2159
2043
|
readonly fingerprint: string;
|
|
2160
2044
|
readonly resources: ReadonlyMap<string, ResourceNode>;
|
|
2045
|
+
/** The app data schemas `definePolicy` was given; symbol-keyed so freezing the policy leaves the schemas alone. */
|
|
2046
|
+
readonly [POLICY_X]?: PolicyAppDataSchemas;
|
|
2161
2047
|
readonly providers?: readonly DecisionProvider[];
|
|
2162
2048
|
/** Permission keys a hosted policy document may grant or deny; empty by default. */
|
|
2163
2049
|
readonly hostable: readonly string[];
|
|
@@ -2187,23 +2073,21 @@ type PolicyIndex = {
|
|
|
2187
2073
|
/** The grants `grantList` returns, by permission key, in the same order. */
|
|
2188
2074
|
readonly grantsByKey: ReadonlyMap<string, readonly Grant[]>;
|
|
2189
2075
|
};
|
|
2190
|
-
declare function normalizeApproval(approval: ApprovalOption | undefined, permission?: string): Grant["approval"];
|
|
2191
2076
|
type GrantCondition<T, K extends PermissionKind> = K extends "collection" ? Omit<GrantOptions<T>, "where" | "fields"> | ClosureGrantFn<T> : GrantOptions<T> | ClosureGrantFn<T>;
|
|
2192
|
-
declare function allow<T, K extends PermissionKind = PermissionKind>(permission: Permission<string, T, K> | readonly Permission<string, T, K>[], condition?: GrantCondition<T, K>): Omit<Grant, "role" | "scope"> | Omit<Grant, "role" | "scope">[];
|
|
2193
|
-
declare function deny<T, K extends PermissionKind = PermissionKind>(permission: Permission<string, T, K> | readonly Permission<string, T, K>[], condition?: GrantCondition<T, K>): Omit<Grant, "role" | "scope"> | Omit<Grant, "role" | "scope">[];
|
|
2194
|
-
type RoleGrants = readonly (Omit<Grant, "role" | "scope"> | readonly Omit<Grant, "role" | "scope">[])[];
|
|
2195
|
-
/** A role held at a named scope: `on` is checked against `definePolicy({ scopes })`. */
|
|
2196
|
-
declare function role<const S extends string>(name: string | Role, grants: RoleGrants, options: RoleOptions<S> & {
|
|
2197
|
-
readonly on: S;
|
|
2198
|
-
}): RoleBinding<S>;
|
|
2199
|
-
/** A global role, or one held on a resource. */
|
|
2200
|
-
declare function role(name: string | Role, grants: RoleGrants, options?: RoleOptions<never>): RoleBinding<never>;
|
|
2201
|
-
/** Options built at runtime: the scope name is only checked by `definePolicy`. */
|
|
2202
|
-
declare function role(name: string | Role, grants: RoleGrants, options?: RoleOptions): RoleBinding;
|
|
2203
|
-
declare function normalizeAssurance(input: AssuranceRequirement | undefined): AssuranceRequirement | undefined;
|
|
2204
2077
|
/** Resource name to level name to its normalised condition. */
|
|
2205
2078
|
type PolicyLevels = Readonly<Record<string, Readonly<Record<string, Condition>>>>;
|
|
2206
|
-
|
|
2079
|
+
/**
|
|
2080
|
+
* Standard Schemas for the app data a policy carries. `grant` checks every
|
|
2081
|
+
* grant's `meta.x` at `definePolicy` and throws on invalid data; `membership`
|
|
2082
|
+
* checks `Membership.x` as each subject resolves, dropping an invalid `x`
|
|
2083
|
+
* (never the membership) with an `on('auth')` event of reason `schema`.
|
|
2084
|
+
*/
|
|
2085
|
+
type PolicyAppDataSchemas = {
|
|
2086
|
+
readonly grant?: AppDataSchema<unknown>;
|
|
2087
|
+
readonly membership?: AppDataSchema<unknown>;
|
|
2088
|
+
};
|
|
2089
|
+
type PolicyOptions<TUser, TPrincipal extends Principal, S extends PolicyScopesInput = PolicyScopesInput> = {
|
|
2090
|
+
readonly x?: PolicyAppDataSchemas;
|
|
2207
2091
|
readonly roles?: readonly RoleBinding<ScopeNames<S>>[];
|
|
2208
2092
|
readonly grants?: readonly (Omit<Grant, "role" | "scope"> | readonly Omit<Grant, "role" | "scope">[] | Grant)[];
|
|
2209
2093
|
/**
|
|
@@ -2212,8 +2096,8 @@ type DefinePolicyOptions<TUser, TPrincipal extends Principal, S extends PolicySc
|
|
|
2212
2096
|
* the first and second scope.
|
|
2213
2097
|
*/
|
|
2214
2098
|
readonly scopes?: S;
|
|
2215
|
-
|
|
2216
|
-
readonly subject
|
|
2099
|
+
/** Maps the application's user to the principal PermDock decides for; `null` is anonymous. */
|
|
2100
|
+
readonly subject: (user: TUser) => TPrincipal | null;
|
|
2217
2101
|
readonly context?: (user: TUser) => Readonly<Record<string, unknown>> | Promise<Readonly<Record<string, unknown>>>;
|
|
2218
2102
|
readonly validate?: ValidateMode;
|
|
2219
2103
|
readonly onDenied?: (decision: unknown) => never | void;
|
|
@@ -2243,7 +2127,6 @@ type DefinePolicyOptions<TUser, TPrincipal extends Principal, S extends PolicySc
|
|
|
2243
2127
|
*/
|
|
2244
2128
|
readonly oauthScopes?: Readonly<Record<string, readonly (Permission | PermissionTree)[]>>;
|
|
2245
2129
|
};
|
|
2246
|
-
declare function definePolicy<TUser, TPrincipal extends Principal, const Input extends PermissionTree | PolicyVocabulary, const S extends PolicyScopesInput = PolicyScopesInput>(permissions: Input, options: DefinePolicyOptions<TUser, TPrincipal, S>): Policy<TUser, TPrincipal, VocabularyFromInput<Input>>;
|
|
2247
2130
|
type MembershipFixture = {
|
|
2248
2131
|
readonly principal?: string;
|
|
2249
2132
|
readonly tenant?: string;
|
|
@@ -2254,7 +2137,6 @@ type SeparationConflict = {
|
|
|
2254
2137
|
readonly tenant?: string;
|
|
2255
2138
|
readonly roles: readonly [string, string];
|
|
2256
2139
|
};
|
|
2257
|
-
declare function separationConflicts(policy: Policy, memberships: readonly MembershipFixture[]): readonly SeparationConflict[];
|
|
2258
2140
|
type PrincipalOf<P> = P extends Policy<unknown, infer TPrincipal> ? TPrincipal : Principal;
|
|
2259
2141
|
type SubjectOf<P> = {
|
|
2260
2142
|
readonly principal: PrincipalOf<P> | null;
|
|
@@ -2265,4 +2147,4 @@ type SubjectOf<P> = {
|
|
|
2265
2147
|
readonly expiresAt?: number;
|
|
2266
2148
|
};
|
|
2267
2149
|
//#endregion
|
|
2268
|
-
export {
|
|
2150
|
+
export { MemberEntry as $, Delegation as $n, DeliveryFailureCause as $t, PolicyScopes as A, relation as An, CredentialRequest as At, ValidateMode as B, LimitDetail as Bn, LocalSnapshotManifest as Bt, MembershipFixture as C, RelationGrantee as Cn, isConditionRef as Cr, Credential as Ct, PolicyDelegation as D, authenticated as Dn, CredentialPermissionInput as Dt, PolicyAppDataSchemas as E, assurance as En, CredentialPermission as Et, RoleScope as F, DenialDetails as Fn, isFeedId as Ft, CustomRoleSourceFactory as G, TraceSkip as Gn, SnapshotScope as Gt, WireValidity as H, Obligation as Hn, SnapshotAssignable as Ht, SeparationConflict as I, DenialReason as In, parseCredential as It, EntitlementSource as J, Assurance as Jn, AutomationEvent as Jt, DecisionProvider as K, TraceSkipReason as Kn, AccessEvent as Kt, SubjectOf as L, DeniedDecision as Ln, InstanceHandle as Lt, PrincipalOf as M, ApprovalRequiredDecision as Mn, credentialDelegation as Mt, RoleBinding as N, Decision as Nn, credentialPolicyViolation as Nt, PolicyOAuthScope as O, inherit as On, CredentialPolicy as Ot, RoleOptions as P, Denial as Pn, decideCredential as Pt, LimitStore as Q, CustomRoleGrant as Qn, DeliveryEvent as Qt, SupportAccessOptions as R, ExplainedDecision as Rn, Instant as Rt, HostedGrantRef as S, InheritGrantee as Sn, isConditionDate as Sr, ApiKeyPrincipal as St, Policy as T, anyone as Tn, CredentialKind as Tt, CredentialVerifier as U, Quota as Un, SnapshotGrant as Ut, VocabularyFromInput as V, MatchedGrant as Vn, Snapshot as Vt, CustomRoleSource as W, Trace as Wn, SnapshotNotEntitled as Wt, LimitConsumeInput as X, Binding as Xn, DecisionEvent as Xt, JwtClaims as Y, AuthorizationDetail as Yn, CredentialEvent as Yt, LimitRemaining as Z, CustomRole as Zn, DeliveryChannel as Zt, GrantLimit as _, anyOf as _n, RestrictedAncestors as _r, SupportSessionDecision as _t, ApprovalRequirement as a, WireDenial as an, VerifiedClaims as ar, SettingsSource as at, GrantScope as b, Grantee as bn, hasConditionOp as br, decideSupportSession as bt, BreakGlassOptions as c, Scope as cn, MembershipVia as cr, TenantSettings as ct, ClosureContext as d, AnyOfApprover as dn, ConditionValue as dr, TokenVerifier as dt, DirectoryEvent as en, GnapAccess as er, MembershipSource as et, ClosureGrantFn as f, Approver as fn, MemberOfCondition as fr, VerificationFailure as ft, GrantCondition as g, allOf as gn, RelatedHop as gr, SupportSession as gt, Grant as h, UserApprover as hn, RelatedCondition as hr, DecideSupportSessionOptions as ht, ApprovalOption as i, WireDecision as in, Subject as ir, RelationSource as it, PolicyVocabulary as j, AppObligation as jn, DecideCredentialOptions as jt, PolicyOptions as k, plan as kn, CredentialPolicyViolation as kt, BreakGlassRequirements as l, ScopeDeclaration as ln, Condition as lr, TokenFailureCause as lt, DelegationTarget as m, PermissionApprover as mn, OpaqueCondition as mr, WhereCompiler as mt, ApprovalEscalation as n, MembershipEvent as nn, Membership as nr, RelationGroup as nt, ApprovalStage as o, WireDelegation as on, ActorKind as or, SnapshotSource as ot, DelegationInput as p, ApproverInput as pn, MemberOfParent as pr, VerifiedToken as pt, DecisionSink as q, Actor as qn, AuthEvent as qt, ApprovalMode as r, SinkEvent as rn, Principal as rr, RelationHolder as rt, AssuranceRequirement as s, PolicyScopesInput as sn, AdapterId as sr, SubjectResolver as st, ActivationOption as t, EmailCategory as tn, JsonWebKeyLike as tr, RelationChain as tt, BreakGlassSpec as u, ScopeNames as un, ConditionRef as ur, TokenSigner as ut, GrantMeta as v, holder as vn, SqlFunctionArg as vr, SupportSessionPolicy as vt, ObligationInput as w, actor as wn, isSqlFunctionField as wr, CredentialDecision as wt, GrantValidity as x, GranteeInput as xn, isCondition as xr, parseSupportSession as xt, GrantOptions as y, user as yn, SqlFunctionCondition as yr, SupportSessionRequest as yt, SupportConsent as z, GrantedDecision as zn, LocalCustomRoleTable as zt };
|