From 38b5c2ddcbdc5fcef556782a1962f2f99be0330d Mon Sep 17 00:00:00 2001 From: Josh Fried <112121129+joshfried-aws@users.noreply.github.com> Date: Thu, 23 Mar 2023 14:22:18 -0400 Subject: [PATCH] bumping up to 3.0.0-alpha (#347) * bumping up to 3.0.0 alpha * typo * updating workflow --- .github/workflows/pr.yml | 18 +++-- Cargo.lock | 6 +- README.md | 108 ++++++++++++++-------------- guard-ffi/Cargo.toml | 5 +- guard-lambda/Cargo.toml | 4 +- guard/Cargo.toml | 2 +- guard/README.md | 148 ++++++++++++++++++++++----------------- 7 files changed, 152 insertions(+), 139 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index b950c7dd2..3a828333a 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: [ main, development ] + branches: [ main, development, rogue_one] pull_request: - branches: [ main, development ] + branches: [ main, development, rogue_one] env: CARGO_TERM_COLOR: always @@ -19,7 +19,7 @@ jobs: run: cargo build --release --verbose - name: Run unit tests run: cargo test --verbose - + shellcheck: name: Shellcheck runs-on: ubuntu-latest @@ -69,11 +69,11 @@ jobs: - name: Run integration tests using parse-tree command run: | cd aws-guard-rules-registry/rules - + FAILED_RULES=() SKIPPED_RULES=() rules=( $(find . -type f -name "*.guard") ) - + for rule in "${rules[@]}" do if [ $(sed -e '/^[ \s]*#.*$/d' $rule | sed -r '/^\s*$/d' | wc -l) -eq 0 ]; then @@ -84,7 +84,7 @@ jobs: FAILED_RULES+=("$rule") fi done - + SKIPPED_RULE_COUNT=${#SKIPPED_RULES[@]} if [ $SKIPPED_RULE_COUNT -gt 0 ]; then echo "The following $SKIPPED_RULE_COUNT rule(s) were skipped because they contained only comments:" @@ -93,9 +93,9 @@ jobs: echo "$skipped_rule" done fi - + FAILED_RULE_COUNT=${#FAILED_RULES[@]} - + if [ $FAILED_RULE_COUNT -gt 0 ]; then echo "The following $FAILED_RULE_COUNT rule(s) have failed the parse-tree integration tests with a non-zero error code:" for failed_rule in "${FAILED_RULES[@]}" @@ -106,5 +106,3 @@ jobs: else echo "All the rules have succeeded the parse-tree integration tests." fi - - diff --git a/Cargo.lock b/Cargo.lock index a22e91155..728ad25ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,7 +124,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfn-guard" -version = "2.1.3" +version = "3.0.0-alpha" dependencies = [ "Inflector", "clap", @@ -156,7 +156,7 @@ dependencies = [ [[package]] name = "cfn-guard-ffi" -version = "2.1.3" +version = "3.0.0-alpha" dependencies = [ "cfn-guard", "ffi-support", @@ -164,7 +164,7 @@ dependencies = [ [[package]] name = "cfn-guard-lambda" -version = "2.1.3" +version = "3.0.0-alpha" dependencies = [ "cfn-guard", "lambda_runtime", diff --git a/README.md b/README.md index 6f78e8934..dc36f210a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Validate Cloud Environments with Policy-as-Code** -AWS CloudFormation Guard is an open-source general-purpose policy-as-code evaluation tool. It provides developers with a simple-to-use, yet powerful and expressive domain-specific language (DSL) to define policies and enables developers to validate JSON- or YAML- formatted structured data with those policies. +AWS CloudFormation Guard is an open-source general-purpose policy-as-code evaluation tool. It provides developers with a simple-to-use, yet powerful and expressive domain-specific language (DSL) to define policies and enables developers to validate JSON- or YAML- formatted structured data with those policies. Guard 2.0 release is a complete re-write of the earlier 1.0 version to make the tool general-purpose. With Guard 2.0, developers can continue writing policies for CloudFormation Templates. In addition, developers can use Guard in the following business domains: @@ -10,10 +10,10 @@ Guard 2.0 release is a complete re-write of the earlier 1.0 version to make the 1. Terraform plan (in JSON format) for deployment safety assessment checks or Terraform state files to detect live state deviations. 2. Static assessment of IaC templates to determine network reachability like Amazon Redshift cluster deployed inside a VPC and prevent the provision of such stacks. 2. **Detective Governance and Compliance:** validate conformity of Configuration Management Database (CMDB) resources such as AWS Config-based configuration items (CIs). For example, developers can use Guard policies against AWS Config CIs to continuously monitor state of deployed AWS and non-AWS resources, detect violations from policies, and trigger remediation. -3. **Deployment Safety:** validate CloudFormation ChangeSets to ensure changes are safe before deployment. For example, renaming an Amazon DynamoDB Table will cause a replacement of the Table. With Guard 2.0, you can prevent such changes in your CI/CD pipelines. +3. **Deployment Safety:** validate CloudFormation ChangeSets to ensure changes are safe before deployment. For example, renaming an Amazon DynamoDB Table will cause a replacement of the Table. With Guard 2.0, you can prevent such changes in your CI/CD pipelines. > **NOTE**: If you are using Guard 1.0, we highly recommend adopting Guard 2.0 because Guard 2.0 is a major release that introduces multiple features to simplify your current policy-as-code experience. Guard 2.0 and higher versions are backward incompatible with your Guard 1.0 rules and can result in breaking changes. To migrate from Guard 1.0 to Guard 2.0, 1) use migrate command to transition your existing 1.0 rules to 2.0 rules and 2) read all new Guard 2.0 features. -> +> > You can find code related to Guard 2.0 on the main branch of the repo and code related to Guard 1.0 on [Guard1.0 branch](https://github.com/aws-cloudformation/cloudformation-guard/tree/Guard1.0) of the repo. **Guard In Action** @@ -46,7 +46,7 @@ Guard 2.0 release is a complete re-write of the earlier 1.0 version to make the > Clause is an assertion that evaluates to true or false. Clauses can either use binary operations to compare two values (e.g `==, >` and `in`), or unary operations that takes only one value (e.g. `exists, empty,` and `is_list`). Here is a sample clause that compares `Type` to be a `AWS::S3::Bucket` : ``` -Type == /AWS::S3::Bucket/ +Type == /AWS::S3::Bucket/ ``` **4) What are the supported** **types** **that can I use to define clauses?** @@ -56,12 +56,12 @@ Type == /AWS::S3::Bucket/ > *Unary Operators:* `exists, empty, is_string, is_list, is_struct, is_bool, is_int, is_float, not(!)` > *Binary Operators:* `==, !=, >, >=, <, <=, IN ` > -> Most operators are self-explanatory. A few important points: +> Most operators are self-explanatory. A few important points: > > 1. Refer [Guard: Clauses](docs/CLAUSES.md) to understand the usage of `exists` and `empty` operators > 2. Clause `ports >= [10, 20, 30]` implies that every element for `ports` is `>= 30`. If your intention is range, then express it as `r[10, 30]` . > 3. Clause `ports >= 100` can have ports resolve to an array `[121, 200, 443]`. This check ensures that every element returned was >= 100, and in the example shown this evaluates to `true.` -> 4. `IN` operator for collections (does not work for `string` type) to check if any value matches. For example: +> 4. `IN` operator for collections (does not work for `string` type) to check if any value matches. For example: ``` Properties.SslPolicy IN ["ELBSecurityPolicy-TLS-1-2-2017-01", "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"] @@ -78,13 +78,13 @@ rule s3_bucket_name_encryption_check when %s3_buckets !empty { %s3_buckets { Properties { # common prefix - BucketName == /^MyCompanyPrefix/ - + BucketName == /^MyCompanyPrefix/ + # encryption MUST BE on BucketEncryption.ServerSideEncryptionConfiguration[*] { - # only KMS - ServerSideEncryptionByDefault.SSEAlgorithm IN - ["aws:KMS"] + # only KMS + ServerSideEncryptionByDefault.SSEAlgorithm IN + ["aws:KMS"] } } } @@ -104,14 +104,14 @@ rule s3_bucket_name_encryption_check when %s3_buckets !empty { > Guard is a DSL and an accompanying CLI tool that allows easy-to-use definitions for declaring and enforcing policies. Today the tool supports local file-based execution of a category of policies. Guard doesn’t support the following things today, along with workarounds for some: > > 1. Sourcing of rules from external locations such as GitHub Release and S3 bucket. If you want this feature natively in Guard, please raise an issue or +1 an existing issue. -> 2. Ability to import Guard policy file by reference (local file or GitHub, S3, etc.). It currently only supports a directory on disk of policy files, that it would execute. +> 2. Ability to import Guard policy file by reference (local file or GitHub, S3, etc.). It currently only supports a directory on disk of policy files, that it would execute. > 3. Parameter/Vault resolution for IaC tools such as CloudFormation or Terraform. Before you ask, the answer is NO. We will not add native support in Guard as the engine is general-purpose. If you need CloudFormation resolution support, raise an issue and we might have a solution for you. We do not support HCL natively. We do, however, support Terraform Plan in JSON to run policies against for deployment safety. If you need HCL support, raise an issue as well. -> 4. Ability to reference variables like `%s3_buckets`, inside error messages. Both JSON/Console output for evaluation results contain some of this information for inference. We also do not support using variable references to create dynamic regex expressions. However, we support variable references inside queries for cross join support, like `Resources.%references.Properties.Tags`. +> 4. Ability to reference variables like `%s3_buckets`, inside error messages. Both JSON/Console output for evaluation results contain some of this information for inference. We also do not support using variable references to create dynamic regex expressions. However, we support variable references inside queries for cross join support, like `Resources.%references.Properties.Tags`. > 5. Support for specifying variable names when accessing map or list elements to cature these values. For example, consider this check `Resources[resource_name].Properties.Tags not empty`, here `resource_name` captures the key or index value. The information is tracked as a part of the evaluation context today and present in both console/JSON outputs. This support will be extended to regex expression variable captures as well. -> 6. There are [known issues](docs/KNOWN_ISSUES.md) with potential workarounds that we are tracking towards resolution +> 6. There are [known issues](docs/KNOWN_ISSUES.md) with potential workarounds that we are tracking towards resolution **11) What are we really thankful about?** -> Where do we start? Hmm.... we want to thank Rust [language’s forums](https://users.rust-lang.org/), [build management, and amazing ecosystem](https://crates.io/) without which none of this would have been possible. We are not the greatest Rust practitioners, so if we did something that is not idiomatic Rust, please raise a PR. +> Where do we start? Hmm.... we want to thank Rust [language’s forums](https://users.rust-lang.org/), [build management, and amazing ecosystem](https://crates.io/) without which none of this would have been possible. We are not the greatest Rust practitioners, so if we did something that is not idiomatic Rust, please raise a PR. > > We want to make a special mention to [nom](https://github.com/Geal/nom) combinator parser framework to write our language parser in. This was an excellent decision that improved readability, testability, and composition. We highly recommend it. There are some rough edges, but it’s just a wonderful, awesome library. Thank you. Apart from that, we are consumers of many crates including [hyper](https://crates.io/crates/hyper) for HTTP handling, [simple logger](https://crates.io/crates/simple_logger), and many more. We also want to thank the open-source community for sharing their feedback with us through GitHub issues/PRs. > @@ -119,13 +119,13 @@ rule s3_bucket_name_encryption_check when %s3_buckets !empty { ## Guard DSL -### Tenets +### Tenets **(Unless you know better ones)** These tenets help guide the development of the Guard DSL: -* **Simple**: The language must be simple for customers to author policy rules, simple to integrate with an integrated development environment (IDE), readable for human comprehension, and machine enforceable. +* **Simple**: The language must be simple for customers to author policy rules, simple to integrate with an integrated development environment (IDE), readable for human comprehension, and machine enforceable. * **Unambiguous**: The language must not allow for ambiguous interpretations that make it hard for customers to comprehend the policy evaluation. The tool is targeted for security and compliance related attestations that need the auditor to consistently and unambiguously understand rules and their evaluations. @@ -206,7 +206,7 @@ If building on `Ubuntu`, it is recommended to run `sudo apt-get update; sudo apt 10. Run it and accept the defaults. #### Cargo-based Installation -Now that you have [rust and cargo installed](https://doc.rust-lang.org/cargo/getting-started/installation.html), installation of cfn-guard is easy: +Now that you have [rust and cargo installed](https://doc.rust-lang.org/cargo/getting-started/installation.html), installation of cfn-guard is easy: ```bash $ cargo install cfn-guard @@ -216,9 +216,9 @@ Check `help` to see if it is working. ```bash $ cfn-guard help -cfn-guard 2.1.3 +cfn-guard 3.0.0-alpha - Guard is a general-purpose tool that provides a simple declarative syntax to define + Guard is a general-purpose tool that provides a simple declarative syntax to define policy-as-code as rules to validate against any structured hierarchical data (like JSON/YAML). Rules are composed of clauses expressed using Conjunctive Normal Form (fancy way of saying it is a logical AND of OR clauses). Guard has deep @@ -253,13 +253,13 @@ SUBCOMMANDS: ### How does Guard CLI work? -The two common Guard CLI commands are `validate` and `test`. +The two common Guard CLI commands are `validate` and `test`. #### Validate -Validate command is used when you need to assess the compliance or security posture as defined by a set of policy files against incoming JSON/YAML data. Common data payloads used are CloudFormation Templates, CloudFormation ChangeSets, Kubernetes Pod policies, Terraform Plan/Configuration in JSON format, and more. Here is an example run of the `validate` command for assessing Kubernetes Pod Container configurations +Validate command is used when you need to assess the compliance or security posture as defined by a set of policy files against incoming JSON/YAML data. Common data payloads used are CloudFormation Templates, CloudFormation ChangeSets, Kubernetes Pod policies, Terraform Plan/Configuration in JSON format, and more. Here is an example run of the `validate` command for assessing Kubernetes Pod Container configurations -1. Save the sample policy rules file below as `k8s-pod-containers-limits.guard`: +1. Save the sample policy rules file below as `k8s-pod-containers-limits.guard`: ``` # @@ -267,29 +267,29 @@ Validate command is used when you need to assess the compliance or security post # # -# These set of rules primarily apply to the version 1 of the API spec (including v1Beta) and +# These set of rules primarily apply to the version 1 of the API spec (including v1Beta) and # the kind of document is a 'Pod' # -rule version_and_kind_match +rule version_and_kind_match { apiVersion == /v1/ kind == 'Pod' } # -# For the 'Pod' document ensure that containers have resource limits set +# For the 'Pod' document ensure that containers have resource limits set # for memory # -rule ensure_container_has_memory_limits when version_and_kind_match +rule ensure_container_has_memory_limits when version_and_kind_match { - spec.containers[*] + spec.containers[*] { - resources.limits + resources.limits { # # Ensure that memory attribute is set # - memory exists + memory exists << Id: K8S_REC_22 Description: Memory limit must be set for the container @@ -300,19 +300,19 @@ rule ensure_container_has_memory_limits when version_and_kind_match } # -# For the 'Pod' document ensure that containers have resource limits set +# For the 'Pod' document ensure that containers have resource limits set # for cpu # -rule ensure_container_has_cpu_limits when version_and_kind_match +rule ensure_container_has_cpu_limits when version_and_kind_match { - spec.containers[*] + spec.containers[*] { - resources.limits + resources.limits { # # Ensure that cpu attribute is set # - cpu exists + cpu exists << Id: K8S_REC_24 Description: Cpu limit must be set for the container @@ -320,8 +320,8 @@ rule ensure_container_has_cpu_limits when version_and_kind_match } } } -``` - +``` + 2. Paste the command below and hit `enter` ```bash @@ -329,8 +329,8 @@ cfn-guard validate -r k8s-pod-containers-limits.guard ``` 3. Cut-n-paste the sample configuration below for k8s pods on STDIN and then hit `CTRL+D`: - -```yaml + +```yaml apiVersion: v1 kind: Pod metadata: @@ -358,7 +358,7 @@ spec: ![Execution of validate](images/guard-validate.png) -The container `app` does not contain CPU limits specified, which fails the overall evaluation as shown in the screenshot. +The container `app` does not contain CPU limits specified, which fails the overall evaluation as shown in the screenshot. #### Test @@ -368,19 +368,19 @@ Test command is used during the development of guard policy rules files. Test pr ``` # -# Select from Resources section of the template all ApiGateway resources -# present in the template. +# Select from Resources section of the template all ApiGateway resources +# present in the template. # let api_gws = Resources.*[ Type == 'AWS::ApiGateway::RestApi' ] # -# Rule intent -# a) All ApiGateway instances deployed must be private +# Rule intent +# a) All ApiGateway instances deployed must be private # b) All ApiGateway instances must have atleast one IAM policy condition key to allow access from a VPC # # Expectations: # 1) SKIP when there are not API Gateway instances in the template -# 2) PASS when ALL ApiGateway instances MUST be "PRIVATE" and +# 2) PASS when ALL ApiGateway instances MUST be "PRIVATE" and # ALL ApiGateway instances MUST have one IAM Condition key with aws:sourceVpc or aws:SourceVpc # 3) FAIL otherwise # @@ -396,9 +396,9 @@ rule check_rest_api_has_vpc_access when check_rest_api_is_private { %api_gws { Properties { # - # ALL ApiGateways must have atleast one IAM statement that has Condition keys with + # ALL ApiGateways must have atleast one IAM statement that has Condition keys with # aws:sourceVpc - # + # some Policy.Statement[*] { Condition.*[ keys == /aws:[sS]ource(Vpc|VPC|Vpce|VPCE)/ ] !empty } @@ -423,7 +423,7 @@ rule check_rest_api_has_vpc_access when check_rest_api_is_private { check_rest_api_is_private: SKIP check_rest_api_has_vpc_access: SKIP - input: - Resources: + Resources: apiGw: Type: AWS::ApiGateway::RestApi expectations: @@ -431,7 +431,7 @@ rule check_rest_api_has_vpc_access when check_rest_api_is_private { check_rest_api_is_private: FAIL check_rest_api_has_vpc_access: SKIP - input: - Resources: + Resources: apiGw: Type: AWS::ApiGateway::RestApi Properties: @@ -442,7 +442,7 @@ rule check_rest_api_has_vpc_access when check_rest_api_is_private { check_rest_api_is_private: PASS check_rest_api_has_vpc_access: FAIL - input: - Resources: + Resources: apiGw: Type: AWS::ApiGateway::RestApi Properties: @@ -453,7 +453,7 @@ rule check_rest_api_has_vpc_access when check_rest_api_is_private { check_rest_api_is_private: FAIL check_rest_api_has_vpc_access: SKIP - input: - Resources: + Resources: apiGw: Type: AWS::ApiGateway::RestApi Properties: @@ -472,7 +472,7 @@ rule check_rest_api_has_vpc_access when check_rest_api_is_private { check_rest_api_has_vpc_access: PASS ``` -3. Run the test command +3. Run the test command ```bash cfn-guard test -r api_gateway_private_access.guard -t api_gateway_private_access_tests.yaml @@ -503,8 +503,8 @@ As a starting point for writing Guard rules for yourself or your organisation we ## AWS Rule Registry -As a reference for Guard rules and rule-sets that contain (on a best-effort basis) the compliance policies that adhere -to the industry best practices around usages across AWS resources, we have recently launched +As a reference for Guard rules and rule-sets that contain (on a best-effort basis) the compliance policies that adhere +to the industry best practices around usages across AWS resources, we have recently launched [AWS Guard Rules Registry](https://github.com/aws-cloudformation/aws-guard-rules-registry). diff --git a/guard-ffi/Cargo.toml b/guard-ffi/Cargo.toml index 9d58ea765..f3b6e0f07 100644 --- a/guard-ffi/Cargo.toml +++ b/guard-ffi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cfn-guard-ffi" -version = "2.1.3" +version = "3.0.0-alpha" edition = "2018" authors = ["Diwakar Chakravarthy", "John Tompkins", "Omkar Hegde", "Priya Padmanaban", "aws-cloudformation-developers ", "Tyler Southwick"] description = "AWS CloudFormation Guard is an open-source general-purpose policy-as-code evaluation tool. It provides developers with a simple-to-use, yet powerful and expressive domain-specific language (DSL) to define policies and enables developers to validate JSON- or YAML- formatted structured data with those policies." @@ -14,6 +14,5 @@ keywords = ["policy-as-code", "guard", "cfn-guard", "security", "compliance"] crate-type = ["rlib", "dylib"] [dependencies] -cfn-guard = { version = "2.1.3", path = "../guard" } +cfn-guard = { version = "3.0.0-alpha", path = "../guard" } ffi-support = "0.4.4" - diff --git a/guard-lambda/Cargo.toml b/guard-lambda/Cargo.toml index e97247312..659673dd1 100644 --- a/guard-lambda/Cargo.toml +++ b/guard-lambda/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cfn-guard-lambda" -version = "2.1.3" +version = "3.0.0-alpha" authors = ["Diwakar Chakravarthy", "John Tompkins", "Omkar Hegde", "Priya Padmanaban", "Bryan Ayala", "Kexiang Wang", "Akshay Rane", "Josh Fried", "aws-cloudformation-developers "] description = "Lambda version of cfn-guard. Checks JSON- or YAML- formatted structured data for policy compliance using a simple, policy-as-code, declarative syntax" @@ -17,4 +17,4 @@ serde_derive = "1.0.92" simple_logger = "4.0.0" log = "0.4.6" tokio = "1.24.2" -cfn-guard = { version = "2.1.3", path = "../guard" } \ No newline at end of file +cfn-guard = { version = "3.0.0-alpha", path = "../guard" } diff --git a/guard/Cargo.toml b/guard/Cargo.toml index a3e18dade..212d6904d 100644 --- a/guard/Cargo.toml +++ b/guard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cfn-guard" -version = "2.1.3" +version = "3.0.0-alpha" edition = "2018" authors = ["Diwakar Chakravarthy", "John Tompkins", "Omkar Hegde", "Priya Padmanaban", "Bryan Ayala", "Kexiang Wang", "Akshay Rane", "Tyler Southwick", "Josh Fried", "aws-cloudformation-developers "] diff --git a/guard/README.md b/guard/README.md index e0254b850..01ebf4cde 100644 --- a/guard/README.md +++ b/guard/README.md @@ -1,6 +1,6 @@ # AWS CloudFormation Guard 2.0's Modes of Operation -AWS CloudFormation Guard is an open-source general-purpose policy-as-code evaluation tool. It provides developers with a simple-to-use, yet powerful and expressive domain-specific language (DSL) to define policies and enables developers to validate JSON- or YAML- formatted structured data with those policies. +AWS CloudFormation Guard is an open-source general-purpose policy-as-code evaluation tool. It provides developers with a simple-to-use, yet powerful and expressive domain-specific language (DSL) to define policies and enables developers to validate JSON- or YAML- formatted structured data with those policies. As an example of how to use AWS CloudFormation Guard (cfn-guard), given a CloudFormation template (template.json): @@ -34,7 +34,7 @@ And a rules file (rules.guard): ``` # Create a variable named 'aws_ec2_volume_resources' that selects all resources of type "AWS::EC2::Volume" -# in the input resource template +# in the input resource template let aws_ec2_volume_resources = Resources.*[ Type == 'AWS::EC2::Volume' ] # Create a rule named aws_template_parameters for validation in the "Parameters" section of the template @@ -42,7 +42,7 @@ rule aws_template_parameters { Parameters.InstanceName == "TestInstance" } -# Create a rule named aws_ec2_volume that filters on "AWS::EC2::Volume" type being present in the template +# Create a rule named aws_ec2_volume that filters on "AWS::EC2::Volume" type being present in the template rule aws_ec2_volume when %aws_ec2_volume_resources !empty { %aws_ec2_volume_resources.Properties.Encrypted == true %aws_ec2_volume_resources.Properties.Size IN [50, 500] @@ -61,7 +61,7 @@ aws_template_parameters FAIL aws_ec2_volume FAIL ``` -We designed `cfn-guard` to be plugged into your build processes. +We designed `cfn-guard` to be plugged into your build processes. If CloudFormation Guard validates the templates successfully, it gives you an exit status (`$?` in bash) of `0`. If CloudFormation Guard identifies a rule violation, it gives you a status report of the rules that failed. Use the verbose flag `-v` to see the detailed evaluation tree that shows how CloudFormation Guard evaluated each rule. @@ -76,33 +76,57 @@ Use the verbose flag `-v` to see the detailed evaluation tree that shows how Clo `validate` (like the example above) validates data against rules. ```bash -cfn-guard-validate -Evaluates rules against the data files to determine success or failure. -You can point rules flag to a rules directory and point data flag to a data directory. -When pointed to a directory it will read all rules in the directory file and evaluate -them against the data files found in the directory. The command can also point to a -single file and it would work as well. -Note - When pointing the command to a directory, the directory may not contain a mix of -rules and data files. The directory being pointed to must contain only data files, -or rules files. - -USAGE: - cfn-guard validate [FLAGS] [OPTIONS] --rules - -FLAGS: - -a, --alphabetical Validate files in a directory ordered alphabetically - -h, --help Prints help information - -m, --last-modified Validate files in a directory ordered by last modified times - -p, --print-json Print output in json format - -s, --show-clause-failures Show clause failure along with summary - -V, --version Prints version information - -v, --verbose Verbose logging - -OPTIONS: - -d, --data Provide a file or dir for data files in JSON or YAML - -r, --rules Provide a rules file or a directory of rules files - -``` +Usage: cfn-guard validate [OPTIONS] <--rules [...]|--payload> + +Options: + -r, --rules [...] + Provide a rules file or a directory of rules files. Supports passing multiple values by using this option repeatedly. + Example: + --rules rule1.guard --rules ./rules-dir1 --rules rule2.guard + For directory arguments such as `rules-dir1` above, scanning is only supported for files with following extensions: .guard, .ruleset + -d, --data [...] + Provide a data file or directory of data files in JSON or YAML. Supports passing multiple values by using this option repeatedly. + Example: + --data template1.yaml --data ./data-dir1 --data template2.yaml + For directory arguments such as `data-dir1` above, scanning is only supported for files with following extensions: .yaml, .yml, .json, .jsn, .template + -i, --input-parameters [...] + Provide a data file or directory of data files in JSON or YAML that specifies any additional parameters to use along with data files to be used as a combined context. All the parameter files passed as input get merged and this combined context is again merged with each file passed as an argument for `data`. Due to this, every file is expected to contain mutually exclusive properties, without any overlap. Supports passing multiple values by using this option repeatedly. + Example: + --input-parameters param1.yaml --input-parameters ./param-dir1 --input-parameters param2.yaml + For directory arguments such as `param-dir1` above, scanning is only supported for files with following extensions: .yaml, .yml, .json, .jsn, .template + -t, --type + Specify the type of data file used for improved messaging - ex: CFNTemplate [possible values: CFNTemplate] + -o, --output-format + Specify the format in which the output should be displayed [default: single-line-summary] [possible values: json, yaml, single-line-summary] + -E, --previous-engine + Uses the old engine for evaluation. This parameter will allow customers to evaluate old changes before migrating + -S, --show-summary + Controls if the summary table needs to be displayed. --show-summary fail (default) or --show-summary pass,fail (only show rules that did pass/fail) or --show-summary none (to turn it off) or --show-summary all (to show all the rules that pass, fail or skip) [default: fail] [possible values: none, all, pass, fail, skip] + -s, --show-clause-failures + Show clause failure along with summary + -a, --alphabetical + Validate files in a directory ordered alphabetically + -m, --last-modified + Validate files in a directory ordered by last modified times + -v, --verbose + Verbose logging + -p, --print-json + Print output in json format + -P, --payload + Provide rules and data in the following JSON format via STDIN, + {"rules":["", "", ...], "data":["", "", ...]}, where, + - "rules" takes a list of string version of rules files as its value and + - "data" takes a list of string version of data files as it value. + When --payload is specified --rules and --data cannot be specified. + -z, --structured + Print out a list of structured and valid JSON/YAML. This argument conflicts with the following arguments: + verbose + print-json + previous-engine + show-summary: all/fail/pass/skip + output-format: single-line-summary + -h, --help + Print help``` ### Rulegen @@ -126,7 +150,7 @@ OPTIONS: For example, using the same template (template.json) from the above example: ```bash -$ cfn-guard rulegen --data template.json +$ cfn-guard rulegen --data template.json let aws_ec2_volume_resources = Resources.*[ Type == 'AWS::EC2::Volume' ] rule aws_ec2_volume when %aws_ec2_volume_resources !empty { %aws_ec2_volume_resources.Properties.Size IN [500, 100] @@ -146,7 +170,7 @@ cfn-guard rulegen --data template.json --output rules.guard `migrate` command generates rules in the new AWS Cloudformation Guard 2.0 syntax from rules written using 1.0 language. ```bash -cfn-guard-migrate +cfn-guard-migrate Migrates 1.0 rules to 2.0 compatible rules. USAGE: @@ -176,9 +200,9 @@ The equivalent rules in the 2.0 language can be generated using the migrate comm $ cfn-guard migrate --rules example.ruleset rule migrated_rules { let aws_ec2_volume = Resources.*[ Type == "AWS::EC2::Volume" ] - + let encryption_flag = true - + %aws_ec2_volume.Properties.Encrypted == %encryption_flag %aws_ec2_volume.Properties.Size <= 100 } @@ -189,21 +213,17 @@ rule migrated_rules { `parse-tree` command generates a parse tree for the rules defined in a rules file. Use the `--output` flag to write the generated tree to a file. ```bash -cfn-guard-parse-tree +cfn-guard-parse-tree Prints out the parse tree for the rules defined in the file. -USAGE: - cfn-guard parse-tree [FLAGS] [OPTIONS] +Usage: cfn-guard parse-tree [OPTIONS] -FLAGS: - -h, --help Prints help information - -j, --print-json Print output in json format - -y, --print-yaml Print output in json format - -V, --version Prints version information - -OPTIONS: - -o, --output Write to output file - -r, --rules Provide a rules file +Options: + -r, --rules Provide a rules file + -o, --output Write to output file + -p, --print-json Print output in JSON format. Use -p going forward, as the short flag -j is on deprecation path. + -y, --print-yaml Print output in YAML format + -h, --help Print help ``` ### Test @@ -216,28 +236,24 @@ Built in unit testing capability to validate a Guard rules file against unit tests specified in YAML format to determine each individual rule's success or failure testing. -USAGE: - cfn-guard test [FLAGS] --rules-file --test-data [alphabetical] - -FLAGS: - -h, --help Prints help information - -m, --last-modified Sort by last modified times within a directory - -V, --version Prints version information - -v, --verbose Verbose logging - -OPTIONS: - -r, --rules-file Provide a rules file - -t, --test-data Provide a file or dir for data files in JSON or YAML - -ARGS: - Sort alphabetically inside a directory +Usage: cfn-guard test [OPTIONS] + +Options: + -r, --rules-file Provide a rules file + -t, --test-data Provide a file or dir for data files in JSON or YAML + -d, --dir Provide the root directory for rules + -E, --previous-engine Uses the old engine for evaluation. This parameter will allow customers to evaluate old changes before migrating + -a, --alphabetical Sort alphabetically inside a directory + -m, --last-modified Sort by last modified times within a directory + -v, --verbose Verbose logging + -h, --help Print help ``` For example, given a rules file (rules.guard) as: ```bash rule assert_all_resources_have_non_empty_tags { - when Resources.* !empty { + when Resources.* !empty { Resources.*.Properties.Tags !empty } } @@ -251,10 +267,10 @@ You can write a YAML-formatted unit test file (test.yml) as: Resources: {} expectations: rules: - assert_all_resources_have_non_empty_tags: SKIP + assert_all_resources_have_non_empty_tags: SKIP - input: Resources: - nonCompliant: + nonCompliant: Type: Consoto::Network::VPC Properties: {} expectations: @@ -265,6 +281,6 @@ You can write a YAML-formatted unit test file (test.yml) as: You can then test your rules file using the `test` command as: ```bash -$ cfn-guard test -r rules.guard -t test.yml +$ cfn-guard test -r rules.guard -t test.yml PASS Expected Rule = assert_all_resources_have_non_empty_tags, Status = SKIP, Got Status = SKIP PASS Expected Rule = assert_all_resources_have_non_empty_tags, Status = FAIL, Got Status = FAIL