import type { Context } from "../context.ts"; import { type AccessRule } from "./access-rule.ts"; import { type CloudflareApiOptions } from "./api.ts"; /** * Access decision a policy applies when its rules match. * - `allow`: grant access when an authenticated user matches `include`. * - `deny`: deny access when matched. * - `non_identity`: allow without identity (e.g. service tokens, IP allowlists). * - `bypass`: skip Access entirely (no auth required). */ export type AccessPolicyDecision = "allow" | "deny" | "non_identity" | "bypass"; /** * An approval group authorising an access request when * `approvalRequired: true`. */ export interface AccessPolicyApprovalGroup { /** Number of approvals required from this group. */ approvalsNeeded: number; /** Email addresses of approvers. */ emailAddresses?: string[]; /** UUID of an Access email list. */ emailListUuid?: string; } /** * Optional MFA enforcement on top of the IdP's authentication. */ export interface AccessPolicyMfaConfig { allowedAuthenticators?: string[]; mfaDisabled?: boolean; /** Cloudflare duration string, e.g. `"30m"`. */ sessionDuration?: string; } /** * Connection-protocol-specific options (currently only RDP clipboard * formats are supported by Cloudflare). */ export interface AccessPolicyConnectionRules { rdp?: { allowedClipboardFormats?: ("text" | "image" | "files")[]; }; } /** * Properties for creating or updating an {@link AccessPolicy}. */ export interface AccessPolicyProps extends CloudflareApiOptions { /** * Display name of the policy. * * @default ${app}-${stage}-${id} */ name?: string; /** * Decision the policy applies. **Immutable** — changing the decision will * trigger replacement of the underlying Cloudflare resource. */ decision: AccessPolicyDecision; /** * Rules a request must match to be considered (OR logic). Must be * non-empty — Cloudflare rejects policies with no include rules. */ include: AccessRule[]; /** * Rules that, when matched, exclude the request from this policy. */ exclude?: AccessRule[]; /** * Rules that must additionally match (AND logic). */ require?: AccessRule[]; /** * Require explicit approval before granting access. */ approvalRequired?: boolean; /** * Approver groups consulted when `approvalRequired: true`. */ approvalGroups?: AccessPolicyApprovalGroup[]; /** * Prompt the user for a purpose justification on each access. */ purposeJustificationRequired?: boolean; /** * Prompt text shown when `purposeJustificationRequired` is true. */ purposeJustificationPrompt?: string; /** * Force isolated browser rendering for this policy. */ isolationRequired?: boolean; /** * Optional MFA enforcement. */ mfaConfig?: AccessPolicyMfaConfig; /** * Override the default Access session duration (Cloudflare duration string). */ sessionDuration?: string; /** * Per-protocol connection rules (e.g. RDP clipboard restrictions). */ connectionRules?: AccessPolicyConnectionRules; /** * Adopt an existing policy with the same name instead of failing. * * @default false */ adopt?: boolean; /** * Whether to delete the policy when removed from Alchemy. * * @default true */ delete?: boolean; } /** * Output for an {@link AccessPolicy}. */ export type AccessPolicy = Omit & { /** Cloudflare-assigned policy UUID. */ id: string; /** Display name. */ name: string; /** Number of applications currently referencing this policy. */ appCount: number; /** ISO 8601 creation timestamp. */ createdAt: string; /** ISO 8601 last-update timestamp. */ updatedAt: string; }; /** * Type guard for {@link AccessPolicy}. */ export declare function isAccessPolicy(resource: any): resource is AccessPolicy; /** * Creates a reusable Cloudflare Zero Trust [Access policy](https://developers.cloudflare.com/cloudflare-one/policies/access/) * that can be attached to one or more {@link AccessApplication} resources. * * @example * // Allow employees from a specific email domain. * const employees = await AccessPolicy("employees", { * name: "Employees", * decision: "allow", * include: [{ email_domain: { domain: "acme.com" } }], * }); * * @example * // Bypass Access for an office IP range. * const officeBypass = await AccessPolicy("office-bypass", { * name: "Office Bypass", * decision: "bypass", * include: [{ ip: { ip: "203.0.113.0/24" } }], * }); * * @example * // Reference an AccessGroup and require approval. * const sensitive = await AccessPolicy("sensitive", { * name: "Sensitive admin access", * decision: "allow", * include: [{ group: { id: adminGroup } }], * approvalRequired: true, * approvalGroups: [ * { approvalsNeeded: 2, emailAddresses: ["security@acme.com"] }, * ], * isolationRequired: true, * }); */ export declare const AccessPolicy: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context, id: string, props: AccessPolicyProps) => Promise); //# sourceMappingURL=access-policy.d.ts.map