/** * IAM coverage engine for template-level permission-gap checks (TL-PERM-*). * * Pure functions over synthesized template JSON - no I/O, no network, no * dependencies beyond the shared types. Everything runs client-side. * * Design stance: these helpers answer "does this role PROVABLY have zero * coverage for this service/resource?" - so coverage matching is deliberately * generous. Anything unresolvable, conditional, or unknown counts as covered * (or marks the whole role indeterminate), because the TL-PERM rules must only * fire on provable gaps. Known false-negative tradeoff: a literal same-service * ARN is treated as covering any target in that service, since in-template * resources rarely have statically knowable literal ARNs. */ import type { CloudFormationResource } from '../../../types/analysis.types'; /** * Map of well-known AWS managed policy ARN patterns to the permissions they grant. * ARN patterns use regex to handle partition wildcards. */ export declare const KNOWN_MANAGED_POLICY_PERMISSIONS: Array<{ pattern: RegExp; name: string; actions: string[]; }>; /** * Check if an inline action is covered by a managed policy action. * Handles wildcard patterns like "s3:*" covering "s3:GetObject", * and "s3:Get*" covering "s3:GetObject". */ export declare const isActionCoveredBy: (inlineAction: string, managedAction: string) => boolean; /** * Resource types the TL-PERM checks understand as access targets, mapped to * the IAM action namespace and the ARN service segment used for matching. */ export declare const SERVICE_TARGET_TYPES: Record; /** * All Effect:Allow statements reachable from a role, with an indeterminate * flag for anything the engine cannot statically evaluate. */ export interface EffectiveRoleStatements { /** * Allow statements from the role's inline policies, attached * AWS::IAM::Policy resources, in-template managed policies, and synthetic * statements ({ Action, Resource: '*' }) derived from well-known AWS * managed policy ARNs. */ statements: Array>; /** * True when coverage cannot be determined: unknown managed policy ARN, * Fn::If inside policy material, or malformed policy documents. * Callers MUST treat indeterminate as fully covered (skip, no finding). */ indeterminate: boolean; } /** * Strict reference-edge collector. Unlike findAllReferencedResources, plain * strings equal to a logical id are NOT edges (values like table *names* * appear as strings without being template references), and Fn::Sub * placeholders ARE parsed (both string and [template, vars] forms). */ export declare const collectReferenceEdges: (value: unknown, allResourceIds: Set) => Set; /** * Collect the PolicyDocuments of standalone AWS::IAM::Policy resources * attached to a role via Roles: [{ Ref: roleId }] (the CDK DefaultPolicy * shape) or a literal logical-id string. */ export declare const getAttachedPolicyDocuments: (roleId: string, resources: Record) => Array<{ name: string; document: unknown; }>; /** * Gather every Allow statement effective on a role: inline Policies, attached * AWS::IAM::Policy resources, in-template AWS::IAM::ManagedPolicy documents, * and synthetic statements for well-known AWS managed policy ARNs. * PermissionsBoundary is ignored - it can only restrict, never grant, so it * is irrelevant to a zero-coverage rule. */ export declare const collectEffectiveRoleStatements: (roleId: string, resources: Record) => EffectiveRoleStatements; /** * Does one entry of a statement's Resource cover the target resource? * Generous by design - see module header. */ export declare const statementResourceCoversTarget: (resourceEntry: unknown, targetLogicalId: string, arnService: string, allResourceIds: Set) => boolean; /** * Does the role grant ANY action in the service namespace on the target? * Indeterminate roles always count as covering. */ export declare const roleCoversAnyServiceAction: (effective: EffectiveRoleStatements, servicePrefix: string, arnService: string, targetLogicalId: string, allResourceIds: Set) => boolean; /** * Does the role grant one SPECIFIC action (e.g. "sqs:ReceiveMessage") on the * target? Indeterminate roles always count as covering. */ export declare const roleCoversAction: (effective: EffectiveRoleStatements, requiredAction: string, arnService: string, targetLogicalId: string, allResourceIds: Set) => boolean; /** * Is there an in-template resource-side policy attached to the target that * mentions the role? Access can be granted from the resource side (bucket * policy naming the role's ARN, etc.) - deliberately loose matching (any * reference to the role anywhere in the policy document), erring toward * covered. */ export declare const hasResourceSidePolicyGrant: (targetLogicalId: string, roleId: string, resources: Record) => boolean;