import { type IAMClient } from "@aws-sdk/client-iam"; import { type Result } from "@fjall/generator"; import type { DeployCallbacks } from "../../types/callbacks.js"; export interface DeployBoundaryTeardownScope { /** * Partition of the session running the sweep, from its own STS caller ARN * (`resolveCallerPartition`). Required for the same reason the probe needs * it: a partition-pinned ARN would make the sweep read NoSuchEntity — * "policy not present" — and silently leave a live policy behind. */ partition: string; accountId: string; fjallOrgId: string; } export interface DeployBoundaryTeardownResult { deleted: boolean; /** * Identifier-only: IAM principal names (role / user / group) and static * literals, never error-derived text — the DeleteConflict arm reports a * fixed verdict, not the SDK message — so sinks need no mask * (security-standards § "Values, not identifiers"). */ reason: string; } /** * Reference-counted teardown of the account-global `FjallDeployBoundary` * managed policy. * * The policy is written by the `Custom::FjallDeployBoundary` adopt-or-create * resource, whose Delete handler deliberately leaves it in place: once * `cdk bootstrap --custom-permissions-boundary` has capped the CDK * cfn-exec-role with the same policy, IAM refuses to delete it (DeleteConflict) * from inside any stack, and the cfn-exec-role reference lives outside every * stack anyway. End-of-life removal therefore belongs here, after the account * stack — and with it the FjallDeploy role — is gone. * * Deletes only when `ListEntitiesForPolicy` — unfiltered, so a role carrying * the policy as an attached permissions policy counts exactly as a bounded * one does — lists NO role, user or group. It never un-caps a role: removing * the boundary from a bootstrapped cfn-exec-role would drift the CDKToolkit * stack's `InputPermissionsBoundary` and re-widen a role that outlives this * destroy. Non-default versions are deleted only once that count is empty: * IAM refuses `DeletePolicy` while any exist, and on a policy still in force * they are the administrator's `SetDefaultPolicyVersion` rollback history. * * Failure messages stay raw — callers mask at their output boundary. */ export declare function deleteDeployBoundaryIfUnreferenced(client: IAMClient, scope: DeployBoundaryTeardownScope, abortSignal?: AbortSignal): Promise>; /** * Best-effort wrapper around {@link deleteDeployBoundaryIfUnreferenced}: * surfaces the outcome via callbacks/logger and swallows failures. A cleanup * miss leaves a harmless orphaned policy (a later reconnect adopts it) and * must never block a teardown. A retention that names a referrer is an * operator action (the default seam-2 estate keeps the policy alive through * the bootstrapped cfn-exec-role until the CDKToolkit stacks go), so it * reaches the destroy transcript; an absent policy or an abort stays at debug. */ export declare function cleanupOrphanedDeployBoundary(client: IAMClient, scope: DeployBoundaryTeardownScope, callbacks: DeployCallbacks, abortSignal?: AbortSignal): Promise;