permdock 0.7.0 → 0.8.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 +1 -3
- package/dist/a2a/index.d.ts +7 -7
- package/dist/a2a/index.js +8 -8
- package/dist/action-result-CL-QCITA.d.ts +19 -0
- package/dist/{adapter-context-CRhqyzCk.js → adapter-context-CIQpQxbE.js} +8 -2
- package/dist/{adoption-scan-D-feE7BE.js → adoption-scan-BLs67P1l.js} +5 -5
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/ai-sdk/index.d.ts +19 -13
- package/dist/ai-sdk/index.js +6 -6
- package/dist/{app-data-MuyzVqX8.js → app-data-UNNm07jV.js} +10 -7
- package/dist/{approval-header-CJACtHkv.js → approval-header-8QV6MU4H.js} +6 -3
- package/dist/{approval-prompt-Dg5LeAcT.js → approval-prompt-B8hQY69x.js} +5 -6
- package/dist/{approval-prompt-K0faOLFp.d.ts → approval-prompt-PYagyQUj.d.ts} +13 -11
- package/dist/approvals/index.d.ts +4 -4
- package/dist/approvals/index.js +6 -6
- package/dist/{approvals-CMRfsbBh.js → approvals-DnIBTuXE.js} +66 -42
- package/dist/{approvers-CqPOLD-o.js → approvers-B4r0N_Uz.js} +8 -2
- package/dist/{arazzo-ClrF3PVb.js → arazzo-3RhGfkAK.js} +2 -2
- package/dist/{arazzo-rdeJ8n1J.js → arazzo-B5-ulWif.js} +6 -6
- package/dist/{args-CC3OwyHW.js → args-0FrVs5EH.js} +14 -7
- package/dist/astro/index.d.ts +30 -12
- package/dist/astro/index.js +2 -2
- package/dist/{audience-BrMs8c4o.js → audience-BAkBDMqn.js} +8 -8
- package/dist/{auth-CscUX8Sy.js → auth--yPyZNgr.js} +19 -7
- package/dist/authzen/index.d.ts +34 -28
- package/dist/authzen/index.js +23 -20
- package/dist/{automation-DOtAFWdy.d.ts → automation-DqEoWHBc.d.ts} +42 -32
- package/dist/{automation-ySsxp_Yp.js → automation-x3KEUusw.js} +22 -21
- package/dist/better-auth/index.d.ts +2 -2
- package/dist/better-auth/index.js +13 -7
- package/dist/better-supabase/index.d.ts +357 -227
- package/dist/better-supabase/index.js +219 -140
- package/dist/{bind-JDuvxjuW.d.ts → bind-Cp2hBHzP.d.ts} +27 -12
- package/dist/{bind-D1nO6fiC.js → bind-D_sZSVA3.js} +22 -10
- package/dist/{body-CH5of8Ne.js → body-CJQwYVa8.js} +3 -3
- package/dist/{body-text-QcXok_SI.js → body-text-DQhcmqdY.js} +8 -4
- package/dist/{boundary-BM8a_P6E.js → boundary-BV3O1eud.js} +8 -2
- package/dist/{boundary-BmHxVH1J.d.ts → boundary-C9ck-3uK.d.ts} +13 -4
- package/dist/{budget-NbEtbJC_.js → budget-BELja5A9.js} +6 -3
- package/dist/{budget-JqcRqyhK.d.ts → budget-hYsPz_yE.d.ts} +6 -3
- package/dist/{build-instance-DxE7czo9.js → build-instance-CNWaYJyr.js} +3 -3
- package/dist/{capability-L7NnfhiE.js → capability-BqX94r07.js} +31 -25
- package/dist/{capability-D4UC9TTW.d.ts → capability-ChuiONQU.d.ts} +41 -29
- package/dist/{casbin-BW9pS47J.js → casbin-H0rKxBx2.js} +16 -8
- package/dist/{casbin-BHijLuHY.js → casbin-cbSbhT_k.js} +2 -2
- package/dist/{casl-CmJlgziS.js → casl-C4OINZHI.js} +2 -2
- package/dist/{casl-UbI8v-Wq.js → casl-CHHoCldP.js} +19 -10
- package/dist/catalog/index.d.ts +51 -30
- package/dist/catalog/index.js +18 -15
- package/dist/{catalog-D69WhFii.js → catalog-BFpz2EmT.js} +20 -19
- package/dist/{catalog-BaMQfQ6Y.js → catalog-DCspHDc8.js} +3 -3
- package/dist/{catalog-doc-CV9s6B1S.js → catalog-doc-DjMKzJp9.js} +28 -14
- package/dist/{catalog-fingerprint-C144oW4M.js → catalog-fingerprint-e6aCWosn.js} +18 -14
- package/dist/catalog-mRQQQhNK.js +1 -0
- package/dist/catalog-operations-Dadrl7Z-.js +60 -0
- package/dist/{challenge-nGWma08S.js → challenge-DImNcR7B.js} +48 -27
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.js +13 -10
- package/dist/chat-sdk/index.d.ts +44 -26
- package/dist/chat-sdk/index.js +17 -17
- package/dist/{checks-BC_0mPIq.js → checks-CGkP3Z7A.js} +4 -1
- package/dist/{claims-map-7oQ3ue4X.js → claims-map-CKkoAAYF.js} +5 -2
- package/dist/{claims-map-Ca-QX8C6.d.ts → claims-map-D1Pb5oRq.d.ts} +8 -5
- package/dist/claude-agent/index.d.ts +6 -6
- package/dist/claude-agent/index.js +6 -3
- package/dist/clerk/index.d.ts +11 -7
- package/dist/clerk/index.js +6 -6
- package/dist/cli/bin.js +4 -4
- package/dist/cli/index.d.ts +82 -7
- package/dist/cli/index.js +6 -6
- package/dist/{clients-C7zLFuWT.d.ts → clients-C_NOET3z.d.ts} +5 -5
- package/dist/{clients-DjU5ABMy.js → clients-DYr3U86j.js} +3 -3
- package/dist/cloud/index.d.ts +84 -52
- package/dist/cloud/index.js +53 -39
- package/dist/{cloud-CO8pYtwr.js → cloud-BFlGMaak.js} +4 -5
- package/dist/{codemod-i4N2BhDc.js → codemod-DLQ9Zpo4.js} +3 -4
- package/dist/{codemod-BP6n8N9L.js → codemod-DWSN2erG.js} +523 -201
- package/dist/collect-B5BL3klN.js +1 -0
- package/dist/{collect-BaWeMjwV.js → collect-B7ZFAJU3.js} +26 -63
- package/dist/{collect-DNm3oKOk.js → collect-Bzv3le0A.js} +4 -5
- package/dist/{compare-pfyVnBjE.js → compare-DTfyUunF.js} +2 -2
- package/dist/compile/index.d.ts +2 -2
- package/dist/compile/index.js +1 -1
- package/dist/{compile-COM2VKuN.d.ts → compile-BFzysW3o.d.ts} +36 -12
- package/dist/{compile-BAEO5bOk.js → compile-EzEMB-7v.js} +77 -33
- package/dist/{completion-BNdVf7X2.js → completion-saoYiRFO.js} +17 -8
- package/dist/config-BwPBfN0t.js +108 -0
- package/dist/{config-DGZzMV1B.js → config-DBeXXmBF.js} +2 -2
- package/dist/{config-report-Cm7UITNA.js → config-report-BipSWA6V.js} +9 -6
- package/dist/config-shape-ykV0Vm2n.js +134 -0
- package/dist/{connection-DjhIJSs2.js → connection-B72dg5Q2.js} +23 -22
- package/dist/{connector-schema-_VCSsdtD.js → connector-schema-CYLQNMYq.js} +3 -2
- package/dist/{context--uM9V3Ui.js → context-BnIzxTNE.js} +4 -3
- package/dist/convex/index.d.ts +13 -7
- package/dist/convex/index.js +9 -6
- package/dist/{core-B5-w6Kw9.js → core-H-mbhpZc.js} +26 -20
- package/dist/{core-CQkE8Esr.d.ts → core-hWIARPDz.d.ts} +49 -22
- package/dist/{create-UTnUVETj.d.ts → create-BSNrVuxh.d.ts} +70 -37
- package/dist/{create-B2-CQqCI.d.ts → create-BVq1lNQE.d.ts} +49 -28
- package/dist/{create-QHuuPw3q.d.ts → create-CM1FciYG.d.ts} +37 -29
- package/dist/{create-Cb86Z8Im.js → create-Cq4Uox0f.js} +10 -7
- package/dist/{create-DJrlhEp9.js → create-_noSrY1T.js} +15 -21
- package/dist/{credential-CIM7wHwA.js → credential-CyyyvCsL.js} +41 -38
- package/dist/{credentials-BpuTwd7a.js → credentials-CdDxp7jN.js} +6 -6
- package/dist/{deciding-columns-DRo2QM6E.js → deciding-columns-NB4wcyBf.js} +2 -2
- package/dist/{delegation-C5rOdTp5.js → delegation-CDB6_keF.js} +31 -22
- package/dist/delivery/index.d.ts +4 -4
- package/dist/delivery/index.js +5 -5
- package/dist/{delivery-rwOKLWRm.js → delivery-BupfvJIV.js} +34 -22
- package/dist/{delivery-event-xX4obB8F.js → delivery-event-JioK5YbS.js} +6 -6
- package/dist/denied-text-CHNlVInN.d.ts +22 -0
- package/dist/{describe-DZlnEtLy.js → describe-Bb4hGK5d.js} +5 -5
- package/dist/{describe-O0SwYIK8.d.ts → describe-ByS9LgHK.d.ts} +5 -5
- package/dist/{device-BARQ8eYG.js → device-BwbJNmb2.js} +11 -8
- package/dist/{diff-Btr1c1Ow.js → diff-CN8IYhC_.js} +2 -2
- package/dist/{diff-DzT-xD13.js → diff-iZWV65nC.js} +22 -13
- package/dist/{digest-B3kc_PgQ.d.ts → digest-8Yx2CchM.d.ts} +3 -3
- package/dist/{doctor-BU1szn63.js → doctor-CHD1M9R5.js} +287 -135
- package/dist/{doctor-BoK_y0KO.js → doctor-D3wo-yuz.js} +4 -4
- package/dist/drizzle/index.d.ts +33 -19
- package/dist/drizzle/index.js +17 -9
- package/dist/elysia/index.d.ts +17 -11
- package/dist/elysia/index.js +5 -5
- package/dist/{errors-BKy0EfhN.js → errors-B6R_lg2a.js} +13 -4
- package/dist/{errors-BWXBMaKK.d.ts → errors-CHwoRRpB.d.ts} +4 -1
- package/dist/{errors-DpP_U6Bf.js → errors-Vpu6rKHl.js} +13 -10
- package/dist/{errors-B_Qg9D3e.d.ts → errors-zi_4T-rx.d.ts} +22 -6
- package/dist/{evaluate-B_oqFbWC.js → evaluate-Dd8Ta0Ie.js} +140 -78
- package/dist/{evaluations-DReoiVBw.js → evaluations-IBceAeKT.js} +40 -19
- package/dist/{evaluations-BCddEOfO.d.ts → evaluations-z8dQFDaN.d.ts} +11 -5
- package/dist/eve/index.d.ts +9 -6
- package/dist/eve/index.js +4 -4
- package/dist/{event-time-CsegxXxB.js → event-time-BGy48400.js} +8 -4
- package/dist/{expiry-D4_YKRKD.js → expiry-6XByK0dm.js} +8 -5
- package/dist/express/index.d.ts +9 -6
- package/dist/express/index.js +9 -6
- package/dist/fastify/index.d.ts +16 -10
- package/dist/fastify/index.js +8 -5
- package/dist/{fetch-adapter-CuhyYwC1.d.ts → fetch-adapter-C1DCvpqV.d.ts} +9 -6
- package/dist/{fetch-adapter-De-u6vhJ.js → fetch-adapter-JL43jD3E.js} +14 -11
- package/dist/fields-D0vUI6dq.js +498 -0
- package/dist/{files-acUbNwWt.js → files-B3AA05f1.js} +8 -5
- package/dist/{files-D_JIzUrP.js → files-BSjrtIHw.js} +11 -4
- package/dist/{fixtures-BTMW6zgU.js → fixtures-A1_sp_tR.js} +15 -6
- package/dist/{flags-aaeRAdiD.js → flags-DXjoTVbS.js} +2 -2
- package/dist/{freeze-CrU8nQeX.js → freeze-jjan0lCv.js} +4 -1
- package/dist/{from-snapshot-Bz469dIh.js → from-snapshot-DCakWRsr.js} +18 -15
- package/dist/gen-B5kvbAoZ.js +58 -0
- package/dist/gen-DWCYcMQM.js +827 -0
- package/dist/{generate-3FNO5P5Q.js → generate-CRVV5V7l.js} +14 -8
- package/dist/generate-CezbCaTI.js +275 -0
- package/dist/{grantee-BrRANrpT.js → grantee-Dke-9rd1.js} +4 -4
- package/dist/{grantee-conditions-C6P1Tvol.js → grantee-conditions-BrYPe-w0.js} +12 -12
- package/dist/{grantee-match-0RtHWQDx.js → grantee-match-7RZZvoT_.js} +12 -6
- package/dist/{graph-sql-B-dsAT6j.d.ts → graph-sql-BwFC4Qjs.d.ts} +3 -3
- package/dist/h3/index.d.ts +10 -7
- package/dist/h3/index.js +3 -3
- package/dist/headers-B9jQxjtW.d.ts +10 -0
- package/dist/{helpers-DY3vXuGs.js → helpers-DJicaG6f.js} +40 -28
- package/dist/hono/index.d.ts +16 -10
- package/dist/hono/index.js +5 -5
- package/dist/{hosted-BmjzxQhp.d.ts → hosted-Cmtxogd0.d.ts} +33 -21
- package/dist/{hosted-XBgU6RGT.js → hosted-D0IzESu_.js} +42 -21
- package/dist/{http-ujKm0JXE.js → http-DH94eh6f.js} +4 -4
- package/dist/{http-BBoKefeS.js → http-DKLXrFGk.js} +13 -7
- package/dist/{http-Ca3Sr5x1.js → http-DOL33cO0.js} +11 -8
- package/dist/{import-Bz0GefWg.js → import-CST57XLp.js} +64 -51
- package/dist/{import-DB2EG_iy.js → import-_YqhhwvX.js} +6 -6
- package/dist/{index-BSfRl0hZ.d.ts → index-B8s204GL.d.ts} +64 -52
- package/dist/{index-DH9DUDEM.d.ts → index-BT5-1VsX.d.ts} +54 -30
- package/dist/{index-BTkwrK7v.d.ts → index-BW_0MZOS.d.ts} +282 -172
- package/dist/{index-CMiPH2Tv.d.ts → index-BhxEUY9J.d.ts} +64 -37
- package/dist/{index-DLwcuCN_.d.ts → index-Bv5iXPqU.d.ts} +51 -30
- package/dist/{index-BE8y3moU.d.ts → index-_9UiQIkt.d.ts} +127 -82
- package/dist/index.d.ts +22 -22
- package/dist/index.js +33 -33
- package/dist/{init-5TXNji88.js → init-Dz_PsHdv.js} +5 -5
- package/dist/{init-B-4t1NzC.js → init-cE3A8aXq.js} +10 -10
- package/dist/{instance-options-CU0YQCLH.d.ts → instance-options-B0KXqTrJ.d.ts} +4 -4
- package/dist/{instance-snapshot-CjcwnEiV.js → instance-snapshot--JWiTrvO.js} +75 -55
- package/dist/{instant-BluqDvyS.js → instant-DK3Iz83e.js} +2 -2
- package/dist/{internals-Dk8A8fX3.js → internals-B3IgHrvo.js} +6 -3
- package/dist/{json-schema-B-vAwlde.js → json-schema-BPGa-RjQ.js} +9 -3
- package/dist/{json-schema-CN_iLFH2.d.ts → json-schema-BfXgnRNT.d.ts} +4 -4
- package/dist/jwt/index.d.ts +57 -27
- package/dist/jwt/index.js +24 -21
- package/dist/{kernel-DVExUwkp.js → kernel-C-fYydV2.js} +32 -23
- package/dist/kysely/index.d.ts +49 -33
- package/dist/kysely/index.js +9 -7
- package/dist/{live-options-BaAFCIiu.js → live-options-BBIT68le.js} +2 -2
- package/dist/{load-DxroEzH1.js → load-DjSU5KXO.js} +6 -6
- package/dist/load-Dm0pSYH3.js +1 -0
- package/dist/{login-ClSJh5t5.js → login-D-8tMqzo.js} +4 -4
- package/dist/{login-WC9HPJpU.js → login-DplQ0s84.js} +16 -9
- package/dist/{manifest-Dv6q4i5s.js → manifest-Cgiq5oqc.js} +49 -38
- package/dist/{manifest-BVhExYhw.d.ts → manifest-CzzWtnAb.d.ts} +126 -31
- package/dist/{manifest-schema-Cv492Qev.js → manifest-schema-2r37XRhD.js} +44 -3
- package/dist/{manifest-B79YuF2T.js → manifest-wg8WkkpD.js} +6 -6
- package/dist/{map-claims-etGIS_Dv.js → map-claims-BNWCJtmP.js} +14 -8
- package/dist/{map-error-BQGyDm_M.js → map-error-pasIGqMT.js} +7 -7
- package/dist/{markers-C6joDI3o.js → markers-BeHZ4x9Q.js} +20 -5
- package/dist/mcp/index.d.ts +114 -61
- package/dist/mcp/index.js +70 -40
- package/dist/{migrate-Dodel0IJ.js → migrate-B7oP_sQU.js} +35 -17
- package/dist/module-values-BJTBdo6y.js +107 -0
- package/dist/nest/index.d.ts +23 -13
- package/dist/nest/index.js +18 -11
- package/dist/next/client.d.ts +5 -2
- package/dist/next/client.js +1 -1
- package/dist/next/index.d.ts +72 -26
- package/dist/next/index.js +110 -6
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +4 -3
- package/dist/node/index.d.ts +5 -5
- package/dist/node/index.js +3 -3
- package/dist/{ocsf-BFp-PZZA.js → ocsf-TcjRBgIs.js} +15 -5
- package/dist/openai/index.d.ts +13 -7
- package/dist/openai/index.js +3 -3
- package/dist/openapi/index.d.ts +51 -30
- package/dist/openapi/index.js +2 -2
- package/dist/{openapi-Ddb4628T.js → openapi-BOsx0xn9.js} +33 -18
- package/dist/{openapi-DMocl1bh.js → openapi-CBZUhA3l.js} +4 -5
- package/dist/{openapi-ztVaux6j.js → openapi-VeHHU2l9.js} +23 -14
- package/dist/{operation-findings-kRcEp8lE.js → operation-findings-CXtFzlKJ.js} +3 -3
- package/dist/{operations-BNLes61x.d.ts → operations-Ci_rT6Uo.d.ts} +10 -7
- package/dist/orpc/index.d.ts +68 -14
- package/dist/orpc/index.js +62 -13
- package/dist/otel/index.d.ts +7 -4
- package/dist/otel/index.js +8 -5
- package/dist/output-files-BHOIlrfD.js +1 -0
- package/dist/{output-files-CCMdcFWb.js → output-files-BIQ_9pIs.js} +29 -17
- package/dist/{output-DgSDLrta.js → output-tkju6U7R.js} +9 -5
- package/dist/ownership-B4L59T9u.js +1054 -0
- package/dist/{parse-Ddhz2xf4.js → parse-1_ZheTW5.js} +16 -13
- package/dist/parse-local-manifest-BQhTlLQS.d.ts +10 -0
- package/dist/{parse-local-manifest-T1Q8X3A2.js → parse-local-manifest-DEiCF4ah.js} +19 -7
- package/dist/{parse-request-D_tUXG6M.js → parse-request-CwCZpyjV.js} +7 -8
- package/dist/{paths-DXSHAMIa.js → paths-CUvURzHp.js} +4 -1
- package/dist/pdp/index.d.ts +9 -6
- package/dist/pdp/index.js +20 -13
- package/dist/{peer-DOzzMfZL.js → peer-C9LvBCcb.js} +1 -1
- package/dist/{peer-12Q5I_RH.js → peer-Q0fuZ6hx.js} +9 -3
- package/dist/{permdock-Dco6dyCK.d.ts → permdock-B6Sf4T_S.d.ts} +253 -129
- package/dist/{permdock-BfWEeMqk.js → permdock-L-_I_3zP.js} +59 -35
- package/dist/{permission-registry-DpPtSKNZ.js → permission-registry-B8tYxPIt.js} +23 -10
- package/dist/{permission-types-DhNEmoRG.d.ts → permission-types-CAY-GU7e.d.ts} +127 -41
- package/dist/{permissions-CoqCOfJ3.d.ts → permissions-Bx6UI8n1.d.ts} +6 -3
- package/dist/{permissions-CyH2MV_B.js → permissions-CVXmRILq.js} +3 -3
- package/dist/{permissions-DArULThq.js → permissions-mDcTWoBs.js} +8 -5
- package/dist/pg-DQTqRrou.js +60 -0
- package/dist/{pins-8ILTftC9.js → pins-nqarl3oE.js} +4 -1
- package/dist/{pkce-5h8NgMQJ.js → pkce-CnmmYqUZ.js} +1 -1
- package/dist/{policy-B7dg_yzu.d.ts → policy-Ba4bDhaj.d.ts} +5 -5
- package/dist/{policy-DaJy4nK4.js → policy-CLQ8__GF.js} +43 -23
- package/dist/{policy-from-catalog-DFWYkNdu.js → policy-from-catalog-CJgOm6aq.js} +28 -25
- package/dist/{policy-module-CTlwMvLI.js → policy-module-xym9fnSq.js} +12 -6
- package/dist/{policy-types-B-F-qAZk.d.ts → policy-types-CCiDRZBH.d.ts} +738 -349
- package/dist/{postgres-store-BL9M_CA1.js → postgres-store-DcyrPS-r.js} +43 -16
- package/dist/{postgrest-r5faDIzD.js → postgrest-D4nuPXIQ.js} +52 -33
- package/dist/{postgrest-CYacM_u7.d.ts → postgrest-DicQyqm-.d.ts} +54 -35
- package/dist/{powersync-53ryOZip.js → powersync-DHNQX06W.js} +127 -69
- package/dist/{powersync-13odBwiM.js → powersync-DXqGuq9A.js} +3 -3
- package/dist/powersync-Djf-zCpB.js +1 -0
- package/dist/preset/index.d.ts +38 -28
- package/dist/preset/index.js +1 -1
- package/dist/{preset-CHTbd-DQ.js → preset-BjLzeFpp.js} +56 -32
- package/dist/{principal-source-pHneukrx.js → principal-source-C6N60GtM.js} +10 -10
- package/dist/prisma/index.d.ts +69 -41
- package/dist/prisma/index.js +21 -17
- package/dist/{problem-CTviyH5L.js → problem-BVLHFK33.js} +41 -21
- package/dist/{problem-details-cn5X30gZ.js → problem-details-CLDgX1KV.js} +13 -4
- package/dist/{problem-types-CJ2325SZ.js → problem-types-DSsRfONQ.js} +4 -1
- package/dist/{prompt-DwtVemER.js → prompt-BYc6drYW.js} +4 -1
- package/dist/protected-action-BE7N_Luo.d.ts +58 -0
- package/dist/protected-action-DUYqb-Ma.js +80 -0
- package/dist/{protected-DXE3cQYg.js → protected-action-QEA8arRB.js} +48 -14
- package/dist/{provider-BQsTYYy0.js → provider-C55OGXJ7.js} +5 -4
- package/dist/{provider-Csk-THAn.d.ts → provider-DXfq5c2d.d.ts} +1 -1
- package/dist/{provider-store-IgqQipCO.js → provider-store-CaTv00tr.js} +13 -9
- package/dist/pull-B65ndFNZ.js +1 -0
- package/dist/{pull-CN5OLxrF.js → pull-CwpGaQSi.js} +12 -11
- package/dist/{push-tVdG8dUL.js → push-DgssgzkK.js} +19 -13
- package/dist/{pushed-policy-BbcY9r_4.d.ts → pushed-policy-D1Eoi6NM.d.ts} +12 -6
- package/dist/{pushed-policy-CmYeSQqq.js → pushed-policy-ITwYKvvH.js} +10 -7
- package/dist/react/index.d.ts +9 -8
- package/dist/react/index.js +7 -6
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react/provider-client.js +1 -1
- package/dist/react-native/index.d.ts +94 -55
- package/dist/react-native/index.js +200 -61
- package/dist/{refs-CNJBiTFo.js → refs-C8BKxc_e.js} +2 -2
- package/dist/{relation-walk-3OyDBF0S.js → relation-walk-DK_gkgL7.js} +12 -9
- package/dist/{relations-BnCWnJGI.js → relations-BxvRvDHK.js} +3 -3
- package/dist/{replay-Du1tJjG7.js → replay-BU09ad4L.js} +1 -1
- package/dist/{replay-DCDD_ZfL.d.ts → replay-DNftIb_R.d.ts} +1 -1
- package/dist/{request-context-BykKLmyE.js → request-context-C25ilqiJ.js} +8 -8
- package/dist/{request-schema-CMreVuFM.js → request-schema-DhX7UbfQ.js} +4 -1
- package/dist/resend/index.d.ts +34 -28
- package/dist/resend/index.js +29 -29
- package/dist/resolve-names-CF7xXLSG.js +201 -0
- package/dist/{resource-relations-D_jw0BFx.js → resource-relations-8-pCScBO.js} +18 -9
- package/dist/{retire-Wj6dkyDE.js → retire-B2xffQgY.js} +15 -6
- package/dist/{revocations-R07lFBnX.d.ts → revocations-BaUXHM1N.d.ts} +6 -3
- package/dist/{rls-CxBZb4rZ.js → rls-CNEH2_BG.js} +299 -124
- package/dist/{rls-Ck_PocSp.js → rls-Ca8Jz9b5.js} +13 -6
- package/dist/{role-builder-C1VJzvcr.js → role-builder-BK2-T6oD.js} +41 -20
- package/dist/{row-conditions-h2HythXQ.js → row-conditions-BAGHOmVq.js} +4 -3
- package/dist/{rpc-Bk1bE-ch.js → rpc-fNqAIqQk.js} +8 -5
- package/dist/{run-uLD2aWuO.js → run-Bz26OTfO.js} +26 -23
- package/dist/run-D-JE8QWb.js +1 -0
- package/dist/{run-ticket-BpNi7BCi.d.ts → run-ticket-DbWI9f99.d.ts} +29 -14
- package/dist/{run-ticket-B5d_63Ma.js → run-ticket-Dv7aF7Dk.js} +9 -9
- package/dist/{runtime-Vif3_-zf.js → runtime-BGnrOkVH.js} +5 -2
- package/dist/{saas-Az_Kz-4D.js → saas-iWnUdwCt.js} +42 -29
- package/dist/{scan-DSljDE1Y.js → scan-DCj1KQfn.js} +1 -1
- package/dist/{schema-B4v0Qrac.js → schema-BOJjqlWL.js} +3 -2
- package/dist/{schema-gIcCx7zM.js → schema-Dst9I9Gs.js} +8 -4
- package/dist/scim/index.d.ts +2 -2
- package/dist/scim/index.js +2 -2
- package/dist/{scim-C7JYhySg.js → scim-D8YupzX1.js} +2 -2
- package/dist/{scim-YNieBO1U.js → scim-jJBJ7g1Z.js} +33 -15
- package/dist/{scopes-BHsc-wp-.js → scopes-0Up_UA2t.js} +41 -23
- package/dist/server/index.d.ts +11 -11
- package/dist/server/index.js +12 -12
- package/dist/{server-Bnga6I50.js → server-3cVlTLde.js} +31 -31
- package/dist/{server-types-C4gZUEZy.d.ts → server-types-CIlpSA2G.d.ts} +81 -46
- package/dist/{sha256-D9ihqmvd.js → sha256-C-4WXKIu.js} +4 -3
- package/dist/{shared-fMKOv8hP.js → shared-Afctg7B0.js} +65 -32
- package/dist/{shared-C8LjUdVU.js → shared-l0oGGetg.js} +9 -6
- package/dist/{signals-D3NcTKUS.js → signals-B1vHR3fN.js} +2 -2
- package/dist/{sink-BEZSlMS_.js → sink-D9_vh372.js} +32 -21
- package/dist/{sink-Cp_Eot9W.d.ts → sink-Dvi7YZG_.d.ts} +44 -20
- package/dist/{skills-Dcjw9_1C.js → skills-Bjj7BNEQ.js} +12 -8
- package/dist/{skills-g_3BS9NC.js → skills-OuoMR49L.js} +3 -3
- package/dist/{snapshot-CbGmYiJx.js → snapshot-CXlzi69u.js} +21 -18
- package/dist/{snapshot-cache-Pahd3IYJ.d.ts → snapshot-cache-BAXZ0KOp.d.ts} +21 -12
- package/dist/{snapshot-cache-DT2Kx1F8.js → snapshot-cache-Bx_4xC_6.js} +14 -11
- package/dist/solid/index.d.ts +55 -16
- package/dist/solid/index.js +46 -12
- package/dist/solid-start/index.d.ts +30 -12
- package/dist/solid-start/index.js +3 -3
- package/dist/{sources-DEEuGb8S.d.ts → sources-B1Os_YUu.d.ts} +126 -53
- package/dist/{sources-B-zYB4GS.js → sources-CMAM-2A3.js} +46 -27
- package/dist/{sql-B96movIM.js → sql-0WjxIp9g.js} +28 -7
- package/dist/{sql-CDEPCA0g.d.ts → sql-B80DFdpG.d.ts} +2 -2
- package/dist/{src-DLFrtrrC.js → src-DZ0l9UAg.js} +190 -100
- package/dist/ssf/index.d.ts +3 -3
- package/dist/ssf/index.js +47 -35
- package/dist/{standard-webhooks-B_qRg0ws.d.ts → standard-webhooks-C-qX4mJW.d.ts} +7 -7
- package/dist/{standard-webhooks-DgFFD-Ga.js → standard-webhooks-D67a3nzk.js} +5 -5
- package/dist/{store-DSP9oGvh.js → store-RNFvaJJv.js} +32 -26
- package/dist/{store-options-B_poyYvg.js → store-options-Dil3lraY.js} +105 -15
- package/dist/stores-C0Kta5Ft.d.ts +59 -0
- package/dist/{stores-BqEuHC05.js → stores-DxZWDXCs.js} +42 -5
- package/dist/{stream-CvdUS9V1.js → stream-CDvF0sJm.js} +5 -5
- package/dist/{stream-2Vwhl7Er.d.ts → stream-ltuLdtTG.d.ts} +4 -3
- package/dist/{style-Ds1gNm77.js → style-DblOtSga.js} +1 -1
- package/dist/{style-Cqo7-73x.js → style-Ds11Hmk4.js} +2 -1
- package/dist/{subject-settings-CkEwrw3W.js → subject-settings-8sH5HlII.js} +8 -4
- package/dist/{row-check-Dt35czLy.d.ts → subject-settings-vNW8qmUH.d.ts} +30 -18
- package/dist/supabase/index.d.ts +48 -38
- package/dist/supabase/index.js +5 -5
- package/dist/supabase/middleware.d.ts +19 -13
- package/dist/supabase/middleware.js +7 -7
- package/dist/{supabase--0aJdLEd.js → supabase-BL1qJzzY.js} +79 -35
- package/dist/{supabase-Bqp7iIY2.js → supabase-D39cuGPt.js} +3 -3
- package/dist/{supabase-hook-Dg0SrQWR.js → supabase-hook-B-yXnzUl.js} +175 -196
- package/dist/supabase-hook-H-MtE9Wd.js +1 -0
- package/dist/{supautils-MESd81bF.js → supautils-BU-pAEpf.js} +166 -47
- package/dist/{support-session-Cna49-3f.js → support-session-BsmPCbz8.js} +21 -21
- package/dist/svelte/PermissionBoundary.svelte +2 -6
- package/dist/svelte/Protected.svelte +2 -8
- package/dist/svelte/index.d.ts +9 -8
- package/dist/svelte/index.js +10 -9
- package/dist/svelte/runtime.d.ts +4 -4
- package/dist/svelte/runtime.js +4 -4
- package/dist/svelte/source.d.ts +9 -8
- package/dist/svelte/source.js +6 -5
- package/dist/sveltekit/index.d.ts +30 -12
- package/dist/sveltekit/index.js +2 -2
- package/dist/{ownership-Z2LpxsGa.js → tables-DeMNEy6V.js} +641 -1104
- package/dist/tanstack-start/index.d.ts +22 -10
- package/dist/tanstack-start/index.js +2 -2
- package/dist/{target-Bw37TFNA.js → target-qdEAnnhU.js} +6 -6
- package/dist/{tenancy-CmeBQ6Nv.js → tenancy-5d1zVBvK.js} +25 -19
- package/dist/terminal/index.d.ts +23 -14
- package/dist/terminal/index.js +17 -20
- package/dist/testing/core.d.ts +1 -1
- package/dist/testing/core.js +1 -1
- package/dist/testing/fixtures/index.d.ts +8 -5
- package/dist/testing/fixtures/index.js +78 -17
- package/dist/testing/index.d.ts +224 -141
- package/dist/testing/index.js +299 -234
- package/dist/testing/saas/index.d.ts +43 -27
- package/dist/testing/saas/index.js +2 -2
- package/dist/testing/saas/permissions.d.ts +1 -1
- package/dist/testing/saas/permissions.js +1 -1
- package/dist/{text-diff-DhITNCnD.js → text-diff-BtfSmdUo.js} +2 -2
- package/dist/{thenable-yD7SabqG.js → thenable-BNSM1U2R.js} +12 -3
- package/dist/{time-DkWjdL98.js → time-nR1JesoH.js} +32 -8
- package/dist/{token-2qYDvXz2.js → token-DC9EQiet.js} +14 -12
- package/dist/{tool-refusal-reAhIzdl.js → tool-refusal-Qpjs_W6M.js} +5 -2
- package/dist/trpc/index.d.ts +11 -8
- package/dist/trpc/index.js +15 -9
- package/dist/type-helpers-BIPIDa6a.d.ts +50 -0
- package/dist/{types-DBHftjgS.d.ts → types-AMJ5qoU_.d.ts} +45 -33
- package/dist/{types-CfiKC5aN.d.ts → types-B2mlGuhW.d.ts} +14 -11
- package/dist/{types-D3A19w4A.d.ts → types-B4uqKDnp.d.ts} +22 -13
- package/dist/{types-CQVEQawv.d.ts → types-BJk0BKRX.d.ts} +24 -14
- package/dist/types-B_d_g7T3.d.ts +262 -0
- package/dist/{types-DC44-hqb.d.ts → types-B_tiYvk8.d.ts} +59 -32
- package/dist/{types-DqzsnlSA.js → types-CcUXciSj.js} +17 -5
- package/dist/{types-BWZybqs9.d.ts → types-DC1Loeh3.d.ts} +381 -202
- package/dist/{types-CIeZcG8v.d.ts → types-DHKPcqzr.d.ts} +2 -2
- package/dist/{types-cTos-H7p.d.ts → types-DjuMBNF9.d.ts} +68 -32
- package/dist/{types-CeIscIKp.d.ts → types-HzqOtvsJ.d.ts} +23 -12
- package/dist/{types-BXMYB7BY.d.ts → types-ZzRGoViD.d.ts} +77 -24
- package/dist/{types-BfVmNJO5.d.ts → types-ah9NlU6j.d.ts} +128 -50
- package/dist/{types-DXmwu78Z.d.ts → types-djVzLlIV.d.ts} +31 -14
- package/dist/{types-g7Oy6Zg4.d.ts → types-yUuPR5Hy.d.ts} +47 -24
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +2 -2
- package/dist/usage-CYeXek0p.js +1 -0
- package/dist/{usage-Bybmck7f.js → usage-CxEzS4ey.js} +50 -26
- package/dist/{usage-CDaLXCfL.js → usage-ab0PdusX.js} +2 -2
- package/dist/{validation-error-ZfUHbKvf.js → validation-error-CYg2kJEw.js} +4 -1
- package/dist/{validation-error-CQpoquwj.d.ts → validation-error-YGg2mXyH.d.ts} +5 -2
- package/dist/{validity-CZ7-y0Cj.js → validity-Buc7w8E9.js} +13 -10
- package/dist/{verifier-DHuh-okk.js → verifier-DUV6pLqZ.js} +10 -4
- package/dist/{verify-pe8rL_Qw.js → verify-DZeqoWu5.js} +148 -487
- package/dist/version-DMQ0dnN5.js +48 -0
- package/dist/version-DizhmD72.js +1 -0
- package/dist/{views-BB8E9dTP.js → views-CD8wuL4Z.js} +19 -6
- package/dist/{vocabulary-Bg3eeT2H.d.ts → vocabulary-DEJ5j4mR.d.ts} +7 -4
- package/dist/vue/index.d.ts +71 -22
- package/dist/vue/index.js +50 -13
- package/dist/{waiter-DwEyouan.d.ts → waiter-Bu9zAlE0.d.ts} +13 -10
- package/dist/{waiter-BGUtGYoU.js → waiter-aBLM63_f.js} +1 -1
- package/dist/{watch-C-4VmFlL.js → watch-Cx_WciLE.js} +8 -8
- package/dist/watch-DB42U1ib.js +1 -0
- package/dist/webmcp/index.d.ts +11 -11
- package/dist/webmcp/index.js +8 -5
- package/dist/{where-scope-wq2coopv.js → where-scope-DlCdCM_8.js} +24 -18
- package/dist/{who-can-BwNsI_Js.js → who-can-rI7dCR9Q.js} +23 -20
- package/dist/workflow/index.d.ts +3 -3
- package/dist/workflow/index.js +13 -13
- package/dist/workflow-sdk/index.d.ts +19 -13
- package/dist/workflow-sdk/index.js +6 -6
- package/dist/{wrap-CiSc_KCq.js → wrap-B2wziJI_.js} +4 -4
- package/dist/{wrap-B6R0cMRL.d.ts → wrap-DlJE3gS_.d.ts} +8 -5
- package/package.json +7 -7
- package/schemas/catalog-v1.json +3 -0
- package/schemas/supabase-manifest-v1.json +33 -1
- package/skills/permdock-credentials/references/tokens-keys-links.md +8 -6
- package/skills/permdock-data/references/queries-and-rls.md +2 -1
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +2 -2
- package/skills/permdock-wire/references/adapters.md +14 -22
- package/dist/catalog-BCCjSAdH.js +0 -1
- package/dist/collect-k_Dulxr5.js +0 -1
- package/dist/config-CoQHDrDi.js +0 -166
- package/dist/denied-text-D4qkEtFz.d.ts +0 -19
- package/dist/fields-ClcQLrVc.js +0 -238
- package/dist/generate-CNU1pIOo.js +0 -171
- package/dist/headers-BIjfMaoC.js +0 -8
- package/dist/headers-CIbDTUTK.d.ts +0 -7
- package/dist/load-DrMHXzgN.js +0 -1
- package/dist/output-files-DPAY7-GX.js +0 -1
- package/dist/package-root-Dk_ETdkp.js +0 -31
- package/dist/parse-local-manifest-e4mdwAKd.d.ts +0 -10
- package/dist/policies-B2lZIurj.js +0 -295
- package/dist/powersync-CExtTLyA.js +0 -1
- package/dist/problem-details-Tcfmj3bV.d.ts +0 -7
- package/dist/protected-BwZYL1X_.d.ts +0 -39
- package/dist/pull-Cty6Ovyu.js +0 -1
- package/dist/run-Bz7DXGEv.js +0 -1
- package/dist/stores-BAZwSYZA.d.ts +0 -31
- package/dist/supabase-hook-DJxC4PoP.js +0 -1
- package/dist/types-CKV71kKh.d.ts +0 -172
- package/dist/usage-y-kBNdqs.js +0 -1
- package/dist/version-CEbQ5UeM.js +0 -18
- package/dist/version-DXkYUISx.js +0 -1
- package/dist/watch-Bd9mx3rd.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as RoleTree, i as RoleMeta, n as PlanTree, r as Role, t as Plan } from "./vocabulary-
|
|
1
|
+
import { M as AppData, N as AppDataSchema, P as MetaValue, b as ResourceNode, d as PermissionKind, f as PermissionTree, k as POLICY_SCOPES, u as Permission } from "./permission-types-CAY-GU7e.js";
|
|
2
|
+
import { a as RoleTree, i as RoleMeta, n as PlanTree, r as Role, t as Plan } from "./vocabulary-DEJ5j4mR.js";
|
|
3
3
|
//#region src/conditions/ast.d.ts
|
|
4
4
|
type ConditionRef = {
|
|
5
5
|
readonly ref: string;
|
|
@@ -64,27 +64,34 @@ type RelatedCondition = {
|
|
|
64
64
|
readonly op: "related";
|
|
65
65
|
readonly resource: string;
|
|
66
66
|
readonly relation: string;
|
|
67
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* The row's own id field, or (with `parent` or `hops`) the field holding the
|
|
69
|
+
* next instance's id.
|
|
70
|
+
*/
|
|
68
71
|
readonly field: string;
|
|
69
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Parent hops walked above the first `resource` instance; `0` reads only that
|
|
74
|
+
* instance.
|
|
75
|
+
*/
|
|
70
76
|
readonly depth: number;
|
|
71
77
|
/** The row is a child of `resource`, reached through `field`. */
|
|
72
78
|
readonly parent?: true;
|
|
73
79
|
/**
|
|
74
|
-
* To-one links from the row to `resource`: `field` points at the first
|
|
75
|
-
*
|
|
76
|
-
*
|
|
80
|
+
* To-one links from the row to `resource`: `field` points at the first hop's
|
|
81
|
+
* resource, each later hop follows `link` on the resource before it, and the
|
|
82
|
+
* last hop's resource is `resource`.
|
|
77
83
|
*/
|
|
78
84
|
readonly hops?: readonly RelatedHop[];
|
|
79
85
|
/**
|
|
80
|
-
* The `resource` instances the subject holds a resource role on; replaces
|
|
81
|
-
*
|
|
86
|
+
* The `resource` instances the subject holds a resource role on; replaces the
|
|
87
|
+
* `relation` lookup (`relation` is then empty).
|
|
82
88
|
*/
|
|
83
89
|
readonly ids?: readonly string[];
|
|
84
90
|
readonly permission?: string;
|
|
85
91
|
/**
|
|
86
92
|
* The row's boolean column that keeps ancestor grants out: with `parent` or
|
|
87
|
-
* `hops`, a restricted row matches nothing; without, the walk stops at the
|
|
93
|
+
* `hops`, a restricted row matches nothing; without, the walk stops at the
|
|
94
|
+
* row.
|
|
88
95
|
*/
|
|
89
96
|
readonly restricted?: string;
|
|
90
97
|
readonly restrictedAncestors?: RestrictedAncestors;
|
|
@@ -117,10 +124,10 @@ type SqlFunctionCondition = {
|
|
|
117
124
|
readonly twin: Condition;
|
|
118
125
|
};
|
|
119
126
|
/**
|
|
120
|
-
* The request's session was checked against the Auth server while the
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
127
|
+
* The request's session was checked against the Auth server while the subject
|
|
128
|
+
* was resolved (`liveSession: true`), not only verified from the token: a
|
|
129
|
+
* revoked session still verifies until `exp`. Written `{ subject: { session: {
|
|
130
|
+
* live: true } } }`.
|
|
124
131
|
*/
|
|
125
132
|
type LiveSessionCondition = {
|
|
126
133
|
readonly op: "liveSession";
|
|
@@ -145,14 +152,18 @@ type FieldOperator = {
|
|
|
145
152
|
readonly notIn?: unknown;
|
|
146
153
|
readonly isNull?: boolean;
|
|
147
154
|
};
|
|
148
|
-
type WhereShorthand<T = Record<string, unknown>> =
|
|
155
|
+
type WhereShorthand<T = Record<string, unknown>> = unknown extends T ? RowWhere<Record<string, unknown>> : RowWhere<T>;
|
|
156
|
+
type RowWhere<T> = {
|
|
149
157
|
readonly and?: readonly WhereShorthand<T>[];
|
|
150
158
|
readonly or?: readonly WhereShorthand<T>[];
|
|
151
159
|
readonly not?: WhereShorthand<T>;
|
|
152
160
|
} & ("subject" extends keyof T ? { readonly [K in keyof T as Exclude<K, "subject">]?: FieldWhere<T[K]>; } & {
|
|
153
161
|
readonly subject?: SubjectWhere | FieldWhere<T["subject"]>;
|
|
154
162
|
} : { readonly [K in keyof T]?: FieldWhere<T[K]>; } & {
|
|
155
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* Holds only when the resolver checked the session live (`liveSession:
|
|
165
|
+
* true`).
|
|
166
|
+
*/
|
|
156
167
|
readonly subject?: SubjectWhere;
|
|
157
168
|
});
|
|
158
169
|
type SubjectWhere = {
|
|
@@ -173,11 +184,20 @@ type FieldWhere<V> = V | FieldOperator | {
|
|
|
173
184
|
* credential kinds, delivery channels) stays closed.
|
|
174
185
|
*/
|
|
175
186
|
type OpenUnion<T extends string> = T | (string & NonNullable<unknown>);
|
|
176
|
-
/**
|
|
187
|
+
/**
|
|
188
|
+
* `actor.kind`: the values PermDock's adapters set, or an integrator's own; a
|
|
189
|
+
* policy delegation matches it by equality.
|
|
190
|
+
*/
|
|
177
191
|
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">;
|
|
178
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* The adapter a decision event names: a PermDock entry, or an integrator's own
|
|
194
|
+
* adapter.
|
|
195
|
+
*/
|
|
179
196
|
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">;
|
|
180
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* How a membership was obtained (`membership.via`); `viaOnly` and support rules
|
|
199
|
+
* match it by equality.
|
|
200
|
+
*/
|
|
181
201
|
type MembershipVia = OpenUnion<"direct" | "contact" | "credential" | "elevated" | "feed" | "link" | "share" | "support" | "support-session" | "scim">;
|
|
182
202
|
//#endregion
|
|
183
203
|
//#region src/core/subject.d.ts
|
|
@@ -210,8 +230,8 @@ type Assurance = {
|
|
|
210
230
|
/**
|
|
211
231
|
* Roles held in one scope instance (`scope` + `id`, with the id of every
|
|
212
232
|
* ancestor scope in `within`) or on one resource (`on`). Evaluation only sees
|
|
213
|
-
* the canonical form; `tenant` / `team` are accepted as input for the first
|
|
214
|
-
*
|
|
233
|
+
* the canonical form; `tenant` / `team` are accepted as input for the first and
|
|
234
|
+
* second declared scope and normalised away.
|
|
215
235
|
*/
|
|
216
236
|
type Membership = {
|
|
217
237
|
readonly scope?: string;
|
|
@@ -222,26 +242,44 @@ type Membership = {
|
|
|
222
242
|
readonly id: string;
|
|
223
243
|
};
|
|
224
244
|
readonly roles: readonly string[];
|
|
225
|
-
/**
|
|
245
|
+
/**
|
|
246
|
+
* Roles the holder may activate here but does not hold; `permdock.activate`
|
|
247
|
+
* writes an elevated membership.
|
|
248
|
+
*/
|
|
226
249
|
readonly eligible?: readonly string[];
|
|
227
250
|
readonly via?: MembershipVia;
|
|
228
251
|
readonly expiresAt?: number;
|
|
229
|
-
/**
|
|
252
|
+
/**
|
|
253
|
+
* The principal id that wrote this membership: who elevated, consented to or
|
|
254
|
+
* granted the access.
|
|
255
|
+
*/
|
|
230
256
|
readonly grantedBy?: string;
|
|
231
|
-
/**
|
|
257
|
+
/**
|
|
258
|
+
* Free text recording why the membership was written: the activation or
|
|
259
|
+
* consent justification.
|
|
260
|
+
*/
|
|
232
261
|
readonly reason?: string;
|
|
233
|
-
/**
|
|
262
|
+
/**
|
|
263
|
+
* A subgroup the holder belongs to inside the instance (`vendor-support`); a
|
|
264
|
+
* `junctionMembershipSource` group column fills it.
|
|
265
|
+
*/
|
|
234
266
|
readonly member?: {
|
|
235
267
|
readonly group: string;
|
|
236
268
|
};
|
|
237
|
-
/**
|
|
269
|
+
/**
|
|
270
|
+
* `idp`: the identity provider (SCIM) owns this membership; the application
|
|
271
|
+
* must not edit it.
|
|
272
|
+
*/
|
|
238
273
|
readonly managedBy?: "idp";
|
|
239
|
-
/**
|
|
274
|
+
/**
|
|
275
|
+
* Seats this membership holds (`dev-mode`, `editor`); `plan()` grantees match
|
|
276
|
+
* them inside the active tenant.
|
|
277
|
+
*/
|
|
240
278
|
readonly entitlements?: readonly string[];
|
|
241
279
|
/**
|
|
242
|
-
* Set when the instance or an ancestor instance is suspended: the
|
|
243
|
-
*
|
|
244
|
-
*
|
|
280
|
+
* Set when the instance or an ancestor instance is suspended: the permission
|
|
281
|
+
* keys the membership still grants (`suspension.scopes.<scope>.keep`). Every
|
|
282
|
+
* other grant, allow or deny, ignores it, and so do role listings.
|
|
245
283
|
*/
|
|
246
284
|
readonly keep?: readonly string[];
|
|
247
285
|
/**
|
|
@@ -257,13 +295,16 @@ type Membership = {
|
|
|
257
295
|
readonly team?: string;
|
|
258
296
|
};
|
|
259
297
|
/**
|
|
260
|
-
* One permission a custom role adds or removes. It names a declared
|
|
261
|
-
*
|
|
298
|
+
* One permission a custom role adds or removes. It names a declared permission
|
|
299
|
+
* key and carries no condition, approval or limit of its own.
|
|
262
300
|
*/
|
|
263
301
|
type CustomRoleGrant = {
|
|
264
302
|
readonly permission: string;
|
|
265
303
|
readonly effect?: "allow" | "deny";
|
|
266
|
-
/**
|
|
304
|
+
/**
|
|
305
|
+
* A level the permission's resource declares (`resource(…, { levels })`);
|
|
306
|
+
* allows only.
|
|
307
|
+
*/
|
|
267
308
|
readonly level?: string;
|
|
268
309
|
};
|
|
269
310
|
type CustomRoleBody = {
|
|
@@ -271,9 +312,9 @@ type CustomRoleBody = {
|
|
|
271
312
|
readonly includes?: readonly string[];
|
|
272
313
|
readonly grants?: readonly CustomRoleGrant[];
|
|
273
314
|
/**
|
|
274
|
-
* Display text and app data, carried onto the role leaf
|
|
275
|
-
*
|
|
276
|
-
*
|
|
315
|
+
* Display text and app data, carried onto the role leaf `assignableRoles()`
|
|
316
|
+
* returns. `x` is checked by the role tree's `defineRoles(…, { x })` schema;
|
|
317
|
+
* an invalid `x` is dropped, not the role.
|
|
277
318
|
*/
|
|
278
319
|
readonly meta?: RoleMeta;
|
|
279
320
|
};
|
|
@@ -281,7 +322,10 @@ type CustomRoleBody = {
|
|
|
281
322
|
type TenantCustomRole = CustomRoleBody & {
|
|
282
323
|
/** The instance of the first scope that owns the role. */
|
|
283
324
|
readonly tenant: string;
|
|
284
|
-
/**
|
|
325
|
+
/**
|
|
326
|
+
* The scope the role is held at; defaults to the first scope. Its ceiling is
|
|
327
|
+
* that scope's assignable roles.
|
|
328
|
+
*/
|
|
285
329
|
readonly scope?: string;
|
|
286
330
|
/** Pins the role to one instance of `scope`. */
|
|
287
331
|
readonly id?: string;
|
|
@@ -302,14 +346,17 @@ type GlobalCustomRole = CustomRoleBody & {
|
|
|
302
346
|
readonly shared?: undefined;
|
|
303
347
|
};
|
|
304
348
|
/**
|
|
305
|
-
* A role the platform defines once for every tenant, held on memberships of
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
349
|
+
* A role the platform defines once for every tenant, held on memberships of its
|
|
350
|
+
* scope in any tenant. Tenant admins assign it but never edit it. Its ceiling
|
|
351
|
+
* is the assignable declared roles of its scope; its name wins over a tenant
|
|
352
|
+
* custom role of the same name.
|
|
309
353
|
*/
|
|
310
354
|
type SharedCustomRole = CustomRoleBody & {
|
|
311
355
|
readonly shared: true;
|
|
312
|
-
/**
|
|
356
|
+
/**
|
|
357
|
+
* The scope the role is held at, never `'global'`; defaults to the first
|
|
358
|
+
* scope.
|
|
359
|
+
*/
|
|
313
360
|
readonly scope?: string;
|
|
314
361
|
readonly tenant?: undefined;
|
|
315
362
|
readonly id?: undefined;
|
|
@@ -320,21 +367,27 @@ type Principal = {
|
|
|
320
367
|
readonly id: string;
|
|
321
368
|
readonly issuer?: string;
|
|
322
369
|
/**
|
|
323
|
-
* `contact`: an external person (a customer contact, a portal user). Only
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
370
|
+
* `contact`: an external person (a customer contact, a portal user). Only its
|
|
371
|
+
* `{ on }` memberships count; it never approves, creates keys or publishes,
|
|
372
|
+
* and is read-only unless a role whose `for` lists `contact` grants the
|
|
373
|
+
* write.
|
|
327
374
|
*/
|
|
328
375
|
readonly kind?: "user" | "service" | "workload" | "link" | "feed" | "contact";
|
|
329
376
|
readonly roles?: readonly string[];
|
|
330
377
|
readonly plans?: readonly string[];
|
|
331
378
|
readonly memberships?: readonly Membership[];
|
|
332
|
-
/**
|
|
379
|
+
/**
|
|
380
|
+
* The token dropped memberships to stay under its size budget; a
|
|
381
|
+
* `claimsFirst` source reads the rest.
|
|
382
|
+
*/
|
|
333
383
|
readonly membershipsTruncated?: boolean;
|
|
334
384
|
/** The authorization version the token was minted at (`authz_ver`). */
|
|
335
385
|
readonly authzVersion?: number;
|
|
336
386
|
readonly tenant?: string;
|
|
337
|
-
/**
|
|
387
|
+
/**
|
|
388
|
+
* Set by core when a requested tenant is not one the subject holds: the
|
|
389
|
+
* denial is then `no-membership`, not `no-tenant`. Never read from a token.
|
|
390
|
+
*/
|
|
338
391
|
readonly unheldTenant?: string;
|
|
339
392
|
readonly assurance?: Assurance;
|
|
340
393
|
readonly binding?: Binding;
|
|
@@ -344,9 +397,16 @@ type Actor = {
|
|
|
344
397
|
readonly id: string;
|
|
345
398
|
readonly kind: ActorKind;
|
|
346
399
|
readonly binding?: Binding;
|
|
347
|
-
/**
|
|
400
|
+
/**
|
|
401
|
+
* `true` denies every permission without `readOnlyHint` (`not-delegated`),
|
|
402
|
+
* with or without a policy delegation.
|
|
403
|
+
*/
|
|
348
404
|
readonly readOnly?: boolean;
|
|
349
|
-
/**
|
|
405
|
+
/**
|
|
406
|
+
* The stable name the application gives this OAuth client (`ClientNames`),
|
|
407
|
+
* set by the subject resolver from the verified client id; policy delegations
|
|
408
|
+
* match it with `to: { kind, client }`.
|
|
409
|
+
*/
|
|
350
410
|
readonly client?: string;
|
|
351
411
|
readonly [key: string]: unknown;
|
|
352
412
|
};
|
|
@@ -369,7 +429,10 @@ type Subject<TPrincipal extends Principal = Principal> = {
|
|
|
369
429
|
readonly context: Readonly<Record<string, unknown>>;
|
|
370
430
|
readonly session?: string;
|
|
371
431
|
readonly expiresAt?: number;
|
|
372
|
-
/**
|
|
432
|
+
/**
|
|
433
|
+
* The token's memberships are behind the source's authorization version:
|
|
434
|
+
* `fresh` permissions deny.
|
|
435
|
+
*/
|
|
373
436
|
readonly stale?: true;
|
|
374
437
|
/**
|
|
375
438
|
* The resolver checked the session against the Auth server for this request
|
|
@@ -381,7 +444,10 @@ type Subject<TPrincipal extends Principal = Principal> = {
|
|
|
381
444
|
//#endregion
|
|
382
445
|
//#region src/core/decision.d.ts
|
|
383
446
|
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" | "no-tenant" | "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";
|
|
384
|
-
/**
|
|
447
|
+
/**
|
|
448
|
+
* The `detail` each denial reason carries, where PermDock sets a structured
|
|
449
|
+
* one.
|
|
450
|
+
*/
|
|
385
451
|
type DenialDetails = {
|
|
386
452
|
readonly limit: LimitDetail;
|
|
387
453
|
/** The window the inactive allow applies in. */
|
|
@@ -413,18 +479,21 @@ type MatchedGrant = {
|
|
|
413
479
|
readonly check?: Grant["check"];
|
|
414
480
|
readonly approval?: "human" | ApprovalRequirement;
|
|
415
481
|
readonly provider?: string;
|
|
416
|
-
/**
|
|
482
|
+
/**
|
|
483
|
+
* The hosted policy document fingerprint and grant id, when a hosted grant
|
|
484
|
+
* matched.
|
|
485
|
+
*/
|
|
417
486
|
readonly hosted?: HostedGrantRef;
|
|
418
487
|
/** A break-glass grant overrode a matching deny. */
|
|
419
488
|
readonly breakGlass?: true;
|
|
420
489
|
};
|
|
421
490
|
/**
|
|
422
491
|
* Something the caller owes alongside a granted action. `over-limit`: a soft
|
|
423
|
-
* `limit` was past its count; `near-limit`: usage reached `alertAt`.
|
|
424
|
-
* `
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
492
|
+
* `limit` was past its count; `near-limit`: usage reached `alertAt`. `notify` /
|
|
493
|
+
* `review`: a break-glass grant's declared follow-ups. `justify`: the
|
|
494
|
+
* break-glass reason, carried so audit records why. `app`: a follow-up the
|
|
495
|
+
* application declared on the grant (`allow(p, { obligations })`); PermDock
|
|
496
|
+
* carries it and never acts on it.
|
|
428
497
|
*/
|
|
429
498
|
type Obligation = {
|
|
430
499
|
readonly kind: "over-limit" | "near-limit" | "notify" | "review";
|
|
@@ -445,8 +514,8 @@ type Quota = {
|
|
|
445
514
|
readonly resetsAt: string;
|
|
446
515
|
};
|
|
447
516
|
/**
|
|
448
|
-
* The `detail` of a `limit` denial: the grant's `count`, its `per` window
|
|
449
|
-
*
|
|
517
|
+
* The `detail` of a `limit` denial: the grant's `count`, its `per` window in
|
|
518
|
+
* seconds and when the window resets (RFC 3339).
|
|
450
519
|
*/
|
|
451
520
|
type LimitDetail = {
|
|
452
521
|
readonly count: number;
|
|
@@ -454,14 +523,13 @@ type LimitDetail = {
|
|
|
454
523
|
readonly resetsAt: string;
|
|
455
524
|
};
|
|
456
525
|
/**
|
|
457
|
-
* Why a candidate grant for the permission was passed over before its
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
* asserted purpose).
|
|
526
|
+
* Why a candidate grant for the permission was passed over before its condition
|
|
527
|
+
* ran: `via-only` (the subject holds no membership of its kind), `purpose` (no
|
|
528
|
+
* asserted purpose it lists), `field` (its `fields` do not cover the requested
|
|
529
|
+
* field), `grantee` (its `to` did not match and added no denial), `role` (a
|
|
530
|
+
* role it names is not held), `validity` (a deny outside its `validFrom` /
|
|
531
|
+
* `validUntil`; an inactive allow adds an `inactive-grant` denial instead),
|
|
532
|
+
* `break-glass-inactive` (a break-glass grant with no asserted purpose).
|
|
465
533
|
*/
|
|
466
534
|
type TraceSkipReason = "via-only" | "purpose" | "field" | "grantee" | "role" | "validity" | "unknown-level" | "break-glass-inactive";
|
|
467
535
|
type TraceSkip = {
|
|
@@ -469,15 +537,18 @@ type TraceSkip = {
|
|
|
469
537
|
readonly permission: string;
|
|
470
538
|
readonly effect: "allow" | "deny";
|
|
471
539
|
readonly why: TraceSkipReason;
|
|
472
|
-
/**
|
|
540
|
+
/**
|
|
541
|
+
* The level a custom role names that its resource does not declare, for
|
|
542
|
+
* `unknown-level`.
|
|
543
|
+
*/
|
|
473
544
|
readonly level?: string;
|
|
474
545
|
};
|
|
475
546
|
/**
|
|
476
|
-
* What `explain` saw: how many candidate grants it examined before the
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
547
|
+
* What `explain` saw: how many candidate grants it examined before the outcome,
|
|
548
|
+
* which allows matched (including the ones a deny overrode), which denies
|
|
549
|
+
* matched, and which grants it passed over. `denies[0]` is the deny that
|
|
550
|
+
* produced a `deny` outcome, or the deny a break-glass grant lifted. Pure local
|
|
551
|
+
* computation; never on a decision event.
|
|
481
552
|
*/
|
|
482
553
|
type Trace = {
|
|
483
554
|
readonly evaluated: number;
|
|
@@ -504,8 +575,8 @@ type GrantedDecision = {
|
|
|
504
575
|
type DeniedDecision = {
|
|
505
576
|
readonly outcome: "denied";
|
|
506
577
|
/**
|
|
507
|
-
* The key of the permission that was checked. Absent on a denial for a
|
|
508
|
-
*
|
|
578
|
+
* The key of the permission that was checked. Absent on a denial for a check
|
|
579
|
+
* that named no declared permission.
|
|
509
580
|
*/
|
|
510
581
|
readonly permission?: string;
|
|
511
582
|
readonly denials: readonly Denial[];
|
|
@@ -552,7 +623,10 @@ type RelationGrantee = {
|
|
|
552
623
|
* to `resource`, then walk its parents only when `depth` is set.
|
|
553
624
|
*/
|
|
554
625
|
readonly through?: "parent" | readonly string[];
|
|
555
|
-
/**
|
|
626
|
+
/**
|
|
627
|
+
* Parent hops walked above the first `resource` instance; absent means
|
|
628
|
+
* `DEFAULT_RELATION_DEPTH` for `'parent'` and `0` for links.
|
|
629
|
+
*/
|
|
556
630
|
readonly depth?: number;
|
|
557
631
|
};
|
|
558
632
|
type PlanGrantee = {
|
|
@@ -601,23 +675,26 @@ type UserApprover = {
|
|
|
601
675
|
readonly id: string;
|
|
602
676
|
};
|
|
603
677
|
/**
|
|
604
|
-
* Whoever holds `permission` in the request's tenant, through any role,
|
|
605
|
-
*
|
|
606
|
-
* (`ApprovalVerdict.permissions`) that the handler computes from the
|
|
607
|
-
*
|
|
678
|
+
* Whoever holds `permission` in the request's tenant, through any role, custom
|
|
679
|
+
* roles included. Checked only through verdict facts
|
|
680
|
+
* (`ApprovalVerdict.permissions`) that the handler computes from the approver's
|
|
681
|
+
* own instance.
|
|
608
682
|
*/
|
|
609
683
|
type PermissionApprover = {
|
|
610
684
|
readonly kind: "permission";
|
|
611
685
|
readonly permission: string;
|
|
612
686
|
};
|
|
613
|
-
/**
|
|
687
|
+
/**
|
|
688
|
+
* An approver who matches at least one item; an item that is a list matches
|
|
689
|
+
* when every entry does.
|
|
690
|
+
*/
|
|
614
691
|
type AnyOfApprover = {
|
|
615
692
|
readonly kind: "any-of";
|
|
616
693
|
readonly of: readonly (Approver | readonly Approver[])[];
|
|
617
694
|
};
|
|
618
695
|
/**
|
|
619
|
-
* Who may approve: a subject-only grantee, a `relation()` the approver holds
|
|
620
|
-
*
|
|
696
|
+
* Who may approve: a subject-only grantee, a `relation()` the approver holds on
|
|
697
|
+
* the requested row (checked when the verdict is given), `user(id)`,
|
|
621
698
|
* `holder(permission)`, or `anyOf(...)`. A list (or `allOf(...)`) matches an
|
|
622
699
|
* approver who satisfies every item.
|
|
623
700
|
*/
|
|
@@ -626,7 +703,10 @@ type ApproverInput = GranteeInput | UserApprover | PermissionApprover | {
|
|
|
626
703
|
readonly kind: "any-of";
|
|
627
704
|
readonly of: readonly ApproverInput[];
|
|
628
705
|
} | readonly ApproverInput[];
|
|
629
|
-
/**
|
|
706
|
+
/**
|
|
707
|
+
* Approves when the approver holds `permission` in the request's tenant (any
|
|
708
|
+
* role, custom roles included).
|
|
709
|
+
*/
|
|
630
710
|
declare function holder(permission: Permission): PermissionApprover;
|
|
631
711
|
/** Approves when the approver matches any one of `items`. */
|
|
632
712
|
declare function anyOf(...items: readonly ApproverInput[]): {
|
|
@@ -639,29 +719,35 @@ declare function allOf(...items: readonly ApproverInput[]): readonly ApproverInp
|
|
|
639
719
|
declare function user(id: string): UserApprover;
|
|
640
720
|
//#endregion
|
|
641
721
|
//#region src/core/scopes.d.ts
|
|
642
|
-
/**
|
|
722
|
+
/**
|
|
723
|
+
* One entry of `definePolicy({ scopes })`: the row field holding the scope id,
|
|
724
|
+
* and its parent scope.
|
|
725
|
+
*/
|
|
643
726
|
type ScopeDeclaration = {
|
|
644
727
|
readonly key: string;
|
|
645
728
|
readonly within?: string;
|
|
646
729
|
};
|
|
647
730
|
type PolicyScopesInput = Readonly<Record<string, ScopeDeclaration>>;
|
|
648
731
|
/**
|
|
649
|
-
* A declared scope, in declaration order. `key` is absent only on the
|
|
650
|
-
*
|
|
732
|
+
* A declared scope, in declaration order. `key` is absent only on the implicit
|
|
733
|
+
* `tenant` / `team` pair of a policy that declares no scopes.
|
|
651
734
|
*/
|
|
652
735
|
type Scope = {
|
|
653
736
|
readonly name: string;
|
|
654
737
|
readonly key?: string;
|
|
655
738
|
readonly within?: string;
|
|
656
739
|
};
|
|
657
|
-
/**
|
|
740
|
+
/**
|
|
741
|
+
* The names `role(..., { on })`, `memberOf` and memberships may use: declared
|
|
742
|
+
* names plus the aliases.
|
|
743
|
+
*/
|
|
658
744
|
type ScopeNames<S> = [S] extends [PolicyScopesInput] ? string extends keyof S ? string : (keyof S & string) | "tenant" | "team" : string;
|
|
659
745
|
//#endregion
|
|
660
746
|
//#region src/core/wire-delegation.d.ts
|
|
661
747
|
/**
|
|
662
|
-
* A delegation as every PermDock wire form carries it: OAuth `scope`
|
|
663
|
-
*
|
|
664
|
-
*
|
|
748
|
+
* A delegation as every PermDock wire form carries it: OAuth `scope` (RFC 6749,
|
|
749
|
+
* space-separated) and RFC 9396 `authorization_details`. An empty `scope` is an
|
|
750
|
+
* empty scope list, which delegates nothing.
|
|
665
751
|
*/
|
|
666
752
|
type WireDelegation = {
|
|
667
753
|
readonly scope?: string;
|
|
@@ -672,9 +758,9 @@ type WireDelegation = {
|
|
|
672
758
|
//#region src/core/wire-denial.d.ts
|
|
673
759
|
/**
|
|
674
760
|
* A denial as it leaves the process: in a decision event, a Problem Details
|
|
675
|
-
* body, an MCP or WebMCP refusal and the decision endpoint. `detail` is a
|
|
676
|
-
*
|
|
677
|
-
*
|
|
761
|
+
* body, an MCP or WebMCP refusal and the decision endpoint. `detail` is a JSON
|
|
762
|
+
* value (a string, or `LimitDetail` on `limit`); what a closure threw and a
|
|
763
|
+
* validation error stay in process.
|
|
678
764
|
*/
|
|
679
765
|
type WireDenial = {
|
|
680
766
|
readonly role: string | null;
|
|
@@ -682,7 +768,10 @@ type WireDenial = {
|
|
|
682
768
|
readonly to?: Grantee | readonly Grantee[];
|
|
683
769
|
readonly detail?: unknown;
|
|
684
770
|
};
|
|
685
|
-
/**
|
|
771
|
+
/**
|
|
772
|
+
* A `Decision` whose denials are `WireDenial`s, as the decision endpoint sends
|
|
773
|
+
* it.
|
|
774
|
+
*/
|
|
686
775
|
type WireDecision = GrantedDecision | ApprovalRequiredDecision | (Omit<DeniedDecision, "denials"> & {
|
|
687
776
|
readonly denials: readonly WireDenial[];
|
|
688
777
|
});
|
|
@@ -706,7 +795,10 @@ type DirectoryEvent = {
|
|
|
706
795
|
readonly iss?: string;
|
|
707
796
|
};
|
|
708
797
|
readonly active?: boolean;
|
|
709
|
-
/**
|
|
798
|
+
/**
|
|
799
|
+
* The application's own data, set where the event is built; plain JSON, never
|
|
800
|
+
* read by a decision.
|
|
801
|
+
*/
|
|
710
802
|
readonly x?: AppData;
|
|
711
803
|
};
|
|
712
804
|
type MembershipEvent = {
|
|
@@ -717,7 +809,10 @@ type MembershipEvent = {
|
|
|
717
809
|
readonly principal: {
|
|
718
810
|
readonly id: string;
|
|
719
811
|
};
|
|
720
|
-
/**
|
|
812
|
+
/**
|
|
813
|
+
* A declared scope name, or the `tenant` / `team` alias; absent for a global
|
|
814
|
+
* role change.
|
|
815
|
+
*/
|
|
721
816
|
readonly scope?: string;
|
|
722
817
|
/** The scope instance; present exactly when `scope` is. */
|
|
723
818
|
readonly id?: string;
|
|
@@ -734,13 +829,16 @@ type MembershipEvent = {
|
|
|
734
829
|
readonly id: string;
|
|
735
830
|
readonly kind: string;
|
|
736
831
|
};
|
|
737
|
-
/**
|
|
832
|
+
/**
|
|
833
|
+
* The application's own data, set where the event is built; plain JSON, never
|
|
834
|
+
* read by a decision.
|
|
835
|
+
*/
|
|
738
836
|
readonly x?: AppData;
|
|
739
837
|
};
|
|
740
838
|
/**
|
|
741
839
|
* An API key's lifecycle: `created`, `rotated` and `revoked` from the
|
|
742
|
-
* application or a credential store, `used` from `subjectFromApiKey`. A
|
|
743
|
-
*
|
|
840
|
+
* application or a credential store, `used` from `subjectFromApiKey`. A `used`
|
|
841
|
+
* event carries `sample`, the fraction of uses reported.
|
|
744
842
|
*/
|
|
745
843
|
type CredentialEvent = {
|
|
746
844
|
readonly type: "credential";
|
|
@@ -762,7 +860,10 @@ type CredentialEvent = {
|
|
|
762
860
|
readonly kind: string;
|
|
763
861
|
};
|
|
764
862
|
readonly sample?: number;
|
|
765
|
-
/**
|
|
863
|
+
/**
|
|
864
|
+
* The application's own data, set where the event is built; plain JSON, never
|
|
865
|
+
* read by a decision.
|
|
866
|
+
*/
|
|
766
867
|
readonly x?: AppData;
|
|
767
868
|
};
|
|
768
869
|
/**
|
|
@@ -798,7 +899,10 @@ type AutomationEvent = {
|
|
|
798
899
|
readonly id: string;
|
|
799
900
|
readonly kind: string;
|
|
800
901
|
};
|
|
801
|
-
/**
|
|
902
|
+
/**
|
|
903
|
+
* The application's own data, set where the event is built; plain JSON, never
|
|
904
|
+
* read by a decision.
|
|
905
|
+
*/
|
|
802
906
|
readonly x?: AppData;
|
|
803
907
|
};
|
|
804
908
|
type SinkEvent = DecisionEvent | DirectoryEvent | MembershipEvent | CredentialEvent | AccessEvent | AutomationEvent | DeliveryEvent;
|
|
@@ -807,14 +911,14 @@ type DeliveryChannel = "email" | "chat" | "webhook";
|
|
|
807
911
|
/** What an email is for; only `notification` mail carries `List-Unsubscribe`. */
|
|
808
912
|
type EmailCategory = "transactional" | "notification" | "security" | "approval";
|
|
809
913
|
/**
|
|
810
|
-
* Why a delivery failed. `denied` and `unlinked` are the router's refusals of
|
|
811
|
-
*
|
|
914
|
+
* Why a delivery failed. `denied` and `unlinked` are the router's refusals of a
|
|
915
|
+
* recipient; the rest come from a transport or a provider webhook.
|
|
812
916
|
*/
|
|
813
917
|
type DeliveryFailureCause = "denied" | "unlinked" | "no-transport" | "no-message" | "invalid-recipient" | "invalid-message" | "rate-limited" | "quota-exceeded" | "unauthorized" | "unavailable" | "suppressed" | "rejected";
|
|
814
918
|
/**
|
|
815
919
|
* One recipient's delivery: `sent` when a transport accepted it, then
|
|
816
|
-
* `delivered`, `bounced` or `complained` from the provider, or `failed`.
|
|
817
|
-
*
|
|
920
|
+
* `delivered`, `bounced` or `complained` from the provider, or `failed`. It
|
|
921
|
+
* carries no address, only the principal the router checked.
|
|
818
922
|
*/
|
|
819
923
|
type DeliveryEvent = {
|
|
820
924
|
readonly type: "delivery";
|
|
@@ -827,7 +931,10 @@ type DeliveryEvent = {
|
|
|
827
931
|
readonly id: string;
|
|
828
932
|
readonly key: string;
|
|
829
933
|
};
|
|
830
|
-
/**
|
|
934
|
+
/**
|
|
935
|
+
* The checked principal, or `trusted` for an address the server loaded
|
|
936
|
+
* itself.
|
|
937
|
+
*/
|
|
831
938
|
readonly recipient?: {
|
|
832
939
|
readonly principal?: {
|
|
833
940
|
readonly id: string;
|
|
@@ -851,7 +958,10 @@ type DeliveryEvent = {
|
|
|
851
958
|
readonly retryable?: boolean;
|
|
852
959
|
/** The denial reason when `cause` is `denied`. */
|
|
853
960
|
readonly reason?: string;
|
|
854
|
-
/**
|
|
961
|
+
/**
|
|
962
|
+
* The application's own data, set where the event is built; plain JSON, never
|
|
963
|
+
* read by a decision.
|
|
964
|
+
*/
|
|
855
965
|
readonly x?: AppData;
|
|
856
966
|
};
|
|
857
967
|
/**
|
|
@@ -891,7 +1001,10 @@ type AccessEvent = {
|
|
|
891
1001
|
};
|
|
892
1002
|
/** A `SupportSession`'s permission keys. */
|
|
893
1003
|
readonly permissions?: readonly string[];
|
|
894
|
-
/**
|
|
1004
|
+
/**
|
|
1005
|
+
* The application's own data, set where the event is built; plain JSON, never
|
|
1006
|
+
* read by a decision.
|
|
1007
|
+
*/
|
|
895
1008
|
readonly x?: AppData;
|
|
896
1009
|
};
|
|
897
1010
|
type DecisionEvent = {
|
|
@@ -915,14 +1028,20 @@ type DecisionEvent = {
|
|
|
915
1028
|
readonly id: string;
|
|
916
1029
|
readonly kind: string;
|
|
917
1030
|
};
|
|
918
|
-
/**
|
|
1031
|
+
/**
|
|
1032
|
+
* OAuth `scope` and RFC 9396 `authorization_details`, as every wire form
|
|
1033
|
+
* carries a delegation.
|
|
1034
|
+
*/
|
|
919
1035
|
readonly delegation?: WireDelegation;
|
|
920
1036
|
/** The API key the subject came from. */
|
|
921
1037
|
readonly credential?: {
|
|
922
1038
|
readonly id: string;
|
|
923
1039
|
readonly kind: CredentialKind;
|
|
924
1040
|
};
|
|
925
|
-
/**
|
|
1041
|
+
/**
|
|
1042
|
+
* The support session the subject came from: the `id` its `access` events
|
|
1043
|
+
* carry as `session.id`.
|
|
1044
|
+
*/
|
|
926
1045
|
readonly supportSession?: {
|
|
927
1046
|
readonly id: string;
|
|
928
1047
|
};
|
|
@@ -946,7 +1065,10 @@ type DecisionEvent = {
|
|
|
946
1065
|
};
|
|
947
1066
|
/** What a granted decision owes, as on `GrantedDecision.obligations`. */
|
|
948
1067
|
readonly obligations?: readonly Obligation[];
|
|
949
|
-
/**
|
|
1068
|
+
/**
|
|
1069
|
+
* Purposes of use the caller asserted (`context.purpose`); present when any
|
|
1070
|
+
* was.
|
|
1071
|
+
*/
|
|
950
1072
|
readonly purpose?: readonly string[];
|
|
951
1073
|
/** The justification the caller supplied (`context.reason`); present when set. */
|
|
952
1074
|
readonly reason?: string;
|
|
@@ -957,7 +1079,10 @@ type DecisionEvent = {
|
|
|
957
1079
|
/** The call that produced the decision. */
|
|
958
1080
|
readonly call: "can" | "decide" | "assert" | "filter" | "endpoint" | "adapter" | "approval" | "simulate" | "explain";
|
|
959
1081
|
readonly adapter?: AdapterId;
|
|
960
|
-
/**
|
|
1082
|
+
/**
|
|
1083
|
+
* The model id the agent model gate decided, or the model that drove the
|
|
1084
|
+
* call.
|
|
1085
|
+
*/
|
|
961
1086
|
readonly model?: string;
|
|
962
1087
|
/** Set on an approval lifecycle event (`com.permdock.approval.<phase>`). */
|
|
963
1088
|
readonly phase?: "requested" | "resolved" | "expired" | "cancelled";
|
|
@@ -966,7 +1091,10 @@ type DecisionEvent = {
|
|
|
966
1091
|
readonly denied: number;
|
|
967
1092
|
readonly approvalRequired: number;
|
|
968
1093
|
};
|
|
969
|
-
/**
|
|
1094
|
+
/**
|
|
1095
|
+
* The application's own data, set where the event is built; plain JSON, never
|
|
1096
|
+
* read by a decision.
|
|
1097
|
+
*/
|
|
970
1098
|
readonly x?: AppData;
|
|
971
1099
|
};
|
|
972
1100
|
type AuthEvent = {
|
|
@@ -985,7 +1113,10 @@ type AuthEvent = {
|
|
|
985
1113
|
//#region src/core/snapshot-types.d.ts
|
|
986
1114
|
type Snapshot = {
|
|
987
1115
|
readonly v: 1;
|
|
988
|
-
/**
|
|
1116
|
+
/**
|
|
1117
|
+
* RFC 3339. The epoch for a snapshot built without a clock. Signed, it is the
|
|
1118
|
+
* token's `iat`.
|
|
1119
|
+
*/
|
|
989
1120
|
readonly issuedAt: string;
|
|
990
1121
|
readonly subject: {
|
|
991
1122
|
readonly principal: {
|
|
@@ -995,13 +1126,19 @@ type Snapshot = {
|
|
|
995
1126
|
readonly tenant?: string;
|
|
996
1127
|
readonly memberships?: readonly Membership[];
|
|
997
1128
|
} | null;
|
|
998
|
-
/**
|
|
1129
|
+
/**
|
|
1130
|
+
* OAuth `scope` and RFC 9396 `authorization_details`, as the token carried
|
|
1131
|
+
* them.
|
|
1132
|
+
*/
|
|
999
1133
|
readonly delegation?: WireDelegation;
|
|
1000
1134
|
readonly context: Readonly<Record<string, unknown>>;
|
|
1001
1135
|
};
|
|
1002
1136
|
/** Roles held in the active tenant, in rank order. */
|
|
1003
1137
|
readonly roles: readonly string[];
|
|
1004
|
-
/**
|
|
1138
|
+
/**
|
|
1139
|
+
* The distinct `meta.audience` values of `roles`, in rank order; absent when
|
|
1140
|
+
* none has one.
|
|
1141
|
+
*/
|
|
1005
1142
|
readonly audiences?: readonly string[];
|
|
1006
1143
|
readonly grants: readonly SnapshotGrant[];
|
|
1007
1144
|
readonly tenants: readonly string[];
|
|
@@ -1013,18 +1150,24 @@ type Snapshot = {
|
|
|
1013
1150
|
readonly roles?: Readonly<Record<string, Role>>;
|
|
1014
1151
|
readonly plans?: Readonly<Record<string, Plan>>;
|
|
1015
1152
|
};
|
|
1016
|
-
/**
|
|
1153
|
+
/**
|
|
1154
|
+
* The policy's scopes in order, so a client checks the row against each
|
|
1155
|
+
* membership's instance.
|
|
1156
|
+
*/
|
|
1017
1157
|
readonly scopes?: readonly SnapshotScope[];
|
|
1018
|
-
/**
|
|
1158
|
+
/**
|
|
1159
|
+
* One entry per tenant in `tenants`: what the subject may hand out there.
|
|
1160
|
+
* Absent without tenants.
|
|
1161
|
+
*/
|
|
1019
1162
|
readonly assignable?: readonly SnapshotAssignable[];
|
|
1020
1163
|
/**
|
|
1021
|
-
* Allow grants of held roles that only a plan the subject lacks keeps
|
|
1022
|
-
*
|
|
1164
|
+
* Allow grants of held roles that only a plan the subject lacks keeps from
|
|
1165
|
+
* applying; they grant nothing and name the plan a denial asks for.
|
|
1023
1166
|
*/
|
|
1024
1167
|
readonly notEntitled?: readonly SnapshotNotEntitled[];
|
|
1025
1168
|
/**
|
|
1026
|
-
* The row id field per resource whose `id` option is not `id`, for the
|
|
1027
|
-
*
|
|
1169
|
+
* The row id field per resource whose `id` option is not `id`, for the grants
|
|
1170
|
+
* in `grants`. Absent when every one reads `id`.
|
|
1028
1171
|
*/
|
|
1029
1172
|
readonly ids?: Readonly<Record<string, string>>;
|
|
1030
1173
|
/**
|
|
@@ -1035,7 +1178,10 @@ type Snapshot = {
|
|
|
1035
1178
|
*/
|
|
1036
1179
|
readonly delegated?: readonly string[];
|
|
1037
1180
|
};
|
|
1038
|
-
/**
|
|
1181
|
+
/**
|
|
1182
|
+
* A grant the subject would hold on another plan: its permission, role and
|
|
1183
|
+
* `to`.
|
|
1184
|
+
*/
|
|
1039
1185
|
type SnapshotNotEntitled = {
|
|
1040
1186
|
readonly permission: string;
|
|
1041
1187
|
readonly role: string | null;
|
|
@@ -1046,17 +1192,29 @@ type SnapshotScope = {
|
|
|
1046
1192
|
readonly name: string;
|
|
1047
1193
|
readonly key: string;
|
|
1048
1194
|
readonly within?: string;
|
|
1049
|
-
/**
|
|
1195
|
+
/**
|
|
1196
|
+
* Resources whose rows this scope's key partitions, from their `memberOf`
|
|
1197
|
+
* relations.
|
|
1198
|
+
*/
|
|
1050
1199
|
readonly resources?: readonly string[];
|
|
1051
|
-
/**
|
|
1200
|
+
/**
|
|
1201
|
+
* Resource name to the field holding this scope's id, for a resource whose
|
|
1202
|
+
* field is not `key` (its own `id`).
|
|
1203
|
+
*/
|
|
1052
1204
|
readonly fields?: Readonly<Record<string, string>>;
|
|
1053
1205
|
};
|
|
1054
|
-
/**
|
|
1206
|
+
/**
|
|
1207
|
+
* The declared roles and the custom-role ceiling the subject may assign in one
|
|
1208
|
+
* tenant.
|
|
1209
|
+
*/
|
|
1055
1210
|
type SnapshotAssignable = {
|
|
1056
1211
|
readonly tenant: string;
|
|
1057
1212
|
readonly roles: readonly string[];
|
|
1058
1213
|
readonly permissions: readonly Permission[];
|
|
1059
|
-
/**
|
|
1214
|
+
/**
|
|
1215
|
+
* Permission key to the levels the subject may hand out; only permissions
|
|
1216
|
+
* whose resource declares levels.
|
|
1217
|
+
*/
|
|
1060
1218
|
readonly levels?: Readonly<Record<string, readonly string[]>>;
|
|
1061
1219
|
};
|
|
1062
1220
|
type SnapshotGrant = {
|
|
@@ -1074,7 +1232,10 @@ type SnapshotGrant = {
|
|
|
1074
1232
|
readonly membership?: Membership;
|
|
1075
1233
|
readonly portable?: false;
|
|
1076
1234
|
readonly fields?: readonly string[];
|
|
1077
|
-
/**
|
|
1235
|
+
/**
|
|
1236
|
+
* When the grant applies (RFC 3339, `from` inclusive, `until` exclusive);
|
|
1237
|
+
* absent means always.
|
|
1238
|
+
*/
|
|
1078
1239
|
readonly validity?: WireValidity;
|
|
1079
1240
|
/** The grant's declared `name`. */
|
|
1080
1241
|
readonly name?: string;
|
|
@@ -1098,10 +1259,52 @@ type LocalSnapshotManifest = {
|
|
|
1098
1259
|
readonly rank?: readonly string[];
|
|
1099
1260
|
/** Every declared grant, without a membership. */
|
|
1100
1261
|
readonly grants: readonly SnapshotGrant[];
|
|
1101
|
-
/**
|
|
1262
|
+
/**
|
|
1263
|
+
* Per custom-role scope (`global` for platform roles): the grants each entry
|
|
1264
|
+
* resolves to.
|
|
1265
|
+
*/
|
|
1102
1266
|
readonly custom: Readonly<Record<string, LocalCustomRoleTable>>;
|
|
1103
|
-
/**
|
|
1267
|
+
/**
|
|
1268
|
+
* The synced tables a device reads the user's memberships, roles and custom
|
|
1269
|
+
* roles from; `permdock powersync generate` adds it.
|
|
1270
|
+
*/
|
|
1104
1271
|
readonly rows?: LocalSnapshotRows;
|
|
1272
|
+
/**
|
|
1273
|
+
* What a device needs to compute `Snapshot.assignable` for the active tenant
|
|
1274
|
+
* the way `assignableIn` does on the server.
|
|
1275
|
+
*/
|
|
1276
|
+
readonly assignable?: LocalAssignable;
|
|
1277
|
+
};
|
|
1278
|
+
/**
|
|
1279
|
+
* The hand-out rules of a policy, as a device evaluates them over its synced
|
|
1280
|
+
* memberships and custom roles.
|
|
1281
|
+
*/
|
|
1282
|
+
type LocalAssignable = {
|
|
1283
|
+
/**
|
|
1284
|
+
* Declared roles a tenant admin may hand out or compose, in rank order, with
|
|
1285
|
+
* the scope each sits on and its allow keys.
|
|
1286
|
+
*/
|
|
1287
|
+
readonly roles: readonly {
|
|
1288
|
+
readonly name: string;
|
|
1289
|
+
readonly on: string;
|
|
1290
|
+
readonly allows: readonly string[];
|
|
1291
|
+
}[];
|
|
1292
|
+
/** Declared role names and permission keys with `meta.manageRoles: true`. */
|
|
1293
|
+
readonly manage: {
|
|
1294
|
+
readonly roles: readonly string[];
|
|
1295
|
+
readonly permissions: readonly string[];
|
|
1296
|
+
};
|
|
1297
|
+
/**
|
|
1298
|
+
* Declared role name to the roles it assigns, when any role declares
|
|
1299
|
+
* `assigns`.
|
|
1300
|
+
*/
|
|
1301
|
+
readonly assigns?: Readonly<Record<string, readonly string[]>>;
|
|
1302
|
+
/** The first scope's custom-role ceiling, in declaration order. */
|
|
1303
|
+
readonly permissions: readonly Permission[];
|
|
1304
|
+
/** Permission key to its level names, in declaration order. */
|
|
1305
|
+
readonly levels?: Readonly<Record<string, readonly string[]>>;
|
|
1306
|
+
/** Index of an allow in `grants` to the levels a holder of it may hand out. */
|
|
1307
|
+
readonly grants?: Readonly<Record<string, readonly string[]>>;
|
|
1105
1308
|
};
|
|
1106
1309
|
/** A column of a synced table, or a value every row has. */
|
|
1107
1310
|
type LocalRowValue = {
|
|
@@ -1110,9 +1313,9 @@ type LocalRowValue = {
|
|
|
1110
1313
|
readonly value: string;
|
|
1111
1314
|
};
|
|
1112
1315
|
/**
|
|
1113
|
-
* A column that holds a role key or user id: the value itself, the `column`
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1316
|
+
* A column that holds a role key or user id: the value itself, the `column` of
|
|
1317
|
+
* the synced `through` table whose `id` it references, or a value each maps to
|
|
1318
|
+
* a role key (`null` for no role).
|
|
1116
1319
|
*/
|
|
1117
1320
|
type LocalRowColumn = {
|
|
1118
1321
|
readonly column: string;
|
|
@@ -1133,7 +1336,10 @@ type LocalMembershipRows = {
|
|
|
1133
1336
|
readonly user: LocalRowColumn;
|
|
1134
1337
|
readonly scope: LocalRowValue;
|
|
1135
1338
|
readonly id: string;
|
|
1136
|
-
/**
|
|
1339
|
+
/**
|
|
1340
|
+
* The role columns (the row holds every non-null key), or the fixed roles
|
|
1341
|
+
* every row holds.
|
|
1342
|
+
*/
|
|
1137
1343
|
readonly roles: readonly LocalRowColumn[] | {
|
|
1138
1344
|
readonly value: readonly string[];
|
|
1139
1345
|
};
|
|
@@ -1151,28 +1357,46 @@ type LocalSnapshotRows = {
|
|
|
1151
1357
|
/** The role columns; the row holds every non-null key. */
|
|
1152
1358
|
readonly roles: readonly LocalRowColumn[];
|
|
1153
1359
|
};
|
|
1154
|
-
/**
|
|
1360
|
+
/**
|
|
1361
|
+
* The custom-role tables (`tenant_id`, `scope`, `scope_id`, `role`, and
|
|
1362
|
+
* `permission`, `effect`, `level` or `include_role`).
|
|
1363
|
+
*/
|
|
1155
1364
|
readonly customRoles?: {
|
|
1156
1365
|
readonly permissions: string;
|
|
1157
1366
|
readonly includes: string;
|
|
1158
1367
|
};
|
|
1159
1368
|
};
|
|
1160
|
-
/**
|
|
1369
|
+
/**
|
|
1370
|
+
* Grants a custom role entry resolves to, held by a placeholder role the client
|
|
1371
|
+
* renames.
|
|
1372
|
+
*/
|
|
1161
1373
|
type LocalCustomRoleTable = {
|
|
1162
|
-
/**
|
|
1374
|
+
/**
|
|
1375
|
+
* `{ permission }` per permission key, and `{ permission, level }` per
|
|
1376
|
+
* declared level.
|
|
1377
|
+
*/
|
|
1163
1378
|
readonly permissions: Readonly<Record<string, {
|
|
1164
1379
|
readonly all: readonly SnapshotGrant[];
|
|
1165
1380
|
readonly levels?: Readonly<Record<string, readonly SnapshotGrant[]>>;
|
|
1381
|
+
/** The levels a holder of `all` may hand out. */
|
|
1382
|
+
readonly reach?: readonly string[];
|
|
1383
|
+
/** Level to the levels a holder of `levels[level]` may hand out. */
|
|
1384
|
+
readonly levelReach?: Readonly<Record<string, readonly string[]>>;
|
|
1166
1385
|
}>>;
|
|
1167
1386
|
/** `includes: [role]` per declared role. */
|
|
1168
1387
|
readonly includes: Readonly<Record<string, readonly SnapshotGrant[]>>;
|
|
1388
|
+
/**
|
|
1389
|
+
* Declared role to permission key to the levels a holder of its included
|
|
1390
|
+
* grants may hand out.
|
|
1391
|
+
*/
|
|
1392
|
+
readonly includeReach?: Readonly<Record<string, Readonly<Record<string, readonly string[]>>>>;
|
|
1169
1393
|
};
|
|
1170
1394
|
//#endregion
|
|
1171
1395
|
//#region src/core/time.d.ts
|
|
1172
1396
|
/**
|
|
1173
|
-
* The one time rule: NumericDate (whole seconds) for JWT registered claims
|
|
1174
|
-
*
|
|
1175
|
-
*
|
|
1397
|
+
* The one time rule: NumericDate (whole seconds) for JWT registered claims and
|
|
1398
|
+
* the claims SQL reads, RFC 3339 for every other JSON field, integer seconds
|
|
1399
|
+
* for durations, and an `Instant` for every runtime `now`.
|
|
1176
1400
|
*/
|
|
1177
1401
|
/**
|
|
1178
1402
|
* The part of a `Temporal.Instant` PermDock reads. Public options take it
|
|
@@ -1185,8 +1409,8 @@ type Instant = {
|
|
|
1185
1409
|
//#endregion
|
|
1186
1410
|
//#region src/core/internals.d.ts
|
|
1187
1411
|
/**
|
|
1188
|
-
* Any instance a feature function accepts: a server `PermDock`, one built
|
|
1189
|
-
*
|
|
1412
|
+
* Any instance a feature function accepts: a server `PermDock`, one built from
|
|
1413
|
+
* a snapshot, or an adapter's wrapper such as `PdpPermDock`.
|
|
1190
1414
|
*/
|
|
1191
1415
|
type InstanceHandle = {
|
|
1192
1416
|
readonly subject: Subject;
|
|
@@ -1194,19 +1418,26 @@ type InstanceHandle = {
|
|
|
1194
1418
|
//#endregion
|
|
1195
1419
|
//#region src/core/credential.d.ts
|
|
1196
1420
|
type CredentialKind = "user" | "service" | "feed";
|
|
1197
|
-
/**
|
|
1421
|
+
/**
|
|
1422
|
+
* A feed id: lowercase, so a mail system that lowercases a local part still
|
|
1423
|
+
* matches. At most 16 characters, so `pdfeed_<id>_<secret>` fits an email local
|
|
1424
|
+
* part.
|
|
1425
|
+
*/
|
|
1198
1426
|
declare function isFeedId(value: string): boolean;
|
|
1199
|
-
/**
|
|
1427
|
+
/**
|
|
1428
|
+
* One permission (a key) a credential may use: on every instance, or only on
|
|
1429
|
+
* `ids`.
|
|
1430
|
+
*/
|
|
1200
1431
|
type CredentialPermission = {
|
|
1201
1432
|
readonly permission: string;
|
|
1202
1433
|
readonly ids?: readonly string[];
|
|
1203
1434
|
};
|
|
1204
1435
|
/**
|
|
1205
|
-
* Credential v1: what a verified API key stands for, never the secret. A
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1208
|
-
*
|
|
1209
|
-
*
|
|
1436
|
+
* Credential v1: what a verified API key stands for, never the secret. A `user`
|
|
1437
|
+
* credential acts as its owner (`principal`) narrowed to `permissions`, and to
|
|
1438
|
+
* the memberships inside `tenant` when it names one; a `service` credential is
|
|
1439
|
+
* its own `service` principal holding `roles` in `tenant`, narrowed the same
|
|
1440
|
+
* way.
|
|
1210
1441
|
*/
|
|
1211
1442
|
type Credential = {
|
|
1212
1443
|
readonly v: 1;
|
|
@@ -1215,12 +1446,15 @@ type Credential = {
|
|
|
1215
1446
|
/** The owner of a `user` credential, or the id of the service principal. */
|
|
1216
1447
|
readonly principal: string;
|
|
1217
1448
|
/**
|
|
1218
|
-
* The instance of the first scope the key is held to. Required on a
|
|
1219
|
-
*
|
|
1220
|
-
*
|
|
1449
|
+
* The instance of the first scope the key is held to. Required on a service
|
|
1450
|
+
* credential, where its roles are held; optional on a user credential, where
|
|
1451
|
+
* it keeps only the owner's memberships inside it.
|
|
1221
1452
|
*/
|
|
1222
1453
|
readonly tenant?: string;
|
|
1223
|
-
/**
|
|
1454
|
+
/**
|
|
1455
|
+
* Service: the roles it holds in `tenant`. Feed: the resource roles it holds
|
|
1456
|
+
* on `on`.
|
|
1457
|
+
*/
|
|
1224
1458
|
readonly roles?: readonly string[];
|
|
1225
1459
|
/** Feed only: the resource instance the roles are held on. */
|
|
1226
1460
|
readonly on?: {
|
|
@@ -1290,14 +1524,20 @@ type CredentialDecision = {
|
|
|
1290
1524
|
} | {
|
|
1291
1525
|
readonly outcome: "approval-required";
|
|
1292
1526
|
readonly credential: Credential;
|
|
1293
|
-
/**
|
|
1527
|
+
/**
|
|
1528
|
+
* Bound to the credential's content and its creator; pass it as
|
|
1529
|
+
* `approved` to resume.
|
|
1530
|
+
*/
|
|
1294
1531
|
readonly token: string;
|
|
1295
1532
|
} | {
|
|
1296
1533
|
readonly outcome: "denied";
|
|
1297
1534
|
readonly denials: readonly Denial[];
|
|
1298
1535
|
};
|
|
1299
1536
|
type DecideCredentialOptions = {
|
|
1300
|
-
/**
|
|
1537
|
+
/**
|
|
1538
|
+
* Where the tenant's `credentials` policy comes from. Without it, only the
|
|
1539
|
+
* no-expiry rule applies.
|
|
1540
|
+
*/
|
|
1301
1541
|
readonly settings?: SettingsSource;
|
|
1302
1542
|
/** The `token` of an approval the application consumed for this request. */
|
|
1303
1543
|
readonly approved?: string;
|
|
@@ -1311,49 +1551,48 @@ type DecideCredentialOptions = {
|
|
|
1311
1551
|
*/
|
|
1312
1552
|
declare function credentialPolicyViolation(credential: Credential, policy: CredentialPolicy | readonly CredentialPolicy[]): CredentialPolicyViolation | undefined;
|
|
1313
1553
|
/**
|
|
1314
|
-
* Validates an untrusted credential record and returns a frozen copy with
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1554
|
+
* Validates an untrusted credential record and returns a frozen copy with only
|
|
1555
|
+
* the v1 fields, or `undefined`. Unknown fields are dropped; a wrong type in a
|
|
1556
|
+
* known field, a service credential without `tenant` and `roles`, or a user
|
|
1557
|
+
* credential with `roles`, rejects the whole record.
|
|
1318
1558
|
*/
|
|
1319
1559
|
declare function parseCredential(input: unknown): Credential | undefined;
|
|
1320
1560
|
/**
|
|
1321
1561
|
* The delegation a credential narrows its principal to: OAuth scopes for
|
|
1322
|
-
* permissions on every instance, one RFC 9396 entry per id otherwise. A key
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1562
|
+
* permissions on every instance, one RFC 9396 entry per id otherwise. A key the
|
|
1563
|
+
* definitions no longer declare is dropped, so a credential whose every key is
|
|
1564
|
+
* gone delegates nothing and every check is denied.
|
|
1325
1565
|
*/
|
|
1326
1566
|
declare function credentialDelegation(credential: Credential, permissions: PermissionTree): Delegation;
|
|
1327
1567
|
/**
|
|
1328
1568
|
* Decides whether the subject of `permdock` may create the credential in
|
|
1329
|
-
* `request`. The creator must be a signed-in user or service that is not
|
|
1330
|
-
*
|
|
1331
|
-
* delegation covers. A key's tenant must be one the creator is a member of;
|
|
1332
|
-
*
|
|
1569
|
+
* `request`. The creator must be a signed-in user or service that is not itself
|
|
1570
|
+
* a link or a credential; a delegated creator hands out only what its
|
|
1571
|
+
* delegation covers. A key's tenant must be one the creator is a member of; a
|
|
1572
|
+
* service key's roles among the creator's `assignableRoles` there and its
|
|
1333
1573
|
* permissions within `assignablePermissions` there (`exceeds-creator`). The
|
|
1334
|
-
* `credentials` policy of the key's tenant (its own, or for a user key
|
|
1335
|
-
*
|
|
1574
|
+
* `credentials` policy of the key's tenant (its own, or for a user key without
|
|
1575
|
+
* one the creator's active tenant) then applies (`credential-policy`; a
|
|
1336
1576
|
* settings source that throws denies with `rule: 'unavailable'`), and
|
|
1337
|
-
* `approval` makes the result `approval-required` until `approved` carries
|
|
1338
|
-
*
|
|
1339
|
-
*
|
|
1577
|
+
* `approval` makes the result `approval-required` until `approved` carries its
|
|
1578
|
+
* token. PermDock never stores the credential; the application does, after a
|
|
1579
|
+
* `granted` result.
|
|
1340
1580
|
*/
|
|
1341
1581
|
/**
|
|
1342
1582
|
* Decides whether the subject of `permdock` may create the credential in
|
|
1343
1583
|
* `request`: the creator's own reach, the `credentials` policy of the key's
|
|
1344
|
-
* tenant (the call's `settings`, else the instance's), and `approval`.
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1347
|
-
* `unsupported`.
|
|
1584
|
+
* tenant (the call's `settings`, else the instance's), and `approval`. PermDock
|
|
1585
|
+
* never stores the credential; the application does, after a `granted` result.
|
|
1586
|
+
* An instance built from a snapshot denies with `unsupported`.
|
|
1348
1587
|
*/
|
|
1349
1588
|
declare function decideCredential(permdock: InstanceHandle, request: CredentialRequest, options?: DecideCredentialOptions): Promise<CredentialDecision>;
|
|
1350
1589
|
//#endregion
|
|
1351
1590
|
//#region src/core/support-session.d.ts
|
|
1352
1591
|
/**
|
|
1353
|
-
* SupportSession v1: a support staff member (`actor`, kind `support`)
|
|
1354
|
-
*
|
|
1355
|
-
*
|
|
1356
|
-
*
|
|
1592
|
+
* SupportSession v1: a support staff member (`actor`, kind `support`) viewing
|
|
1593
|
+
* the app as `principal` in `tenant`, for a stated `reason`. Each request in
|
|
1594
|
+
* the session acts as `principal` with their live rights, narrowed to
|
|
1595
|
+
* `permissions`.
|
|
1357
1596
|
*/
|
|
1358
1597
|
type SupportSession = {
|
|
1359
1598
|
readonly v: 1;
|
|
@@ -1417,90 +1656,94 @@ type DecideSupportSessionOptions = {
|
|
|
1417
1656
|
readonly approval?: boolean;
|
|
1418
1657
|
/** The `token` of an approval the application consumed for this request. */
|
|
1419
1658
|
readonly approved?: string;
|
|
1420
|
-
/**
|
|
1659
|
+
/**
|
|
1660
|
+
* The principal id that approved; required with `approved` and never the
|
|
1661
|
+
* actor.
|
|
1662
|
+
*/
|
|
1421
1663
|
readonly approvedBy?: string;
|
|
1422
1664
|
/** The start time; defaults to the clock. */
|
|
1423
1665
|
readonly now?: Instant;
|
|
1424
1666
|
};
|
|
1425
1667
|
/**
|
|
1426
|
-
* Validates an untrusted support-session record and returns a frozen copy
|
|
1427
|
-
*
|
|
1668
|
+
* Validates an untrusted support-session record and returns a frozen copy with
|
|
1669
|
+
* only the v1 fields, or `undefined`.
|
|
1428
1670
|
*/
|
|
1429
1671
|
declare function parseSupportSession(input: unknown): SupportSession | undefined;
|
|
1430
1672
|
/**
|
|
1431
|
-
* Decides whether the subject of `permdock` may start the support session
|
|
1432
|
-
*
|
|
1673
|
+
* Decides whether the subject of `permdock` may start the support session in
|
|
1674
|
+
* `request`. The actor must be a signed-in person acting for themselves
|
|
1433
1675
|
* (`exceeds-creator` otherwise), give a `reason` (`reason-required`), be a
|
|
1434
|
-
* member of the tenant (`tenant-mismatch`) and be able to use every
|
|
1435
|
-
*
|
|
1436
|
-
*
|
|
1437
|
-
*
|
|
1438
|
-
*
|
|
1676
|
+
* member of the tenant (`tenant-mismatch`) and be able to use every permission
|
|
1677
|
+
* (`exceeds-creator`). Without `permissions` the session gets the actor's
|
|
1678
|
+
* read-only permissions. The tenant's `supportSessions` policy then applies,
|
|
1679
|
+
* and the result is `approval-required` until `approved` carries its token and
|
|
1680
|
+
* `approvedBy` names someone other than the actor.
|
|
1439
1681
|
*/
|
|
1440
1682
|
/**
|
|
1441
|
-
* Decides whether the subject of `permdock` may start the support session
|
|
1442
|
-
*
|
|
1443
|
-
*
|
|
1444
|
-
*
|
|
1445
|
-
*
|
|
1683
|
+
* Decides whether the subject of `permdock` may start the support session in
|
|
1684
|
+
* `request` and returns the record to sign: a stated reason, membership of the
|
|
1685
|
+
* tenant, the actor's own reach, the tenant's `supportSessions` policy and
|
|
1686
|
+
* approval by someone else. An instance built from a snapshot denies with
|
|
1687
|
+
* `unsupported`.
|
|
1446
1688
|
*/
|
|
1447
1689
|
declare function decideSupportSession(permdock: InstanceHandle, request: SupportSessionRequest, options?: DecideSupportSessionOptions): Promise<SupportSessionDecision>;
|
|
1448
1690
|
//#endregion
|
|
1449
1691
|
//#region src/core/interfaces.d.ts
|
|
1450
1692
|
type DecisionProvider = {
|
|
1451
1693
|
readonly name: string;
|
|
1452
|
-
handles(permission: Permission)
|
|
1453
|
-
decide(request: {
|
|
1694
|
+
handles: (permission: Permission) => boolean;
|
|
1695
|
+
decide: (request: {
|
|
1454
1696
|
readonly permission: Permission;
|
|
1455
1697
|
readonly data?: unknown;
|
|
1456
1698
|
readonly subject: Subject;
|
|
1457
1699
|
readonly local: Decision;
|
|
1458
|
-
})
|
|
1700
|
+
}) => Promise<Decision>;
|
|
1459
1701
|
/**
|
|
1460
1702
|
* Ids of the resources of `permission.resource` the subject may act on.
|
|
1461
1703
|
* `null` means the provider could not answer and every row is denied;
|
|
1462
1704
|
* `undefined` means it cannot list, and each row is decided on its own.
|
|
1463
1705
|
*/
|
|
1464
|
-
permitted
|
|
1706
|
+
permitted?: (request: {
|
|
1465
1707
|
readonly permission: Permission;
|
|
1466
1708
|
readonly subject: Subject;
|
|
1467
|
-
})
|
|
1709
|
+
}) => Promise<readonly string[] | null | undefined>;
|
|
1468
1710
|
};
|
|
1469
1711
|
type CustomRoleSource = {
|
|
1470
1712
|
/** Names the implementation in errors and events. */
|
|
1471
1713
|
readonly name?: string;
|
|
1472
1714
|
/**
|
|
1473
|
-
* The custom roles of one tenant. `getPermDock` passes `held`, the role
|
|
1474
|
-
*
|
|
1475
|
-
*
|
|
1715
|
+
* The custom roles of one tenant. `getPermDock` passes `held`, the role names
|
|
1716
|
+
* the subject's live memberships hold there, declared or not, so a source can
|
|
1717
|
+
* skip its read when none of them is a custom role.
|
|
1476
1718
|
*/
|
|
1477
|
-
rolesFor(tenant: string, context?: {
|
|
1719
|
+
rolesFor: (tenant: string, context?: {
|
|
1478
1720
|
readonly held: readonly string[];
|
|
1479
|
-
})
|
|
1480
|
-
assignable
|
|
1721
|
+
}) => CustomRole[] | Promise<CustomRole[]>;
|
|
1722
|
+
assignable?: (tenant: string) => string[] | Promise<string[]>;
|
|
1481
1723
|
/**
|
|
1482
|
-
* Platform custom roles (`scope: 'global'`), read once per signed-in
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
1724
|
+
* Platform custom roles (`scope: 'global'`), read once per signed-in subject,
|
|
1725
|
+
* with `held`, the global role names the subject holds. A role here with a
|
|
1726
|
+
* tenant is ignored.
|
|
1485
1727
|
*/
|
|
1486
|
-
globalRoles
|
|
1728
|
+
globalRoles?: (context?: {
|
|
1487
1729
|
readonly held: readonly string[];
|
|
1488
|
-
})
|
|
1730
|
+
}) => CustomRole[] | Promise<CustomRole[]>;
|
|
1489
1731
|
/**
|
|
1490
1732
|
* Shared custom roles (`shared: true`), defined once for every tenant and
|
|
1491
|
-
* read once per subject with a tenant membership, with `held`, the role
|
|
1492
|
-
*
|
|
1493
|
-
*
|
|
1733
|
+
* read once per subject with a tenant membership, with `held`, the role names
|
|
1734
|
+
* its live memberships hold in any tenant. A role here without `shared: true`
|
|
1735
|
+
* is ignored.
|
|
1494
1736
|
*/
|
|
1495
|
-
sharedRoles
|
|
1737
|
+
sharedRoles?: (context?: {
|
|
1496
1738
|
readonly held: readonly string[];
|
|
1497
|
-
})
|
|
1739
|
+
}) => CustomRole[] | Promise<CustomRole[]>;
|
|
1498
1740
|
};
|
|
1499
1741
|
/**
|
|
1500
|
-
* A `CustomRoleSource` built for the subject the instance serves, for an
|
|
1501
|
-
* option shared by every request: it gets the resolved subject
|
|
1502
|
-
* actor and delegation) and returns that subject's source, or
|
|
1503
|
-
* for none. A throw reads no custom roles and reports
|
|
1742
|
+
* A `CustomRoleSource` built for the subject the instance serves, for an
|
|
1743
|
+
* adapter option shared by every request: it gets the resolved subject
|
|
1744
|
+
* (principal, actor and delegation) and returns that subject's source, or
|
|
1745
|
+
* `undefined` for none. A throw reads no custom roles and reports
|
|
1746
|
+
* `source-threw`.
|
|
1504
1747
|
*/
|
|
1505
1748
|
type CustomRoleSourceFactory = (subject: Subject) => CustomRoleSource | undefined;
|
|
1506
1749
|
/** One member of a scope instance, as `MembershipSource.list` returns it. */
|
|
@@ -1513,39 +1756,42 @@ type MemberEntry = {
|
|
|
1513
1756
|
type MembershipSource = {
|
|
1514
1757
|
/** Names the implementation in errors and events. */
|
|
1515
1758
|
readonly name?: string;
|
|
1516
|
-
membershipsFor(principal: {
|
|
1759
|
+
membershipsFor: (principal: {
|
|
1517
1760
|
readonly id: string;
|
|
1518
1761
|
readonly kind?: string;
|
|
1519
1762
|
}, options: {
|
|
1520
1763
|
readonly tenant?: string;
|
|
1521
|
-
})
|
|
1522
|
-
/**
|
|
1523
|
-
|
|
1764
|
+
}) => Membership[] | Promise<Membership[]>;
|
|
1765
|
+
/**
|
|
1766
|
+
* Every membership held in one scope instance, for member lists and access
|
|
1767
|
+
* reviews.
|
|
1768
|
+
*/
|
|
1769
|
+
list?: (query: {
|
|
1524
1770
|
readonly scope: string;
|
|
1525
1771
|
readonly id: string;
|
|
1526
|
-
})
|
|
1772
|
+
}) => MemberEntry[] | Promise<MemberEntry[]>;
|
|
1527
1773
|
/**
|
|
1528
1774
|
* The principal's current authorization version, bumped on every membership
|
|
1529
|
-
* change. A token whose `authzVersion` is behind it is stale for the
|
|
1530
|
-
*
|
|
1531
|
-
*
|
|
1532
|
-
*
|
|
1775
|
+
* change. A token whose `authzVersion` is behind it is stale for the policy's
|
|
1776
|
+
* `fresh` permissions. `roles` and `memberships` are what the token claims,
|
|
1777
|
+
* so a source can read more than the version in the same call when the claims
|
|
1778
|
+
* show it will be needed.
|
|
1533
1779
|
*/
|
|
1534
|
-
version
|
|
1780
|
+
version?: (principal: {
|
|
1535
1781
|
readonly id: string;
|
|
1536
1782
|
readonly roles?: readonly string[];
|
|
1537
1783
|
readonly memberships?: readonly Membership[];
|
|
1538
|
-
})
|
|
1784
|
+
}) => number | undefined | Promise<number | undefined>;
|
|
1539
1785
|
/**
|
|
1540
|
-
* The global roles the principal holds now. With `onStale: 'reread'`, a
|
|
1541
|
-
*
|
|
1542
|
-
*
|
|
1543
|
-
*
|
|
1786
|
+
* The global roles the principal holds now. With `onStale: 'reread'`, a stale
|
|
1787
|
+
* token's `principal.roles` is replaced by this answer, so a revoked platform
|
|
1788
|
+
* role is lost with the memberships. A throw or rejection leaves no global
|
|
1789
|
+
* roles. Without it, a reread keeps the token's roles.
|
|
1544
1790
|
*/
|
|
1545
|
-
globalRolesFor
|
|
1791
|
+
globalRolesFor?: (principal: {
|
|
1546
1792
|
readonly id: string;
|
|
1547
1793
|
readonly kind?: string;
|
|
1548
|
-
})
|
|
1794
|
+
}) => readonly string[] | Promise<readonly string[]>;
|
|
1549
1795
|
/**
|
|
1550
1796
|
* Keep the memberships the verified token carries and read this source only
|
|
1551
1797
|
* when the token says they were truncated (`claimsFirst`).
|
|
@@ -1555,9 +1801,9 @@ type MembershipSource = {
|
|
|
1555
1801
|
* What a token behind `version` gets. Only permissions the policy marks
|
|
1556
1802
|
* `fresh` look at staleness: `'deny'` (the default) denies those with
|
|
1557
1803
|
* `stale-credentials` and leaves every other permission on the token's
|
|
1558
|
-
* claims; `'reread'` replaces the token's memberships (and global roles,
|
|
1559
|
-
*
|
|
1560
|
-
*
|
|
1804
|
+
* claims; `'reread'` replaces the token's memberships (and global roles, when
|
|
1805
|
+
* the source has `globalRolesFor`) with a live read for the whole subject, so
|
|
1806
|
+
* no decision keeps a revoked grant.
|
|
1561
1807
|
*/
|
|
1562
1808
|
readonly onStale?: "deny" | "reread";
|
|
1563
1809
|
};
|
|
@@ -1565,7 +1811,10 @@ type MembershipSource = {
|
|
|
1565
1811
|
type RelationChain = {
|
|
1566
1812
|
/** Whether the object itself is restricted: nothing above it reaches it. */
|
|
1567
1813
|
readonly restricted?: boolean;
|
|
1568
|
-
/**
|
|
1814
|
+
/**
|
|
1815
|
+
* Ancestors nearest first, at most `depth`; a restricted one ends the walk
|
|
1816
|
+
* after itself.
|
|
1817
|
+
*/
|
|
1569
1818
|
readonly ancestors: readonly {
|
|
1570
1819
|
readonly id: string;
|
|
1571
1820
|
readonly restricted?: boolean;
|
|
@@ -1579,7 +1828,10 @@ type HolderPeriod = {
|
|
|
1579
1828
|
/** Seconds since the epoch; from it on the relation no longer holds. */
|
|
1580
1829
|
readonly expiresAt?: number;
|
|
1581
1830
|
};
|
|
1582
|
-
/**
|
|
1831
|
+
/**
|
|
1832
|
+
* A group holding a relation on an object: whoever holds `relation` on the
|
|
1833
|
+
* group's instance holds it too.
|
|
1834
|
+
*/
|
|
1583
1835
|
type RelationGroup = {
|
|
1584
1836
|
readonly resource: string;
|
|
1585
1837
|
readonly id: string;
|
|
@@ -1597,10 +1849,9 @@ type RelationHolder = HolderPeriod & ({
|
|
|
1597
1849
|
readonly group: RelationGroup;
|
|
1598
1850
|
});
|
|
1599
1851
|
/**
|
|
1600
|
-
* The object graph: parent chains, links and who holds a relation on an
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
* `relation-unavailable`.
|
|
1852
|
+
* The object graph: parent chains, links and who holds a relation on an object.
|
|
1853
|
+
* A source answers facts and never decides; a thrown or rejected call, or a
|
|
1854
|
+
* Promise the instance has not loaded, denies with `relation-unavailable`.
|
|
1604
1855
|
*/
|
|
1605
1856
|
type RelationSource = {
|
|
1606
1857
|
/** Names the implementation in errors and events. */
|
|
@@ -1609,31 +1860,34 @@ type RelationSource = {
|
|
|
1609
1860
|
* With `through: 'parent'`, the parent chain; with a link name, the one
|
|
1610
1861
|
* instance that link points to (`depth` is then 1).
|
|
1611
1862
|
*/
|
|
1612
|
-
ancestors(query: {
|
|
1863
|
+
ancestors: (query: {
|
|
1613
1864
|
readonly resource: string;
|
|
1614
1865
|
readonly id: string;
|
|
1615
1866
|
readonly through: string;
|
|
1616
1867
|
readonly depth: number;
|
|
1617
|
-
})
|
|
1618
|
-
related(query: {
|
|
1868
|
+
}) => RelationChain | Promise<RelationChain>;
|
|
1869
|
+
related: (query: {
|
|
1619
1870
|
readonly resource: string;
|
|
1620
1871
|
readonly id: string;
|
|
1621
1872
|
readonly relation: string;
|
|
1622
|
-
})
|
|
1623
|
-
row
|
|
1873
|
+
}) => RelationHolder[] | Promise<RelationHolder[]>;
|
|
1874
|
+
row?: (query: {
|
|
1624
1875
|
readonly resource: string;
|
|
1625
1876
|
readonly id: string;
|
|
1626
|
-
})
|
|
1877
|
+
}) => Readonly<Record<string, unknown>> | null | undefined | Promise<Readonly<Record<string, unknown>> | null | undefined>;
|
|
1627
1878
|
};
|
|
1628
|
-
/**
|
|
1879
|
+
/**
|
|
1880
|
+
* Plan and seat names a principal holds in a tenant, from billing (Stripe
|
|
1881
|
+
* Entitlements, a table).
|
|
1882
|
+
*/
|
|
1629
1883
|
type EntitlementSource = {
|
|
1630
1884
|
/** Names the implementation in errors and events. */
|
|
1631
1885
|
readonly name?: string;
|
|
1632
|
-
entitlementsFor(principal: {
|
|
1886
|
+
entitlementsFor: (principal: {
|
|
1633
1887
|
readonly id: string;
|
|
1634
1888
|
}, options: {
|
|
1635
1889
|
readonly tenant?: string;
|
|
1636
|
-
})
|
|
1890
|
+
}) => string[] | Promise<string[]>;
|
|
1637
1891
|
};
|
|
1638
1892
|
type JwtClaims = {
|
|
1639
1893
|
readonly iss?: string;
|
|
@@ -1662,29 +1916,32 @@ type VerificationFailure = {
|
|
|
1662
1916
|
type TokenVerifier<TClaims extends JwtClaims = JwtClaims> = {
|
|
1663
1917
|
/** Names the implementation in errors and events. */
|
|
1664
1918
|
readonly name?: string;
|
|
1665
|
-
verify(token: string, expectations: {
|
|
1919
|
+
verify: (token: string, expectations: {
|
|
1666
1920
|
readonly typ?: string | readonly string[];
|
|
1667
1921
|
readonly audience?: string | readonly string[];
|
|
1668
1922
|
readonly issuer?: string;
|
|
1669
1923
|
readonly clockTolerance?: number;
|
|
1670
|
-
})
|
|
1924
|
+
}) => Promise<VerifiedToken<TClaims> | VerificationFailure>;
|
|
1671
1925
|
};
|
|
1672
1926
|
type TokenSigner = {
|
|
1673
1927
|
/** Names the implementation in errors and events. */
|
|
1674
1928
|
readonly name?: string;
|
|
1675
|
-
sign(payload: Readonly<Record<string, unknown>>, options: {
|
|
1929
|
+
sign: (payload: Readonly<Record<string, unknown>>, options: {
|
|
1676
1930
|
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";
|
|
1677
1931
|
/** `aud`; a signer with no default audience refuses to sign without one. */
|
|
1678
1932
|
readonly audience?: string | readonly string[];
|
|
1679
1933
|
/** `exp`, a NumericDate; one hour after `iat` when absent. */
|
|
1680
1934
|
readonly expiresAt?: number;
|
|
1681
|
-
/**
|
|
1935
|
+
/**
|
|
1936
|
+
* `iat`, a NumericDate: the artefact's issue time. The signer's clock
|
|
1937
|
+
* when absent.
|
|
1938
|
+
*/
|
|
1682
1939
|
readonly issuedAt?: number;
|
|
1683
1940
|
/** `jti`: the artefact's id. A fresh UUID when absent. */
|
|
1684
1941
|
readonly jti?: string;
|
|
1685
|
-
})
|
|
1942
|
+
}) => Promise<string>;
|
|
1686
1943
|
readonly kid?: string;
|
|
1687
|
-
jwks
|
|
1944
|
+
jwks?: () => Promise<{
|
|
1688
1945
|
readonly keys: readonly JsonWebKeyLike[];
|
|
1689
1946
|
}>;
|
|
1690
1947
|
};
|
|
@@ -1694,8 +1951,8 @@ type SubjectResolver<TInput, TPrincipal extends Principal = Principal> = (input:
|
|
|
1694
1951
|
type SnapshotSource = {
|
|
1695
1952
|
/** Names the implementation in errors and events. */
|
|
1696
1953
|
readonly name?: string;
|
|
1697
|
-
get()
|
|
1698
|
-
subscribe
|
|
1954
|
+
get: () => Promise<Snapshot | string> | Snapshot | string;
|
|
1955
|
+
subscribe?: (listener: () => void) => () => void;
|
|
1699
1956
|
};
|
|
1700
1957
|
type WhereCompiler<TTarget, TOptions = unknown> = (condition: Condition, target: TTarget, options?: TOptions) => unknown;
|
|
1701
1958
|
type LimitConsumeInput = {
|
|
@@ -1715,31 +1972,31 @@ type LimitRemaining = {
|
|
|
1715
1972
|
type LimitStore = {
|
|
1716
1973
|
/** Names the implementation in errors and events. */
|
|
1717
1974
|
readonly name?: string;
|
|
1718
|
-
consume(input: LimitConsumeInput)
|
|
1719
|
-
remaining(input: LimitConsumeInput)
|
|
1975
|
+
consume: (input: LimitConsumeInput) => Promise<LimitRemaining> | LimitRemaining;
|
|
1976
|
+
remaining: (input: LimitConsumeInput) => LimitRemaining | undefined;
|
|
1720
1977
|
};
|
|
1721
1978
|
type DecisionSink = {
|
|
1722
1979
|
/** Names the implementation in errors and events. */
|
|
1723
1980
|
readonly name?: string;
|
|
1724
|
-
write(events: readonly SinkEvent[])
|
|
1725
|
-
flush
|
|
1981
|
+
write: (events: readonly SinkEvent[]) => Promise<void> | void;
|
|
1982
|
+
flush?: () => Promise<void>;
|
|
1726
1983
|
};
|
|
1727
1984
|
/**
|
|
1728
1985
|
* Looks up the credential an API key stands for. `null` for a key that is
|
|
1729
|
-
* malformed, unknown, revoked or whose secret does not match; never throws
|
|
1730
|
-
*
|
|
1731
|
-
*
|
|
1986
|
+
* malformed, unknown, revoked or whose secret does not match; never throws for
|
|
1987
|
+
* bad input. Verification is the application's (or `apiKeyVerifier`'s), never
|
|
1988
|
+
* core's.
|
|
1732
1989
|
*/
|
|
1733
1990
|
type CredentialVerifier = {
|
|
1734
1991
|
/** Names the implementation in errors and events. */
|
|
1735
1992
|
readonly name?: string;
|
|
1736
|
-
verify(secret: string)
|
|
1993
|
+
verify: (secret: string) => Credential | null | Promise<Credential | null>;
|
|
1737
1994
|
/**
|
|
1738
|
-
* Records a successful use at `at`, for a `lastUsedAt` column. Called
|
|
1739
|
-
*
|
|
1740
|
-
*
|
|
1995
|
+
* Records a successful use at `at`, for a `lastUsedAt` column. Called after a
|
|
1996
|
+
* key resolved and not awaited; a throw or a rejection is ignored, so it
|
|
1997
|
+
* never changes the subject.
|
|
1741
1998
|
*/
|
|
1742
|
-
touch
|
|
1999
|
+
touch?: (id: string, at: Instant) => void | Promise<void>;
|
|
1743
2000
|
};
|
|
1744
2001
|
/** What one tenant configures for itself. Every field only tightens. */
|
|
1745
2002
|
type TenantSettings = {
|
|
@@ -1749,13 +2006,13 @@ type TenantSettings = {
|
|
|
1749
2006
|
readonly supportSessions?: SupportSessionPolicy;
|
|
1750
2007
|
};
|
|
1751
2008
|
/**
|
|
1752
|
-
* Per-tenant settings, a subject input like `CustomRoleSource`: they tighten
|
|
1753
|
-
* a key may be and never grant. A throw denies.
|
|
2009
|
+
* Per-tenant settings, a subject input like `CustomRoleSource`: they tighten
|
|
2010
|
+
* what a key may be and never grant. A throw denies.
|
|
1754
2011
|
*/
|
|
1755
2012
|
type SettingsSource = {
|
|
1756
2013
|
/** Names the implementation in errors and events. */
|
|
1757
2014
|
readonly name?: string;
|
|
1758
|
-
settingsFor(tenant: string)
|
|
2015
|
+
settingsFor: (tenant: string) => TenantSettings | undefined | Promise<TenantSettings | undefined>;
|
|
1759
2016
|
};
|
|
1760
2017
|
//#endregion
|
|
1761
2018
|
//#region src/core/policy-fingerprint.d.ts
|
|
@@ -1785,13 +2042,16 @@ type ApprovalStage = {
|
|
|
1785
2042
|
readonly by: Approver | readonly Approver[];
|
|
1786
2043
|
/** Absent means 1. */
|
|
1787
2044
|
readonly quorum?: number;
|
|
1788
|
-
/**
|
|
2045
|
+
/**
|
|
2046
|
+
* After `after`, `to` may approve this stage as well as `by`; other stages
|
|
2047
|
+
* are unaffected.
|
|
2048
|
+
*/
|
|
1789
2049
|
readonly escalation?: ApprovalEscalation;
|
|
1790
2050
|
};
|
|
1791
2051
|
/**
|
|
1792
|
-
* `'any'`: `quorum` approvers from `by`. `'all'`: every stage completes, in
|
|
1793
|
-
*
|
|
1794
|
-
*
|
|
2052
|
+
* `'any'`: `quorum` approvers from `by`. `'all'`: every stage completes, in any
|
|
2053
|
+
* order. `'sequential'`: stages complete in order; an approver signs only the
|
|
2054
|
+
* first incomplete stage. An approver signs once per request.
|
|
1795
2055
|
*/
|
|
1796
2056
|
type ApprovalMode = "any" | "all" | "sequential";
|
|
1797
2057
|
type ApprovalRequirement = {
|
|
@@ -1805,15 +2065,24 @@ type ApprovalRequirement = {
|
|
|
1805
2065
|
readonly distinct?: boolean;
|
|
1806
2066
|
/** `'resource-change'` binds the approval to the row's `version` field. */
|
|
1807
2067
|
readonly staleOn?: "resource-change";
|
|
1808
|
-
/**
|
|
2068
|
+
/**
|
|
2069
|
+
* Distinct approvers a request needs before it is approved under `by`; absent
|
|
2070
|
+
* means 1.
|
|
2071
|
+
*/
|
|
1809
2072
|
readonly quorum?: number;
|
|
1810
|
-
/**
|
|
2073
|
+
/**
|
|
2074
|
+
* Seconds a request stays open; the store's default when absent, and never
|
|
2075
|
+
* longer than it.
|
|
2076
|
+
*/
|
|
1811
2077
|
readonly ttl?: number;
|
|
1812
2078
|
readonly escalation?: ApprovalEscalation;
|
|
1813
2079
|
};
|
|
1814
2080
|
type ApprovalOption = "human" | {
|
|
1815
2081
|
readonly by?: ApproverInput;
|
|
1816
|
-
/**
|
|
2082
|
+
/**
|
|
2083
|
+
* `'all'` or `'sequential'` with `stages`; absent means `'any'` with
|
|
2084
|
+
* `by`.
|
|
2085
|
+
*/
|
|
1817
2086
|
readonly mode?: ApprovalMode;
|
|
1818
2087
|
readonly stages?: readonly {
|
|
1819
2088
|
readonly by: ApproverInput;
|
|
@@ -1832,11 +2101,20 @@ type ApprovalOption = "human" | {
|
|
|
1832
2101
|
* changes, resuming denies with `stale-approval`.
|
|
1833
2102
|
*/
|
|
1834
2103
|
readonly staleOn?: "resource-change";
|
|
1835
|
-
/**
|
|
2104
|
+
/**
|
|
2105
|
+
* Distinct approvers needed (an integer of at least 1); the same approver
|
|
2106
|
+
* counts once. Absent means 1.
|
|
2107
|
+
*/
|
|
1836
2108
|
readonly quorum?: number;
|
|
1837
|
-
/**
|
|
2109
|
+
/**
|
|
2110
|
+
* Seconds the request stays open (`1800`); caps the approval store's
|
|
2111
|
+
* default.
|
|
2112
|
+
*/
|
|
1838
2113
|
readonly ttl?: number;
|
|
1839
|
-
/**
|
|
2114
|
+
/**
|
|
2115
|
+
* After `after` seconds (`14_400`), `to` may approve as well as `by`, at
|
|
2116
|
+
* any open stage; same kinds as `by`.
|
|
2117
|
+
*/
|
|
1840
2118
|
readonly escalation?: {
|
|
1841
2119
|
readonly after: number;
|
|
1842
2120
|
readonly to: ApproverInput;
|
|
@@ -1864,16 +2142,19 @@ type AssuranceRequirement = {
|
|
|
1864
2142
|
readonly amr?: readonly string[];
|
|
1865
2143
|
};
|
|
1866
2144
|
/**
|
|
1867
|
-
* Time-boxed role activation. A role with `activation` is never held
|
|
1868
|
-
*
|
|
1869
|
-
*
|
|
2145
|
+
* Time-boxed role activation. A role with `activation` is never held directly:
|
|
2146
|
+
* a membership lists it under `eligible`, and `permdock.activate` mints the
|
|
2147
|
+
* elevated membership to write.
|
|
1870
2148
|
*/
|
|
1871
2149
|
type ActivationOption = {
|
|
1872
2150
|
/** The longest an activation may last, in seconds (`14_400`). */
|
|
1873
2151
|
readonly maxDuration?: number;
|
|
1874
2152
|
/** `'required'` denies an activation without a reason. */
|
|
1875
2153
|
readonly justification?: "required" | "optional";
|
|
1876
|
-
/**
|
|
2154
|
+
/**
|
|
2155
|
+
* When set, `activate` returns `approval-required` before the membership can
|
|
2156
|
+
* be written.
|
|
2157
|
+
*/
|
|
1877
2158
|
readonly approval?: ApprovalOption;
|
|
1878
2159
|
/** How fresh the activator's authentication must be. */
|
|
1879
2160
|
readonly assurance?: AssuranceRequirement;
|
|
@@ -1921,10 +2202,16 @@ type SupportAccessOptions<S extends string = string> = {
|
|
|
1921
2202
|
readonly role: string;
|
|
1922
2203
|
/** The scope the support membership sits in; defaults to `tenant`. */
|
|
1923
2204
|
readonly on?: S;
|
|
1924
|
-
/**
|
|
2205
|
+
/**
|
|
2206
|
+
* Every decision under the support membership denies with `actor-required`
|
|
2207
|
+
* without an `act`.
|
|
2208
|
+
*/
|
|
1925
2209
|
readonly actorRequired?: boolean;
|
|
1926
2210
|
readonly consent: SupportConsent;
|
|
1927
|
-
/**
|
|
2211
|
+
/**
|
|
2212
|
+
* Permissions a support session never reaches, compiled to deny grants scoped
|
|
2213
|
+
* to `via: 'support'`.
|
|
2214
|
+
*/
|
|
1928
2215
|
readonly forbid?: readonly (Permission | PermissionTree)[];
|
|
1929
2216
|
/** The subgroup a consented membership records under `member.group`. */
|
|
1930
2217
|
readonly group?: string;
|
|
@@ -1945,38 +2232,56 @@ type GrantOptions<T = Record<string, unknown>> = {
|
|
|
1945
2232
|
readonly approval?: ApprovalOption;
|
|
1946
2233
|
readonly limit?: GrantLimit;
|
|
1947
2234
|
readonly reason?: string;
|
|
1948
|
-
readonly fields?: readonly (keyof T & string)[];
|
|
2235
|
+
readonly fields?: readonly (unknown extends T ? string : keyof T & string)[];
|
|
1949
2236
|
/**
|
|
1950
2237
|
* A stable name for the grant. On a deny, a `breakGlass` override may lift
|
|
1951
|
-
* it; on any grant, it is reported on `decision.matched.name` and on
|
|
1952
|
-
*
|
|
2238
|
+
* it; on any grant, it is reported on `decision.matched.name` and on decision
|
|
2239
|
+
* events.
|
|
1953
2240
|
*/
|
|
1954
2241
|
readonly name?: string;
|
|
1955
2242
|
readonly group?: string;
|
|
1956
|
-
/**
|
|
2243
|
+
/**
|
|
2244
|
+
* Display text and app data for the grant, reported on
|
|
2245
|
+
* `decision.matched.meta`; never read in evaluation.
|
|
2246
|
+
*/
|
|
1957
2247
|
readonly meta?: GrantMeta;
|
|
1958
2248
|
/**
|
|
1959
|
-
* Follow-ups the application owes when this allow grants: each becomes a
|
|
1960
|
-
*
|
|
2249
|
+
* Follow-ups the application owes when this allow grants: each becomes a `{
|
|
2250
|
+
* kind: 'app', name, detail? }` obligation on the decision. Allows only.
|
|
1961
2251
|
*/
|
|
1962
2252
|
readonly obligations?: readonly ObligationInput[];
|
|
1963
|
-
/**
|
|
2253
|
+
/**
|
|
2254
|
+
* Purposes of use (`context.purpose`) that make the grant apply;
|
|
2255
|
+
* non-portable.
|
|
2256
|
+
*/
|
|
1964
2257
|
readonly purpose?: readonly string[];
|
|
1965
|
-
/**
|
|
2258
|
+
/**
|
|
2259
|
+
* The grant applies from this instant on (RFC 3339 or an `Instant`); before
|
|
2260
|
+
* it an allow denies with `inactive-grant` and a deny does not apply.
|
|
2261
|
+
*/
|
|
1966
2262
|
readonly validFrom?: string | Instant;
|
|
1967
|
-
/**
|
|
2263
|
+
/**
|
|
2264
|
+
* The grant stops applying at this instant (exclusive; RFC 3339 or an
|
|
2265
|
+
* `Instant`).
|
|
2266
|
+
*/
|
|
1968
2267
|
readonly validUntil?: string | Instant;
|
|
1969
2268
|
/**
|
|
1970
|
-
* An allow on an instance action counts only on rows whose scope instance
|
|
1971
|
-
*
|
|
2269
|
+
* An allow on an instance action counts only on rows whose scope instance (or
|
|
2270
|
+
* the whole app, globally) is one where the subject also holds this
|
|
1972
2271
|
* permission through a role grant without a row condition.
|
|
1973
2272
|
*/
|
|
1974
2273
|
readonly requires?: Permission | readonly Permission[];
|
|
1975
2274
|
};
|
|
1976
|
-
/**
|
|
2275
|
+
/**
|
|
2276
|
+
* A grant's metadata. PermDock carries it to decisions, events, snapshots and
|
|
2277
|
+
* the catalog and never reads `x`.
|
|
2278
|
+
*/
|
|
1977
2279
|
type GrantMeta = {
|
|
1978
2280
|
readonly description?: string;
|
|
1979
|
-
/**
|
|
2281
|
+
/**
|
|
2282
|
+
* Data the application owns. Plain JSON, checked by `definePolicy(…, { x: {
|
|
2283
|
+
* grant } })`.
|
|
2284
|
+
*/
|
|
1980
2285
|
readonly x?: AppData;
|
|
1981
2286
|
};
|
|
1982
2287
|
/** An app obligation as declared on an allow: its name, or its name and detail. */
|
|
@@ -1986,22 +2291,25 @@ type ObligationInput = string | {
|
|
|
1986
2291
|
};
|
|
1987
2292
|
/**
|
|
1988
2293
|
* When a grant applies, in Unix seconds. `from` is inclusive, `until`
|
|
1989
|
-
* exclusive; either may be absent. Portable: `where()` drops an inactive
|
|
1990
|
-
*
|
|
2294
|
+
* exclusive; either may be absent. Portable: `where()` drops an inactive grant
|
|
2295
|
+
* at the decision clock and generated RLS compares against `now()`.
|
|
1991
2296
|
*/
|
|
1992
2297
|
type GrantValidity = {
|
|
1993
2298
|
readonly from?: number;
|
|
1994
2299
|
readonly until?: number;
|
|
1995
2300
|
};
|
|
1996
|
-
/**
|
|
2301
|
+
/**
|
|
2302
|
+
* A grant's validity in JSON (snapshots, catalogs, `inactive-grant` details):
|
|
2303
|
+
* RFC 3339 bounds.
|
|
2304
|
+
*/
|
|
1997
2305
|
type WireValidity = {
|
|
1998
2306
|
readonly from?: string;
|
|
1999
2307
|
readonly until?: string;
|
|
2000
2308
|
};
|
|
2001
2309
|
/**
|
|
2002
|
-
* The actor a policy delegation is for: an actor kind, narrowed to one id
|
|
2003
|
-
*
|
|
2004
|
-
*
|
|
2310
|
+
* The actor a policy delegation is for: an actor kind, narrowed to one id when
|
|
2311
|
+
* `id` is set, or to one named client when `client` is set (the name the
|
|
2312
|
+
* subject resolver gives a verified client id through `clients`).
|
|
2005
2313
|
*/
|
|
2006
2314
|
type DelegationTarget = {
|
|
2007
2315
|
readonly kind: ActorKind;
|
|
@@ -2017,42 +2325,66 @@ type PolicyDelegation = {
|
|
|
2017
2325
|
readonly from: Grantee | readonly Grantee[];
|
|
2018
2326
|
readonly to: DelegationTarget;
|
|
2019
2327
|
readonly permissions: readonly string[];
|
|
2020
|
-
/**
|
|
2328
|
+
/**
|
|
2329
|
+
* The keys of `permissions` whose `readOnlyHint` is true: all a `readOnly`
|
|
2330
|
+
* actor may use.
|
|
2331
|
+
*/
|
|
2021
2332
|
readonly readOnly: readonly string[];
|
|
2022
2333
|
readonly validity?: GrantValidity;
|
|
2023
2334
|
};
|
|
2024
2335
|
type DelegationInput = {
|
|
2025
|
-
/**
|
|
2336
|
+
/**
|
|
2337
|
+
* Who hands over: the same subject-only selectors as `approval.by` (a role,
|
|
2338
|
+
* `authenticated()`, a plan, `assurance()`); not `relation()`.
|
|
2339
|
+
*/
|
|
2026
2340
|
readonly from: GranteeInput;
|
|
2027
|
-
/**
|
|
2341
|
+
/**
|
|
2342
|
+
* Which actor may act: `actor('eve')`, an actor kind, `{ kind, id }` for one
|
|
2343
|
+
* agent, or `{ kind, client }` for one named OAuth client.
|
|
2344
|
+
*/
|
|
2028
2345
|
readonly to: ActorGrantee | string | DelegationTarget;
|
|
2029
2346
|
/** The leaves or subtrees the actor may use; a deny grant still applies. */
|
|
2030
2347
|
readonly permissions: readonly (Permission | PermissionTree)[];
|
|
2031
2348
|
readonly validFrom?: string | Instant;
|
|
2032
2349
|
readonly validUntil?: string | Instant;
|
|
2033
2350
|
};
|
|
2034
|
-
/**
|
|
2351
|
+
/**
|
|
2352
|
+
* A declared scope name (or the `tenant` / `team` alias), or the resource a
|
|
2353
|
+
* role is held on.
|
|
2354
|
+
*/
|
|
2035
2355
|
type RoleScope<S extends string = string> = S | Permission | PermissionTree | readonly (Permission | PermissionTree)[];
|
|
2036
2356
|
type RoleOptions<S extends string = string> = {
|
|
2037
2357
|
readonly on?: RoleScope<S>;
|
|
2038
2358
|
readonly assignable?: boolean;
|
|
2039
2359
|
/** Roles nobody may hold together with this one in the same scope instance. */
|
|
2040
2360
|
readonly exclusiveWith?: readonly string[];
|
|
2041
|
-
/**
|
|
2361
|
+
/**
|
|
2362
|
+
* Fewest holders a scope instance keeps (checked at commit); default 0. Needs
|
|
2363
|
+
* a named-scope `on`.
|
|
2364
|
+
*/
|
|
2042
2365
|
readonly min?: number;
|
|
2043
2366
|
/** Most holders a scope instance may have. Needs a named-scope `on`. */
|
|
2044
2367
|
readonly max?: number;
|
|
2045
|
-
/**
|
|
2368
|
+
/**
|
|
2369
|
+
* The holder count of a scope instance never changes: the role only moves by
|
|
2370
|
+
* transfer.
|
|
2371
|
+
*/
|
|
2046
2372
|
readonly transferOnly?: boolean;
|
|
2047
2373
|
/**
|
|
2048
|
-
* Roles a holder may assign and revoke. Once any role declares `assigns`,
|
|
2049
|
-
*
|
|
2374
|
+
* Roles a holder may assign and revoke. Once any role declares `assigns`, a
|
|
2375
|
+
* role nobody lists is assigned only by `meta.manageRoles` holders.
|
|
2050
2376
|
*/
|
|
2051
2377
|
readonly assigns?: readonly string[];
|
|
2052
|
-
/**
|
|
2378
|
+
/**
|
|
2379
|
+
* Membership kinds (`via`) that may hold the role; others hold it for
|
|
2380
|
+
* nothing.
|
|
2381
|
+
*/
|
|
2053
2382
|
readonly for?: readonly string[];
|
|
2054
2383
|
readonly meta?: RoleMeta;
|
|
2055
|
-
/**
|
|
2384
|
+
/**
|
|
2385
|
+
* Time-boxed activation: the role becomes eligible-only and `activate` mints
|
|
2386
|
+
* its membership.
|
|
2387
|
+
*/
|
|
2056
2388
|
readonly activation?: ActivationOption;
|
|
2057
2389
|
/** Reserved for restricted credentials; setting it throws until it ships. */
|
|
2058
2390
|
readonly restricted?: never;
|
|
@@ -2070,31 +2402,52 @@ type Grant = {
|
|
|
2070
2402
|
readonly check?: Condition;
|
|
2071
2403
|
readonly approval?: "human" | ApprovalRequirement;
|
|
2072
2404
|
readonly portable: boolean;
|
|
2073
|
-
/**
|
|
2405
|
+
/**
|
|
2406
|
+
* Set when `portable` is false only because the grant reads the relation
|
|
2407
|
+
* graph.
|
|
2408
|
+
*/
|
|
2074
2409
|
readonly graph?: true;
|
|
2075
2410
|
readonly closure?: ClosureGrantFn;
|
|
2076
2411
|
readonly limit?: GrantLimit;
|
|
2077
2412
|
readonly fields?: readonly string[];
|
|
2078
2413
|
readonly scope: GrantScope;
|
|
2079
|
-
/**
|
|
2414
|
+
/**
|
|
2415
|
+
* The grant's stable name: a `breakGlass` override lifts a named deny, and
|
|
2416
|
+
* `decision.matched.name` reports it.
|
|
2417
|
+
*/
|
|
2080
2418
|
readonly name?: string;
|
|
2081
2419
|
readonly group?: string;
|
|
2082
2420
|
readonly meta?: GrantMeta;
|
|
2083
2421
|
/** App obligations an allow adds to its granted decision. */
|
|
2084
2422
|
readonly obligations?: readonly AppObligation[];
|
|
2085
|
-
/**
|
|
2423
|
+
/**
|
|
2424
|
+
* Purposes of use that make the grant apply (`context.purpose`);
|
|
2425
|
+
* non-portable.
|
|
2426
|
+
*/
|
|
2086
2427
|
readonly purpose?: readonly string[];
|
|
2087
|
-
/**
|
|
2428
|
+
/**
|
|
2429
|
+
* Set on a break-glass allow: it overrides named denies and carries
|
|
2430
|
+
* obligations.
|
|
2431
|
+
*/
|
|
2088
2432
|
readonly breakGlass?: BreakGlassSpec;
|
|
2089
|
-
/**
|
|
2433
|
+
/**
|
|
2434
|
+
* The membership kind (`via`) this grant applies under; others never match
|
|
2435
|
+
* it.
|
|
2436
|
+
*/
|
|
2090
2437
|
readonly viaOnly?: MembershipVia;
|
|
2091
2438
|
/** Set only on a grant merged from a hosted policy document. */
|
|
2092
2439
|
readonly hosted?: HostedGrantRef;
|
|
2093
2440
|
/** When the grant applies; absent means always. */
|
|
2094
2441
|
readonly validity?: GrantValidity;
|
|
2095
|
-
/**
|
|
2442
|
+
/**
|
|
2443
|
+
* Set on a custom-role grant narrowed by a resource level
|
|
2444
|
+
* (`CustomRoleGrant.level`).
|
|
2445
|
+
*/
|
|
2096
2446
|
readonly level?: string;
|
|
2097
|
-
/**
|
|
2447
|
+
/**
|
|
2448
|
+
* The permission key the subject must also hold, through a role, on the row's
|
|
2449
|
+
* scope instance or globally.
|
|
2450
|
+
*/
|
|
2098
2451
|
readonly requires?: readonly string[];
|
|
2099
2452
|
};
|
|
2100
2453
|
/** Which hosted policy document and grant a merged grant came from. */
|
|
@@ -2114,13 +2467,22 @@ type RoleBinding<S extends string = string> = {
|
|
|
2114
2467
|
readonly assigns?: readonly string[];
|
|
2115
2468
|
readonly for?: readonly string[];
|
|
2116
2469
|
readonly meta?: RoleMeta;
|
|
2117
|
-
/**
|
|
2470
|
+
/**
|
|
2471
|
+
* Time-boxed activation: the role is eligible-only, and `activate` mints its
|
|
2472
|
+
* membership.
|
|
2473
|
+
*/
|
|
2118
2474
|
readonly activation?: ActivationSpec;
|
|
2119
|
-
/**
|
|
2475
|
+
/**
|
|
2476
|
+
* Support access: consent and `actorRequired` for a vendor-support
|
|
2477
|
+
* membership.
|
|
2478
|
+
*/
|
|
2120
2479
|
readonly support?: SupportSpec;
|
|
2121
2480
|
};
|
|
2122
2481
|
type ValidateMode = "boundary" | "always" | "never";
|
|
2123
|
-
/**
|
|
2482
|
+
/**
|
|
2483
|
+
* The declared scopes, in declaration order; empty when the policy declares
|
|
2484
|
+
* none.
|
|
2485
|
+
*/
|
|
2124
2486
|
type PolicyScopes = readonly Scope[];
|
|
2125
2487
|
type PolicyVocabulary = {
|
|
2126
2488
|
readonly permissions: PermissionTree;
|
|
@@ -2132,7 +2494,7 @@ type VocabularyFromInput<Input> = Input extends PolicyVocabulary ? Input : {
|
|
|
2132
2494
|
readonly roles?: RoleTree;
|
|
2133
2495
|
readonly plans?: PlanTree;
|
|
2134
2496
|
};
|
|
2135
|
-
type Policy<TUser = unknown, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary> = {
|
|
2497
|
+
type Policy<TUser = unknown, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary, S extends PolicyScopesInput = PolicyScopesInput> = {
|
|
2136
2498
|
readonly permissions: V["permissions"];
|
|
2137
2499
|
readonly roles: readonly RoleBinding[];
|
|
2138
2500
|
readonly rolesByName: ReadonlyMap<string, RoleBinding>;
|
|
@@ -2146,18 +2508,39 @@ type Policy<TUser = unknown, TPrincipal extends Principal = Principal, V extends
|
|
|
2146
2508
|
readonly onDenied?: (decision: unknown) => never | void;
|
|
2147
2509
|
readonly fingerprint: string;
|
|
2148
2510
|
readonly resources: ReadonlyMap<string, ResourceNode>;
|
|
2149
|
-
/**
|
|
2511
|
+
/**
|
|
2512
|
+
* The app data schemas `definePolicy` was given; symbol-keyed so freezing the
|
|
2513
|
+
* policy leaves the schemas alone.
|
|
2514
|
+
*/
|
|
2150
2515
|
readonly [POLICY_X]?: PolicyAppDataSchemas;
|
|
2516
|
+
readonly [POLICY_SCOPES]?: S;
|
|
2151
2517
|
readonly providers?: readonly DecisionProvider[];
|
|
2152
|
-
/**
|
|
2518
|
+
/**
|
|
2519
|
+
* Permission keys a hosted policy document may grant or deny; empty by
|
|
2520
|
+
* default.
|
|
2521
|
+
*/
|
|
2153
2522
|
readonly hostable: readonly string[];
|
|
2154
|
-
/**
|
|
2523
|
+
/**
|
|
2524
|
+
* Permission keys that deny with `stale-credentials` when the subject's token
|
|
2525
|
+
* is behind the source.
|
|
2526
|
+
*/
|
|
2155
2527
|
readonly fresh?: readonly string[];
|
|
2156
|
-
/**
|
|
2528
|
+
/**
|
|
2529
|
+
* Policy delegations in declaration order; absent or empty when the policy
|
|
2530
|
+
* declares none.
|
|
2531
|
+
*/
|
|
2157
2532
|
readonly delegations?: readonly PolicyDelegation[];
|
|
2158
|
-
/**
|
|
2533
|
+
/**
|
|
2534
|
+
* Grant levels by resource (`resource(…, { levels })`), normalised; absent
|
|
2535
|
+
* when none are declared.
|
|
2536
|
+
*/
|
|
2159
2537
|
readonly levels?: PolicyLevels;
|
|
2160
|
-
/**
|
|
2538
|
+
/** Resources declared with `orderedLevels: true`, sorted; absent when none. */
|
|
2539
|
+
readonly orderedLevels?: readonly string[];
|
|
2540
|
+
/**
|
|
2541
|
+
* Coarse OAuth scopes in declaration order; absent when the policy declares
|
|
2542
|
+
* none.
|
|
2543
|
+
*/
|
|
2161
2544
|
readonly oauthScopes?: readonly PolicyOAuthScope[];
|
|
2162
2545
|
readonly index: PolicyIndex;
|
|
2163
2546
|
};
|
|
@@ -2170,7 +2553,10 @@ type PolicyOAuthScope = {
|
|
|
2170
2553
|
readonly permissions: readonly string[];
|
|
2171
2554
|
readonly scopes: readonly string[];
|
|
2172
2555
|
};
|
|
2173
|
-
/**
|
|
2556
|
+
/**
|
|
2557
|
+
* Lookups built once per policy, so a decision does not rescan every role and
|
|
2558
|
+
* grant.
|
|
2559
|
+
*/
|
|
2174
2560
|
type PolicyIndex = {
|
|
2175
2561
|
readonly declaredRoles: ReadonlySet<string>;
|
|
2176
2562
|
readonly supports: readonly SupportSpec[];
|
|
@@ -2196,19 +2582,22 @@ type PolicyOptions<TUser, TPrincipal extends Principal, S extends PolicyScopesIn
|
|
|
2196
2582
|
readonly grants?: readonly (Omit<Grant, "role" | "scope"> | readonly Omit<Grant, "role" | "scope">[] | Grant)[];
|
|
2197
2583
|
/**
|
|
2198
2584
|
* Named scopes in order, each with the row field holding its id and an
|
|
2199
|
-
* optional parent (`within`, an earlier scope). `tenant` and `team` alias
|
|
2200
|
-
*
|
|
2585
|
+
* optional parent (`within`, an earlier scope). `tenant` and `team` alias the
|
|
2586
|
+
* first and second scope.
|
|
2201
2587
|
*/
|
|
2202
2588
|
readonly scopes?: S;
|
|
2203
|
-
/**
|
|
2589
|
+
/**
|
|
2590
|
+
* Maps the application's user to the principal PermDock decides for; `null`
|
|
2591
|
+
* is anonymous.
|
|
2592
|
+
*/
|
|
2204
2593
|
readonly subject: (user: TUser) => TPrincipal | null;
|
|
2205
2594
|
readonly context?: (user: TUser) => Readonly<Record<string, unknown>> | Promise<Readonly<Record<string, unknown>>>;
|
|
2206
2595
|
readonly validate?: ValidateMode;
|
|
2207
2596
|
readonly onDenied?: (decision: unknown) => never | void;
|
|
2208
2597
|
readonly providers?: readonly DecisionProvider[];
|
|
2209
2598
|
/**
|
|
2210
|
-
* Leaves or subtrees a hosted policy document (`PolicySource`) may touch.
|
|
2211
|
-
*
|
|
2599
|
+
* Leaves or subtrees a hosted policy document (`PolicySource`) may touch. The
|
|
2600
|
+
* default is none, so a policy without it ignores every hosted grant.
|
|
2212
2601
|
*/
|
|
2213
2602
|
readonly hostable?: readonly (Permission | PermissionTree)[];
|
|
2214
2603
|
/**
|
|
@@ -2219,8 +2608,8 @@ type PolicyOptions<TUser, TPrincipal extends Principal, S extends PolicyScopesIn
|
|
|
2219
2608
|
readonly fresh?: readonly (Permission | PermissionTree)[];
|
|
2220
2609
|
/**
|
|
2221
2610
|
* Standing delegations: holders of `from` let actors matching `to` use
|
|
2222
|
-
* `permissions` for them without a token saying so. A token delegation on
|
|
2223
|
-
*
|
|
2611
|
+
* `permissions` for them without a token saying so. A token delegation on the
|
|
2612
|
+
* call still applies as well; both must cover.
|
|
2224
2613
|
*/
|
|
2225
2614
|
readonly delegations?: readonly DelegationInput[];
|
|
2226
2615
|
/**
|