Package: cfn-policy-validator
IAM Policy Validator for AWS CloudFormationA command line tool that takes a CloudFormation template, parses the IAM policies attached to IAM roles, users, groups, and resources then runs them through IAM Access Analyzer for basic policy validation checks and for custom policy checks. Note that a charge is associated with each custom policy check. For more details about pricing, seeIAM Access Analyzer pricing.Getting StartedInstallation:Python 3.6+ is supported.pip install cfn-policy-validatorBasic usage:cfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1Interactive workshop that walks through use of the cfn-policy-validator tool in a CI/CD pipeline:https://workshops.aws/card/Integrating%20IAM%20Access%20AnalyzerWhy do I need the IAM Policy Validator for AWS CloudFormation?The cfn-policy-validator is designed to prevent the deployment of unwanted IAM identity-based and resource-based policies to your AWS environment.CloudFormation templates commonly useintrinsic functionsin templates that create least privilege IAM policies.  Take a look at the template below which creates an SQS queue with an attached SQS queue policy.{"Resources":{"MyQueue":{"Type":"AWS::SQS::Queue"},"MyQueuePolicy":{"Type":"AWS::SQS::QueuePolicy","Properties":{"PolicyDocument":{"Version":"2012-10-17","Statement":[{"Action":["sqs:SendMessage","sqs:ReceiveMessage"],"Effect":"Allow","Resource":{"Fn::GetAtt":["MyQueue","Arn"]},"Principal":"*"}]},"Queues":[{"Ref":"MyQueue"}]}}}}Extracting the queue policy from this template as is would not give you a valid IAM policy.  The lineFn:GetAtt: ["MyQueue", "Arn"]is not valid IAM policy syntax - this is syntax specific to CloudFormation. The IAM Policy Validator for AWS CloudFormation (cfn-policy-validator) evaluates these intrinsic functions, like Fn:GetAtt, substituting similar or identical values to what you will get when you deploy the template.  This allows it to extract the IAM policies from the template and send them to IAM Access Analyzer, which validates the policies against checks for best practices, external access, and your custom security standard.The cfn-policy-validator returns a non-zero exit code when findings in IAM policies are detected and is designed to be run in a CI/CD pipeline to prevent the deployment of unwanted IAM policies to your AWS environment.Available Commandsvalidatecfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1Parses IAM identity-based and resource-based policies from AWS CloudFormation templates and evaluated CloudFormation intrinsic functions and pseudo parameters. Then runs the policies through IAM Access Analyzer for validation. Returns the findings from validation in JSON format.
Exits with a non-zero error code if any findings categorized as blocking are found in your template.  Exits with an error code of zero if all findings are non-blocking or there are no findings.ArgumentsRequiredOptionsDescription--template-pathYesFILE_NAMEThe path to the CloudFormation template.--regionYesREGIONThe destination region the resources will be deployed to.--parametersKEY=VALUE [KEY=VALUE ...]Keys and values for CloudFormation template parameters.  Only parameters that are referenced by IAM policies in the template are required.--template-configuration-fileFILE_PATH.jsonA JSON formatted file that specifies template parameter values, a stack policy, and tags. Only parameters are used from this file.  Everything else is ignored. Identical values passed in the --parameters flag override parameters in this file. See CloudFormation documentation for file format:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15--profilePROFILEThe named profile to use for AWS API calls.--enable-loggingEnables log output to stdout--ignore-findingFINDING_CODE,RESOURCE_NAME,RESOURCE_NAME.FINDING_CODEAllow validation failures to be ignored. Specify as a comma separated list of findings to be ignored. Can be individual finding codes (e.g. "PASS_ROLE_WITH_STAR_IN_RESOURCE"), a specific resource name (e.g. "MyResource"), or a combination of both separated by a period.(e.g. "MyResource.PASS_ROLE_WITH_STAR_IN_RESOURCE").  Names of finding codes may change in IAM Access Analyzer over time.--treat-finding-type-as-blockingERROR,SECURITY_WARNING,WARNING,SUGGESTION,NONESpecify which finding types should be treated as blocking. Other finding types are treated as nonblocking.  If the tool detects any blocking finding types, it will exit with a non-zero exit code.  If all findings are nonblocking or there are no findings, the tool exits with an exit code of 0.  Defaults to "ERROR" and "SECURITY_WARNING". Specify as a comma separated list of finding types that should be blocking. Pass "NONE" to ignore all findings.--allow-external-principalsACCOUNT,ARNA comma separated list of external principals that should be ignored.  Specify as a comma separated list of a 12 digit AWS account ID, a federated web identity user, a federated SAML user, or an ARN. Specify "*" to allow anonymous access. (e.g. 123456789123,arn:aws:iam::111111111111:role/MyOtherRole,graph.facebook.com)--allow-dynamic-ref-without-versionOverride the default behavior and allow dynamic SSM references without version numbers.  The version number ensures that the SSM parameter value that was validated is the one that is deployed.--exclude-resource-typesAWS::SERVICE::RESOURCE, AWS::SERVICE::RESOURCEList of comma-separated resource types. Resource types should be the same as Cloudformation template resource names such as AWS::IAM::Role, AWS::S3::Bucketcheck-no-new-accesscfn-policy-validatorcheck-no-new-access--template-path./my-template.json--regionus-east-1--reference-policy./my-reference-policy.json--reference-policy-typeidentityParses IAM identity-based and resource-based policies from AWS CloudFormation templates and evaluated CloudFormation intrinsic functions and pseudo parameters. Then runs the policies through IAM Access Analyzer for a custom check against a reference policy. Returns the findings from the custom check in JSON format. Exits with a non-zero error code if any findings categorized as blocking, based on new access, are found in your template. Exits with an error code of zero if all findings are non-blocking or there are no findings. You can find examples for reference policies and learn how to set up and run a custom policy check for new access in theIAM Access Analyzer custom policy checks samplesrepository on GitHub.ArgumentsRequiredOptionsDescription--template-pathYesFILE_NAMEThe path to the CloudFormation template.--regionYesREGIONThe destination region the resources will be deployed to.--parametersKEY=VALUE [KEY=VALUE ...]Keys and values for CloudFormation template parameters.  Only parameters that are referenced by IAM policies in the template are required.--template-configuration-fileFILE_PATH.jsonA JSON formatted file that specifies template parameter values, a stack policy, and tags. Only parameters are used from this file.  Everything else is ignored. Identical values passed in the --parameters flag override parameters in this file. See CloudFormation documentation for file format:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15--profilePROFILEThe named profile to use for AWS API calls.--enable-loggingEnables log output to stdout--ignore-findingFINDING_CODE,RESOURCE_NAME,RESOURCE_NAME.FINDING_CODEAllow validation failures to be ignored. Specify as a comma separated list of findings to be ignored. Can be individual finding codes (e.g. "PASS_ROLE_WITH_STAR_IN_RESOURCE"), a specific resource name (e.g. "MyResource"), or a combination of both separated by a period.(e.g. "MyResource.PASS_ROLE_WITH_STAR_IN_RESOURCE").  Names of finding codes may change in IAM Access Analyzer over time.--reference-policyYesFILE_PATH.jsonA JSON formatted file that specifies the path to the reference policy that is used for a permissions comparison.--reference-policy-typeYesIDENTITY or RESOURCEThe policy type associated with the IAM policy under analysis and the reference policy.--treat-findings-as-non-blockingWhen not specified, the tool detects any findings, it will exit with a non-zero exit code. When specified, the tool exits with an exit code of 0.--allow-dynamic-ref-without-versionOverride the default behavior and allow dynamic SSM references without version numbers.  The version number ensures that the SSM parameter value that was validated is the one that is deployed.--exclude-resource-typesAWS::SERVICE::RESOURCE, AWS::SERVICE::RESOURCEList of comma-separated resource types. Resource types should be the same as Cloudformation template resource names such as AWS::IAM::Role, AWS::S3::Bucketcheck-access-not-grantedcfn-policy-validatorcheck-access-not-granted--template-path./my-template.json--regionus-east-1--actions"secretsmanager:DeleteSecret"Parses IAM identity-based and resource-based policies from AWS CloudFormation templates and evaluated CloudFormation intrinsic functions and pseudo parameters. Then runs the policies through IAM Access Analyzer for a custom check against a list of IAM actions. Returns the findings from the custom check in JSON format. Exits with a non-zero error code if any findings categorized as blocking, based on access granted to at least one of the listed IAM actions, are found in your template. Exits with an error code of zero if all findings are non-blocking or there are no findings.ArgumentsRequiredOptionsDescription--template-pathYesFILE_NAMEThe path to the CloudFormation template.--regionYesREGIONThe destination region the resources will be deployed to.--parametersKEY=VALUE [KEY=VALUE ...]Keys and values for CloudFormation template parameters.  Only parameters that are referenced by IAM policies in the template are required.--template-configuration-fileFILE_PATH.jsonA JSON formatted file that specifies template parameter values, a stack policy, and tags. Only parameters are used from this file.  Everything else is ignored. Identical values passed in the --parameters flag override parameters in this file. See CloudFormation documentation for file format:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15--profilePROFILEThe named profile to use for AWS API calls.--enable-loggingEnables log output to stdout--ignore-findingFINDING_CODE,RESOURCE_NAME,RESOURCE_NAME.FINDING_CODEAllow validation failures to be ignored. Specify as a comma separated list of findings to be ignored. Can be individual finding codes (e.g. "PASS_ROLE_WITH_STAR_IN_RESOURCE"), a specific resource name (e.g. "MyResource"), or a combination of both separated by a period.(e.g. "MyResource.PASS_ROLE_WITH_STAR_IN_RESOURCE").  Names of finding codes may change in IAM Access Analyzer over time.--actionsYesACTION,ACTION,ACTIONList of comma-separated actions.--treat-findings-as-non-blockingWhen not specified, the tool detects any findings, it will exit with a non-zero exit code. When specified, the tool exits with an exit code of 0.--allow-dynamic-ref-without-versionOverride the default behavior and allow dynamic SSM references without version numbers.  The version number ensures that the SSM parameter value that was validated is the one that is deployed.--exclude-resource-typesAWS::SERVICE::RESOURCE, AWS::SERVICE::RESOURCEList of comma-separated resource types. Resource types should be the same as Cloudformation template resource names such as AWS::IAM::Role, AWS::S3::Bucketparsecfn-policy-validatorparse--template-path./my-template.json--regionus-east-1Parses IAM identity-based and resource-based policies from AWS CloudFormation templates and evaluates CloudFormation intrinsic functions and pseudo parameters.  Returns the parsed file in JSON format.  This command does not make any calls to IAM Access Analyzer.  Parse can be a useful troubleshooting tool or useful if you just want the CloudFormation function evaluation.ArgumentsRequiredOptionsDescription--template-pathYesFILE_NAMEThe path to the CloudFormation template.--regionYesREGIONThe destination region the resources will be deployed to.--parametersKEY=VALUE [KEY=VALUE ...]Keys and values for CloudFormation template parameters.  Only parameters that are referenced by IAM policies in the template are required.--template-configuration-fileFILE_PATH.jsonA JSON formatted file that specifies template parameter values, a stack policy, and tags. Everything except for parameters are ignored from this file. Identical values passed in the --parameters flag override parameters in this file. See CloudFormation documentation for file format:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15--profilePROFILEThe named profile to use for AWS API calls.--enable-loggingEnables log output to stdout--allow-dynamic-ref-without-versionOverride the default behavior and allow dynamic SSM references without version numbers.  The version number ensures that the SSM parameter value that was validated is the one that is deployed.--exclude-resource-typesAWS::SERVICE::RESOURCE, AWS::SERVICE::RESOURCEList of comma-separated resource types. Resource types should be the same as Cloudformation template resource names such as AWS::IAM::Role, AWS::S3::BucketSupported resource-based policiesCloudFormation Resource TypePolicy best practice checksAccess previews (check for external access)AWS::KMS::KeyxxAWS::Lambda::PermissionxAWS::Lambda::LayerVersionPermissionxAWS::S3::BucketPolicyxxAWS::S3::AccessPointxxAWS::S3::MultiRegionAccessPointxxAWS::SQS::QueuePolicyxxAWS::SNS::TopicPolicyxAWS::SecretsManager::ResourcePolicyxAWS::IAM::Role (trust policy)xxIntrinsic function and Pseudo parameter supportThe functions in the following list can be used within IAM identity-based or resource-based policies.  The tool only attempts to evaluate intrinsic functions within policies, so you can still use intrinsic functions not on this list elsewhere in your template.Supported intrinsic functionsFn::FindInMapFn::GetAttFn::ImportValueFn::JoinFn::SelectFn::SplitFn::SubRefFn::IfFn::EqualsConditionFn::NotFn::AndFn::OrSupported pseudo parameters:AWS::RegionAWS::AccountIdAWS::PartitionAWS::StackName (returns the literal string "StackName")AWS::NoValueDynamic SSM referencesare supported, but must have a version number.  This is to help ensure the same parameter that is validated is the one that is deployed.  This restriction can be overridden with the --allow-dynamic-ref-without-version argument.SSM-Secure and SecretsManager dynamic references are not yet supported.Notes:Fn::Transform (includes macros and AWS::Serverless/SAM transforms) not yet supportedReferences (Ref/GetAtt) to CloudFormation modules are not yet supportedAcondition functionmay have different behavior when deployed if you use theReffunction in the condition. This is because the tool is unable to accurately provide a value for references that are not known until deployment.CredentialsThe cfn-policy-validator should be run using credentials from the AWS account that you plan to deploy the CloudFormation template to. The tool uses boto3 to interact with your AWS account. You can use one of the following methods to specify credentials:Environment variablesShared credential file (~/.aws/credentials)AWS config file (~/.aws/config)Assume Role providerInstance metadata service on an Amazon EC2 instance that has an IAM role configured.Read more about these optionsYou can also specify anamed profileusing the --profile command line flag.The principal used to execute the cfn-policy-validator requires the following permissions.IAM policy required to run the IAM Policy Validator for AWS CloudFormation{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["iam:GetPolicy","iam:GetPolicyVersion","access-analyzer:ListAnalyzers","access-analyzer:ValidatePolicy","access-analyzer:CreateAccessPreview","access-analyzer:GetAccessPreview","access-analyzer:ListAccessPreviewFindings","access-analyzer:CreateAnalyzer","access-analyzer:CheckNoNewAccess","access-analyzer:CheckAccessNotGranted","s3:ListAllMyBuckets","cloudformation:ListExports","ssm:GetParameter"],"Resource":"*"},{"Effect":"Allow","Action":"iam:CreateServiceLinkedRole","Resource":"*","Condition":{"StringEquals":{"iam:AWSServiceName":"access-analyzer.amazonaws.com"}}}]}Action NameJustificationiam:GetPolicyRead IAM managed policies from your environment if included in an IAM user, role, or group.iam:GetPolicyVersionRead IAM managed policies from your environment if included in an IAM user, role, or group.access-analyzer:ListAnalyzersDetect if there is an existing analyzer in your account.access-analyzer:ValidatePolicyCalled for each policy to validate against IAM policy best practices.access-analyzer:CreateAccessPreviewGenerate access previews.access-analyzer:GetAccessPreviewRetrieve generated access previews.access-analyzer:ListAccessPreviewFindingsRetrieve findings from access preview.access-analyzer:CreateAnalyzer(Optional) Create an analyzer if one does not already exist in the account.  Optional if account has analyzer already.access-analyzer:CheckNoNewAccessCalled for each policy to validate against a reference policy to compare permissions.access-analyzer:CheckAccessNotGrantedCalled for each policy to validate that it does not grant access to a list of IAM actions, considered as critical permissions, provided as input.iam:CreateServiceLinkedRole(Optional) Create a service linked role if an analyzer must be created in account.  Optional if account has analyzer already.s3:ListAllMyBucketsRetrieve the canonical ID of the account.cloudformation:ListExportsList CloudFormation exports to be used with Fn::ImportValuessm:GetParameterResolution of dynamic ssm parameter referencesFAQHow does the validator deal with intrinsic functions within policies?One of the biggest challenges of parsing IAM policies within a CloudFormation template is dealing with Ref and Fn::GetAtt references to other resources within the template. These references commonly return ARNs whose exact value is unknown until the resource is created.The tool deals with this by autogenerating appropriate ARNs for the referenced resource.  The autogenerated ARN will have a valid ARN structure for that resource and a randomly generated name.  The tool can do this and still provide valid IAM finding results because the structure of the ARN is what is important, not the value of the resource name.The tool maps AWS CloudFormation resource types to ARN patterns and does token replacement on the patterns.  The mapping can be seen in cfn_policy_validator/parsers/utils/cfn_to_arn_map.jsonWhat happens if I don't have an existing analyzer in the account?The cfn-policy-validator will create an analyzer for you if you don't have one in your account.  Analyzers for access previews are per account and not per organization.Why does my S3 bucket policy not report a finding even though the policy makes it publicly accessible?Access previews take in the entire context of your AWS account, not just the S3 bucket policy.  If your account level block public access flag is enabled, IAM Access Analyzer correctly classifies your bucket as not publicly accessible and no findings are reported.Why does my SecretsManager Secret not report a finding even though the policy makes it publicly accessible?Creating an access preview for a SecretsManager Secret requires a KMSKeyId.  The cfn-policy-validator does not yet support parsing the KMS Key from the environment.  When no KMSKeyId is supplied, the CreateAccessPreview API uses the default CMK in the account which is not externally accessible.ExamplesBasic validate callcfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1Basic custom policy check callscfn-policy-validatorcheck-no-new-access--template-path./my-template.json--regionus-east-1--reference-policy./my-reference-policy.json--reference-policy-typeidentity
cfn-policy-validatorcheck-access-not-granted--template-path./my-template.json--regionus-east-1--actions"secretsmanager:DeleteSecret"Basic parse callcfn-policy-validatorparse--template-path./my-template.json--regionus-east-1Validate with parameterscfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--parametersMyParameter1=MyValue1MyParameter2=MyValue2Custom policy check with parameterscfn-policy-validatorcheck-no-new-access--template-path./my-template.json--regionus-east-1--reference-policy./my-reference-policy.json--reference-policy-typeidentity--parametersMyParameter1=MyValue1MyParameter2=MyValue2
cfn-policy-validatorcheck-access-not-granted--template-path./my-template.json--regionus-east-1--actions"secretsmanager:DeleteSecret"--parametersMyParameter1=MyValue1MyParameter2=MyValue2Validate with template configuration filecfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--template-configuration-file./template-configuration-file.jsonValidate and ignore findings for a specific finding code for all resourcescfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--ignore-findingPASS_ROLE_WITH_STAR_IN_RESOURCEValidate and ignore findings for a specific resourcecfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--ignore-findingMyResource1Custom policy check and ignore findings for a specific resourcecfn-policy-validatorcheck-no-new-access--template-path./my-template.json--regionus-east-1--reference-policy./my-reference-policy.json--reference-policy-typeidentity--ignore-findingsMyResource1
cfn-policy-validatorcheck-access-not-granted--template-path./my-template.json--regionus-east-1--actions"secretsmanager:DeleteSecret"--ignore-findingsMyResource1Validate and ignore all findings forMyResource1and finding codePASS_ROLE_WITH_STAR_IN_RESOURCEfor all resourcescfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--ignore-findingMyResource1,PASS_ROLE_WITH_STAR_IN_RESOURCEValidate and treat warnings as blocking in addition to ERROR and SECURITY_WARNING (defaults)cfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--treat-finding-type-as-blockingERROR,SECURITY_WARNING,WARNINGCustom policy check and treat findings as non-blockingcfn-policy-validatorcheck-no-new-access--template-path./my-template.json--regionus-east-1--reference-policy./my-reference-policy.json--reference-policy-typeidentity--treat-findings-as-non-blocking
cfn-policy-validatorcheck-access-not-granted--template-path./my-template.json--regionus-east-1--actions"secretsmanager:DeleteSecret"--ignore-findingsMyResource1--treat-findings-as-non-blockingValidate and ignore findings from account 123456789123 for cross account accesscfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--allow-external-principals123456789123Validate and ignore findings from a role in another accountcfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--allow-external-principalsarn:aws:iam::111111111111:role/MyOtherRoleValidate and allow anonymous access (this is usually not what you want, make sure you have a good reason to allow anonymous access)cfn-policy-validatorvalidate--template-path./my-template.json--regionus-east-1--allow-external-principals"*"