| 1 | import type * as AVP from "@distilled.cloud/aws/verifiedpermissions"; |
| 2 | import type * as Effect from "effect/Effect"; |
| 3 | import * as Binding from "../../Binding.ts"; |
| 4 | import type { PolicyStore } from "./PolicyStore.ts"; |
| 5 | |
| 6 | export interface IsAuthorizedRequest extends Omit< |
| 7 | AVP.IsAuthorizedInput, |
| 8 | "policyStoreId" |
| 9 | > {} |
| 10 | export interface IsAuthorizedWithTokenRequest extends Omit< |
| 11 | AVP.IsAuthorizedWithTokenInput, |
| 12 | "policyStoreId" |
| 13 | > {} |
| 14 | export interface BatchIsAuthorizedRequest extends Omit< |
| 15 | AVP.BatchIsAuthorizedInput, |
| 16 | "policyStoreId" |
| 17 | > {} |
| 18 | export interface BatchIsAuthorizedWithTokenRequest extends Omit< |
| 19 | AVP.BatchIsAuthorizedWithTokenInput, |
| 20 | "policyStoreId" |
| 21 | > {} |
| 22 | |
| 23 | /** |
| 24 | * The runtime authorization client returned by binding `IsAuthorized` to a |
| 25 | * `PolicyStore`. Each method injects the store's `policyStoreId` |
| 26 | * automatically. |
| 27 | */ |
| 28 | export interface IsAuthorizedClient { |
| 29 | /** |
| 30 | * Make a single authorization decision (`Allow` / `Deny`) for a principal, |
| 31 | * action, and resource against the store's policies. |
| 32 | */ |
| 33 | isAuthorized( |
| 34 | request: IsAuthorizedRequest, |
| 35 | ): Effect.Effect<AVP.IsAuthorizedOutput, AVP.IsAuthorizedError>; |
| 36 | /** |
| 37 | * Make an authorization decision where the principal is derived from a JWT |
| 38 | * (identity or access token) issued by a configured identity source. |
| 39 | */ |
| 40 | isAuthorizedWithToken( |
| 41 | request: IsAuthorizedWithTokenRequest, |
| 42 | ): Effect.Effect< |
| 43 | AVP.IsAuthorizedWithTokenOutput, |
| 44 | AVP.IsAuthorizedWithTokenError |
| 45 | >; |
| 46 | /** |
| 47 | * Make up to 30 authorization decisions in one call, sharing one principal |
| 48 | * or one resource across the batch. |
| 49 | */ |
| 50 | batchIsAuthorized( |
| 51 | request: BatchIsAuthorizedRequest, |
| 52 | ): Effect.Effect<AVP.BatchIsAuthorizedOutput, AVP.BatchIsAuthorizedError>; |
| 53 | /** |
| 54 | * Make up to 30 authorization decisions in one call for the principal |
| 55 | * derived from a JWT (identity or access token) issued by a configured |
| 56 | * identity source. |
| 57 | */ |
| 58 | batchIsAuthorizedWithToken( |
| 59 | request: BatchIsAuthorizedWithTokenRequest, |
| 60 | ): Effect.Effect< |
| 61 | AVP.BatchIsAuthorizedWithTokenOutput, |
| 62 | AVP.BatchIsAuthorizedWithTokenError |
| 63 | >; |
| 64 | } |
| 65 | |
| 66 | /** |
| 67 | * Runtime binding for Verified Permissions authorization — bind it to a |
| 68 | * `PolicyStore` inside a function runtime to get a client that evaluates |
| 69 | * authorization requests against the store's Cedar policies. |
| 70 | * |
| 71 | * This is the effectful-function DX for authorization: a Lambda calls |
| 72 | * `isAuthorized(...)` and Verified Permissions returns `Allow` or `Deny` |
| 73 | * along with the determining policies. |
| 74 | * ### Authorizing Requests |
| 75 | * **Example:** Decide a Request in a Lambda |
| 76 | * ```typescript |
| 77 | * // init |
| 78 | * const authz = yield* AWS.VerifiedPermissions.IsAuthorized(store); |
| 79 | * |
| 80 | * // runtime |
| 81 | * const { decision } = yield* authz.isAuthorized({ |
| 82 | * principal: { entityType: "PhotoApp::User", entityId: "alice" }, |
| 83 | * action: { actionType: "PhotoApp::Action", actionId: "viewPhoto" }, |
| 84 | * resource: { entityType: "PhotoApp::Photo", entityId: "vacation.jpg" }, |
| 85 | * }); |
| 86 | * // decision === "ALLOW" | "DENY" |
| 87 | * ``` |
| 88 | * |
| 89 | * **Example:** Decide from a JWT |
| 90 | * ```typescript |
| 91 | * const { decision } = yield* authz.isAuthorizedWithToken({ |
| 92 | * identityToken, |
| 93 | * action: { actionType: "PhotoApp::Action", actionId: "viewPhoto" }, |
| 94 | * resource: { entityType: "PhotoApp::Photo", entityId: "vacation.jpg" }, |
| 95 | * }); |
| 96 | * ``` |
| 97 | * |
| 98 | * @binding |
| 99 | */ |
| 100 | export interface IsAuthorized extends Binding.Service< |
| 101 | IsAuthorized, |
| 102 | "AWS.VerifiedPermissions.IsAuthorized", |
| 103 | <S extends PolicyStore>(store: S) => Effect.Effect<IsAuthorizedClient> |
| 104 | > {} |
| 105 | export const IsAuthorized = Binding.Service<IsAuthorized>( |
| 106 | "AWS.VerifiedPermissions.IsAuthorized", |
| 107 | ); |