import type { Context } from "../context.ts"; import { type AccessRule } from "./access-rule.ts"; import { type CloudflareApiOptions } from "./api.ts"; /** * Properties for creating or updating an {@link AccessGroup}. */ export interface AccessGroupProps extends CloudflareApiOptions { /** * Display name of the group. * * @default ${app}-${stage}-${id} */ name?: string; /** * Rules that grant membership (OR logic — any match includes the user). */ include?: AccessRule[]; /** * Rules that revoke membership when matched. */ exclude?: AccessRule[]; /** * Rules that must additionally match for membership (AND logic). */ require?: AccessRule[]; /** * Mark this group as the account default. Default groups apply to every * Access application unless explicitly overridden. * * @default false */ isDefault?: boolean; /** * Adopt an existing group with the same name instead of failing. * * @default false */ adopt?: boolean; /** * Whether to delete the group when removed from Alchemy. * * @default true */ delete?: boolean; } /** * Output for an {@link AccessGroup}. */ export type AccessGroup = Omit & { /** Cloudflare-assigned group UUID. */ id: string; /** Display name. */ name: string; /** ISO 8601 creation timestamp. */ createdAt: string; /** ISO 8601 last-update timestamp. */ updatedAt: string; }; /** * Type guard for {@link AccessGroup}. */ export declare function isAccessGroup(resource: any): resource is AccessGroup; /** * Creates a Cloudflare Zero Trust [Access group](https://developers.cloudflare.com/cloudflare-one/identity/users/groups/), * a reusable bundle of rules that can be referenced by Access policies. * * @example * // Engineering team by email domain. * const engineering = await AccessGroup("engineering", { * name: "Engineering", * include: [{ email_domain: { domain: "acme.com" } }], * }); * * @example * // Allow a managed IP list, exclude one specific IP. * const officeIps = await AccessGroup("office", { * name: "Office IPs", * include: [{ ip_list: { id: "" } }], * exclude: [{ ip: { ip: "203.0.113.99/32" } }], * }); * * @example * // Compose groups: admins are engineers who are also on-call. Resources * // can be passed directly — Alchemy lifts `.id` at the wire boundary. * const onCall = await AccessGroup("on-call", { * include: [{ email_domain: { domain: "acme.com" } }], * }); * const admins = await AccessGroup("admins", { * include: [{ group: { id: engineering } }], * require: [{ group: { id: onCall } }], * }); * * @example * // IdP-bound rules — match Okta groups via an AccessIdentityProvider. * const okta = await AccessIdentityProvider("okta", { * type: "okta", * name: "Acme Okta", * oktaAccount: "acme.okta.com", * clientId: "...", * clientSecret: alchemy.secret.env.OKTA_SECRET, * }); * const sre = await AccessGroup("sre", { * include: [{ okta: { name: "sre", identity_provider_id: okta } }], * }); * * @example * // Account default — applied implicitly to every Access application. * await AccessGroup("default-deny", { * isDefault: true, * include: [{ everyone: {} }], * exclude: [{ email_domain: { domain: "acme.com" } }], * }); */ export declare const AccessGroup: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context, id: string, props: AccessGroupProps) => Promise); //# sourceMappingURL=access-group.d.ts.map