Releases: aws-cloudformation/cloudformation-guard
v3.1.1
What's Changed
- [BugFix]: fix for regression regarding delimiters for show summary by @joshfried-aws in #494
Full Changelog: 3.1.0...3.1.1
v3.1.0
What's Changed
- [Code Quality]: removing unecessary result return types by @joshfried-aws in #445
- [Enhancement]: JUnit reporter for validate command by @joshfried-aws in #446
- [Enhancement] Test Command enhanced reporters (JSON/YAML) by @joshfried-aws in #447
- [Misc]: changing all walkdirs to use the same cmp operator by @joshfried-aws in #450
- [Enhancement] Only show errors/failures in output by @dannyvassallo in #448
- [Enhancement]: JUnit reporters for test command by @joshfried-aws in #451
- "[Misc]: updating readme to reflect new reporters for test and validate" by @joshfried-aws in #452
- [Misc]: updating build and unit tests to include a windows job by @joshfried-aws in #449
- [Misc]: addressing new clippy lints in rust 1.76 by @joshfried-aws in #454
- fix rulegen invalid parameter by @sejimhp in #453
- [Enhancement] Use pretty_assertions by @dannyvassallo in #456
- [Enhancement] Show full path to file #410 by @dannyvassallo in #457
- [Enhancement]: cfn-guard as a library by @joshfried-aws in #458
- [Enhancement] Add support for windows by @dannyvassallo in #460
- [Enhancement] Vscode workspace settings by @dannyvassallo in #462
- [Enhancement] Windows support - Powershell check gh action by @dannyvassallo in #463
- [Code Quality]: default implementation for reader and writer by @joshfried-aws in #461
- adding rustdocs for validate, and it's builder by @joshfried-aws in #465
- [Enhancement] Add typo checker and correct errors by @dannyvassallo in #464
- [Misc]: doc updates for test command by @joshfried-aws in #467
- [MISC] docs update for parse-tree command by @joshfried-aws in #468
- [Misc]: rulegen docs by @joshfried-aws in #469
- [Misc] Removing unnecessary public modifiers by @joshfried-aws in #470
- [Enhancement] Add support for SARIF by @dannyvassallo in #473
- [MISC]: bumping up versions for all packages to 3.1.0-beta by @joshfried-aws in #474
- Bump mio from 0.8.5 to 0.8.11 by @dependabot in #477
- [Documentation] Add ci examples by @dannyvassallo in #481
- [BugFix]: Addressing issues with parsing newline characters on windows for conjunctions by @joshfried-aws in #482
- [Documentation] SARIF Example by @dannyvassallo in #483
- [Documentation] Use Docker for JUNIT examples by @dannyvassallo in #484
- [Docs] Adding documentation for all converter functions by @joshfried-aws in #486
- [Docs] Providing an example for the validate command by @joshfried-aws in #487
- [Misc]: updating all references of 3.1.0-beta to 3.1.0 by @joshfried-aws in #488
New Contributors
- @dannyvassallo made their first contribution in #448
- @sejimhp made their first contribution in #453
Full Changelog: 3.0.3...3.1.0
Table of Contents
- New Validate reporters
- New Test Flag to Specify an Output
- Cfn-Guard as a Library
- Stabilized Converter Functions
New Validate Reporters
- JUnit - users can now use the
-o
or--output-format
flag to request a JUnit report-o junit
- Sarif - users can now use the
-o
or--output-format
flag to request a Sarif report-o sarif
NOTE: If either junit, or sarif output-format is set, this requires the user to also pass --structured
, and -S none
otherwise cfn-guard will return an error
New Test Flag to Specify an Output
- The output format flag has been added to the test command. This means users can now take advantage of 4 different reporting mechanisms; single-line-summary, json, yaml, or junit
Cfn-Guard as a Library
- Users can now leverage cfn-guard as a library. We now have added builders for users to construct commands, and call them as needed. This will allow users to more easily build solutions with cfn-guard for specific needs
Stabilized Converter Functions
NOTE: This feature was previously introduced in version 3.0.1, it is now stabilized as of version 3.1.0
To improve the user experience for validating templates when schemas use types that might be easier evaluated as a different type (i.e. a string thats actually a number) the 3.0.1 release adds support to convert between specific types.
The conversions allowed are the following
strings/floats-> ints
strings/ints -> floats
strings -> bools
bools/floats/ints -> strings
The following is an example of parsing a string into an int.
Given the following template:
Resources:
asg:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: "1"
We can write the following rule
let asg = Resources.*[ Type == 'AWS::AutoScaling::AutoScalingGroup' ]
rule test_parse_int when %asg !empty {
let min = parse_int(%asg.Properties.MinSize)
%min == 1
}
3.1.0-beta
What's Changed
- [Code Quality]: removing unnecessary result return types by @joshfried-aws in #445
- [Enhancement]: JUnit reporter for validate command by @joshfried-aws in #446
- [Enhancement] Test Command enhanced reporters (JSON/YAML) by @joshfried-aws in #447
- [Misc]: changing all walkdirs to use the same cmp operator by @joshfried-aws in #450
- [Enhancement] Only show errors/failures in output by @dannyvassallo in #448
- [Enhancement]: JUnit reporters for test command by @joshfried-aws in #451
- "[Misc]: updating readme to reflect new reporters for test and validate" by @joshfried-aws in #452
- [Misc]: updating build and unit tests to include a windows job by @joshfried-aws in #449
- [Misc]: addressing new clippy lints in rust 1.76 by @joshfried-aws in #454
- fix rulegen invalid parameter by @sejimhp in #453
- [Enhancement] Use pretty_assertions by @dannyvassallo in #456
- [Enhancement] Show full path to file #410 by @dannyvassallo in #457
- [Enhancement]: cfn-guard as a library by @joshfried-aws in #458
- [Enhancement] Add support for windows by @dannyvassallo in #460
- [Enhancement] Vscode workspace settings by @dannyvassallo in #462
- [Enhancement] Windows support - Powershell check gh action by @dannyvassallo in #463
- [Code Quality]: default implementation for reader and writer by @joshfried-aws in #461
- adding rustdocs for validate, and it's builder by @joshfried-aws in #465
- [Enhancement] Add typo checker and correct errors by @dannyvassallo in #464
- [Misc]: doc updates for test command by @joshfried-aws in #467
- [MISC] docs update for parse-tree command by @joshfried-aws in #468
- [Misc]: rulegen docs by @joshfried-aws in #469
- [Misc] Removing unnecessary public modifiers by @joshfried-aws in #470
- [Enhancement] Add support for SARIF by @dannyvassallo in #473
- [MISC]: bumping up versions for all packages to 3.1.0-beta by @joshfried-aws in #474
New Contributors
- @dannyvassallo made their first contribution in #448
- @sejimhp made their first contribution in #453
Full Changelog: 3.0.3...3.1.0-beta
Table of Contents
New Validate Reporters
- JUnit - users can now use the
-o
or--output-format
flag to request a JUnit report-o junit
- Sarif - users can now use the
-o
or--output-format
flag to request a Sarif report-o sarif
NOTE: If either junit, or sarif output-format is set, this requires the user to also pass --structured
, and -S none
otherwise cfn-guard will return an error
New Test Flag to Specify an Output
- The output format flag has been added to the test command. This means users can now take advantage of 4 different reporting mechanisms; single-line-summary, json, yaml, or junit
Cfn-Guard as a Library
- Users can now leverage cfn-guard as a library. We now have added builders for users to construct commands, and call them as needed. This will allow users to more easily build solutions with cfn-guard for specific needs
v3.0.3
What's Changed
- [BugFix]: Gracefully handle keys for maps that are not of type string by @joshfried-aws in #418
- [BugFix]: discovered bug in loader when handling type casted nulls by @joshfried-aws in #420
- [Misc]: Removing unnecessary clones by @joshfried-aws in #421
- guard: add fuzz target. by @sepehrdaddev in #419
- [BugFix]: fix for converting serde_yaml::Value into internal Value type by @joshfried-aws in #422
- [Docs]: fixing list for cfn-guard-fuzz README.md by @joshfried-aws in #423
- [Misc]: bumping up nom to version 5.1.3 by @joshfried-aws in #424
- [BugFix]: fix to catch panic when parsing inner portion of a string by @joshfried-aws in #426
- [Misc]: bumping up fancy-regex to 0.12.0 by @joshfried-aws in #427
- [BugFix]: Add check for control characters in regex by @joshfried-aws in #428
- [BugFix]: Fix panic occurring for regex with incomplete groupings by @joshfried-aws in #429
- [Misc]: split fuzz targets into 2 by @joshfried-aws in #430
- [BugFix]: fixing panic in evaluator when query from typeblock is unresolved by @joshfried-aws in #432
- [Misc]: adding fuzzer to ci by @joshfried-aws in #433
- [Misc]: changing build and test ci job run on both macos and ubuntu by @joshfried-aws in #434
- [Misc]: adding multiple targets for install script job by @joshfried-aws in #435
- [Misc]: adding apple silicon runner to os targets for registry job by @joshfried-aws in #436
- [Misc]: adding apple silicon runner to os targets for cargo build/test by @joshfried-aws in #437
- Bump unsafe-libyaml from 0.2.9 to 0.2.10 in /guard/fuzz by @dependabot in #439
- Bump unsafe-libyaml from 0.2.5 to 0.2.10 by @dependabot in #438
- [Misc]: clippy lints by @joshfried-aws in #440
- Bump rustix from 0.36.8 to 0.36.17 by @dependabot in #441
- [Misc]: Reverting previous changes + bumping up fancy-regex version by @joshfried-aws in #442
New Contributors
- @sepehrdaddev made their first contribution in #419
Full Changelog: 3.0.2...3.0.3
v3.0.2
What's Changed
- fix workflow for publishing to ecr by @joshfried-aws in #408
- [MISC]: updating install script by @joshfried-aws in #409
- [Bugfix]: Loader can panic when handling nested maps by @joshfried-aws in #415
- [Misc]: bumping up all 3.0.1 references to reference 3.0.2 by @joshfried-aws in #416
Full Changelog: 3.0.1...3.0.2
v3.0.1
What's Changed
- [Misc]: Minor fixes to documentation, and help for command options by @joshfried-aws in #384
- [Enhancement]: Conversion functions by @joshfried-aws in #388
- [BugFix]: Custom Message is now JSON/YAML parseable by @joshfried-aws in #396
- [BugFix]: updating docs, adding is_null and is_float operators by @joshfried-aws in #398
- updating known issues by @joshfried-aws in #397
- [BugFix]: small change for single-line-summary error messages by @joshfried-aws in #399
- [Enhancement]: Adding support for calling functions inline by @joshfried-aws in #400
- [Code Quality]: Addressing new clippy lints (warns) by @joshfried-aws in #401
- [BugFix]: cfn-guard no longer errors out when rule files are empty, or contain only comments by @joshfried-aws in #402
Details
Added support for conversion functions
To improve the user experience for validating templates when schemas use types that might be easier evaluated as a different type (i.e. a string thats actually a number) the 3.0.1 release adds support to convert between specific types.
The conversions allowed are the following
strings/floats-> ints
strings/ints -> floats
strings -> bools
bools/floats/ints -> strings
The following is an example of parsing a string into an int.
Given the following template:
Resources:
asg:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: "1"
We can write the following rule
let asg = Resources.*[ Type == 'AWS::AutoScaling::AutoScalingGroup' ]
rule test_parse_int when %asg !empty {
let min = parse_int(%asg.Properties.MinSize)
%min == 1
}
Full Changelog: 3.0.0...3.0.1
v3.0.0
What's Changed
- Populated filename in the output by @akshayrane in #358
- Support for some function expressions / stateful rules by @joshfried-aws in #361
- Combined structured output and updated default rule clause name to include file name by @akshayrane in #360
- Clap Autocompletions by @joshfried-aws in #340
- Adding documentation for functions by @joshfried-aws in #362
- Deprecated migrate and previous engine by @akshayrane in #364
- Removing unnecessary print statement for failure in parse-tree command by @joshfried-aws in #368
- Improve error message for templates that cause an error by @joshfried-aws in #370
- Clippy lints + ci by @joshfried-aws in #371
- [Bugfix]: Fixed bug where cfn template fails validate rule check and when failing node isnt a child of resources by @joshfried-aws in #372
- Updating reporters to all use serde for both json and yaml + misc improvements by @joshfried-aws in #373
- [Bugfix] Fixing improper console output when using single line summary by @joshfried-aws in #378
- [Enhancement] Creating a new error code for rule failures by @joshfried-aws in #379
- Refined documentation for functions, join path bugfix & version bump by @akshayrane in #381
- Changes to CI actions by @akshayrane & @joshfried-aws in #366 & #383
- Updates to
README.md
for3.0.0
- Added latest configuration for aws-guard-rules-registry integration tests
- Added new deployment method for
cfn-guard-lambda
through AWS SAM-CLI - Deprecated
-j
as short flag forprint-json
- Updated names for artifacts to have
v3
in them - Added
rogue_one
branch to docker workflow, this will publish an ECR image for all updates to this remote branch as well
- Updates to
- Added OS-specific cargo targets to release workflow by @akshayrane in #310
- [Code Quality]: Rust-fmt action + formatting project by @joshfried-aws in #315
- [Code Quality]: Implementing custom writer, bug fixes, new integration test framework, and adding initial tests for all commands by @joshfried-aws in #325
- Bump tokio from 1.21.2 to 1.24.2 by @dependabot in #327
- Improved documentation for new Guard version and keeping version up to date for GitHub runner OS by @razcloud in #365
- +[fancy-regex] Added support for advanced regular expressions by @akshayrane in #326
- improved safety of serde_yaml::Value -> value conversion by @joshfried-aws in #328
- Improve handling of function references for test command by @joshfried-aws in #331
- PR to add Thiserror to cfn-guard by @joshfried-aws in #329
- Redirected verbose output from stdout to custom writer and added unit… by @akshayrane in #332
- Addit cargo-audit to CI + bump up clap to 3.0 by @joshfried-aws in #330
- Implemented custom reader, increasing test coverage for validate command. by @joshfried-aws in #334
- Update CONTRIBUTING.md by @swiercek in #335
- Clap4 by @joshfried-aws in #336
- Added integration tests against aws-guard-rules-registry on Ubuntu by @akshayrane in #337
- Update check-tags-present.guard by @Aishwarya4400 in #313
- Adding structured evaluator by @joshfried-aws in #339
Breaking changes in 3.0.0
- Error codes - We emit a different exit code (19) now for validation failure if the data template(s) passed are non-compliant against the rules. This will make it easy to distinguish between the two. Previously, we emitted the same code as for parse errors (5). (PR #379)
- Intrinsic function resolution with test command. We now handle the intrinsic functions like
Fn::ImportValue
,Fn::Sub
, etc in unit tests in an improved way. Read more about this change here. - Standardized the output format for generic JSON/YAML templates to be inline with CFN-specific one. (PR #373)
Table of Contents
- Built-in Functions and Stateful Rules
- Added alternative deployment method using SAM-CLI for
cfn-guard-lambda
- Updated the output to contain filename
- Updated combined structured output & default anonymous rule name
- Command auto-completions
- Added support for advanced regular expressions
- Improved handling for intrinsic functions in test command
- Added
--structured
flag to validate command to emit JSON/YAML parseable output
Details
1. Built-in Functions and Stateful Rules
As of version 3.0.0 guard now supplies some builtin functions, allowing for stateful rules.
Built-in functions are supported only through assignment to a variable at the moment, and not inline.
NOTE: all examples are operating off the following YAML template
Data
(click to expand)
Resources:
newServer:
Type: AWS::New::Service
Properties:
Policy: |
{
"Principal": "*",
"Actions": ["s3*", "ec2*"]
}
Arn: arn:aws:newservice:us-west-2:123456789012:Table/extracted
Encoded: This%20string%20will%20be%20URL%20encoded
Collection:
- a
- b
- c
BucketPolicy:
PolicyText: '{"Version":"2012-10-17","Statement":[{"Sid":"DenyReducedReliabilityStorage","Effect":"Deny","Principal":"*","Action":"s3:*","Resource":"arn:aws:s3:::s3-test-123/*","Condition":{"StringEquals":{"s3:x-amz-storage-class-123":["ONEZONE_IA","REDUCED_REDUNDANCY"]}}}]}'
s3:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
bucket:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
String Manipulation Functions
The following functions all operate on queries that resolve to string values
1. json_parse()
The json_parse
function adds support for parsing inline JSON strings from a given template. After parsing the string into an object,
you can now evaluate certain properties of this struct just like with a normal JSON/YAML object
Rule
(click to expand)
let template = Resources.*[ Type == 'AWS::New::Service']
let expected = {
"Principal": "*",
"Actions": ["s3*", "ec2*"]
}
rule TEST_JSON_PARSE when %template !empty {
let policy = %template.Properties.Policy
let res = json_parse(%policy)
%res !empty
%res == %expected
<<
Violation: the IAM policy does not match with the recommended policy
>>
}
2. regex_replace()
The regex_replace
function adds support for replacing one regular expression with another
In this simple example, we will re-format an ARN by moving around some sections in it.
We will start with a normal ARN that has the following pattern: arn:<Partition>:<Service>:<Region>:<AccountID>:<ResourceType>/<ResourceID>
and we will try to convert it to: <Partition>/<AccountID>/<Region>/<Service>-<ResourceType>/<ResourceID>
Rule
(click to expand)
let template = Resources.*[ Type == 'AWS::New::Service']
rule TEST_REGEX_REPLACE when %template !empty {
%template.Properties.Arn exists
let arn = %template.Properties.Arn
let arn_partition_regex = "^arn:(\w+):(\w+):([\w0-9-]+):(\d+):(.+)$"
let capture_group_reordering = "${1}/${4}/${3}/${2}-${5}"
let res = regex_replace(%arn, %arn_partition_regex, %capture_group_reordering)
%res == "aws/123456789012/us-west-2/newservice-Table/extracted"
<< Violation: Resulting reformatted ARN does not match the expected format >>
}
3. join()
The join
function adds support to collect a query, and the...
v3.0.0-beta
What's Changed
- Populated filename in the output by @akshayrane in #358
- Support for some function expressions / stateful rules by @joshfried-aws in #361
- Combined structured output and updated default rule clause name to include file name by @akshayrane in #360
- Clap auto-completions by @joshfried-aws in #340
- Added documentation for functions by @joshfried-aws in #362
- Deprecated migrate and previous engine by @akshayrane in #364
3.0.0-beta
release changes by @akshayrane in #366- Bumped up version to
3.0.0-beta
- Updates to
README.md
for3.0.0
- Added latest configuration for aws-guard-rules-registry integration tests
- Added new deployment method for
cfn-guard-lambda
through AWS SAM-CLI - Deprecated
-j
as short flag forprint-json
- Updated names for artifacts to have
v3
in them - Added
rogue_one
branch to docker workflow, this will publish an ECR image for all updates to this remote branch as well
- Bumped up version to
Full Changelog: 3.0.0-alpha...3.0.0-beta
Table of Contents
- Built-in Functions and Stateful Rules
- Added alternative deployment method using SAM-CLI for
cfn-guard-lambda
- Updated the output to contain filename
- Updated combined structured output & default anonymous rule name
- Command auto-completions
Details
1. Built-in Functions and Stateful Rules
As of version 3.0.0 guard now supplies some builtin functions, allowing for stateful rules
NOTE: all examples are operating off the following yaml template
Data
(click to expand)
Resources:
newServer:
Type: AWS::New::Service
Properties:
Policy: |
{
"Principal": "*",
"Actions": ["s3*", "ec2*"]
}
Arn: arn:aws:newservice:us-west-2:123456789012:Table/extracted
Encoded: This%20string%20will%20be%20URL%20encoded
Collection:
- a
- b
- c
BucketPolicy:
PolicyText: '{"Version":"2012-10-17","Statement":[{"Sid":"DenyReducedReliabilityStorage","Effect":"Deny","Principal":"*","Action":"s3:*","Resource":"arn:aws:s3:::s3-test-123/*","Condition":{"StringEquals":{"s3:x-amz-storage-class-123":["ONEZONE_IA","REDUCED_REDUNDANCY"]}}}]}'
s3:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
bucket:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
String Manipulation Functions
The following functions all operate on queries that resolve to string values
1. json_parse()
The json_parse function adds support for parsing inline json strings from a given template. After parsing the string into an object,
you can now evaluate certain properties of this struct just like with a normal json/yaml object
This function accepts a single argument:
- this argument can either be a query that resolves to a string or a string literal.
The return value for this function is a query where each string that was resolved from the input is parsed into its json value
The following example shows how you could parse 2 fields on the above template and then write clauses on the results
Rule
(click to expand)
let template = Resources.*[ Type == 'AWS::New::Service']
rule TEST_JSON_PARSE when %template !empty {
let policy = %template.Properties.Policy
let res = json_parse(%policy)
%res !empty
%res == %expected
let policy_text = %template.BucketPolicy.PolicyText
let res2 = json_parse(%policy_text)
%res2.Statement[*]
{
Effect == "Deny"
Resource == "arn:aws:s3:::s3-test-123/*"
}
}
2. regex_replace()
The regex_replace function adds support for replacing one regular expression with another
This function accepts 3 arguments:
- The first argument is a query, each string that is resolved from this query will be operated on
- The second argument is either a query that resolves to a string or a string literal, this is the expression we are looking for to extract
- Note: if this string does not resolve to a valid regular expression an error will occur
- The third argument is either a query that resolves to a string or a string literal, this is the expression we are going to use replace the extracted part of the string
The return value for this function is a query where each string that was resolved from the input that contains the the regex from our 2nd argument is replaced with the regex in the 3rd argument
In this simple example, we will re-format an ARN by moving around some sections in it.
We will start with a normal ARN that has the following pattern: arn:<Partition>:<Service>:<Region>:<AccountID>:<ResourceType>/<ResourceID>
and we will try to convert it to: <Partition>/<AccountID>/<Region>/<Service>-<ResourceType>/<ResourceID>
Rule
(click to expand)
let template = Resources.*[ Type == 'AWS::New::Service']
rule TEST_REGEX_REPLACE when %template !empty {
%template.Properties.Arn exists
let arn = %template.Properties.Arn
let arn_partition_regex = "^arn:(\w+):(\w+):([\w0-9-]+):(\d+):(.+)$"
let capture_group_reordering = "${1}/${4}/${3}/${2}-${5}"
let res = regex_replace(%arn, %arn_partition_regex, %capture_group_reordering)
%res == "aws/123456789012/us-west-2/newservice-Table/extracted"
}
3. join()
The join function adds support to collect a query, and then join their values using the provided delimiter.
This function accepts 2 arguments:
- The first argument is a query, all string values resolved from this query will then be joined using the delimter argument
- The second argument is either a query that resolves to a string/character, or a literal value that is either a string or character
The return value for this function is query where each string that was resolved from the input is joined with the provided delimiter
The following example queries the template for a Collection field on a given resource, it then provides a join on ONLY the string values that this query resolves to with a ,
delimiter
Rule
(click to expand)
let template = Resources.*[ Type == 'AWS::New::Service']
rule TEST_COLLECTION when %template !empty {
let collection = %template.Collection.*
let res = join(%collection, ",")
%res == "a,b,c"
}
4. to_lower()
& 5. to_upper()
Both functions accept a single argument:
- This argument is a query that resolves to a string(s) - all strings resolved will have the operation applied on them
Both these functions are very similar, one manipulates all resolved strings from a query to lower case, and the other to upper case
Rule
(click to expand)
let type = Resources.newServer.Type
rule STRING_MANIPULATION when %type !empty {
let lower = to_lower(%type)
%lower == "aws::new::service"
%lower == /aws::new::service/
let upper = to_upper(%type)
%upper == "AWS::NEW::SERVICE"
%upper == /AWS::NEW::SERVICE/
}
6. substring()
The substring function adds support to collect a part of all strings resolved from a query
This function accepts 3 arguments:
- The first argument is a query, each string that is resolved from this query will be operated on
- The second argument is either a query that resolves to an int or a literal int, this is the starting index for the substring (inclusive)
- The third argument is either a query that resolves to an int or a literal int, this is the ending index for the substring (exclusive)
The return value for this function takes the strings resolved from the first argument, and returns a result of substrings for each one of them:
Note: Any string that would result in an index out of bounds from the 2nd or 3rd argument is skipped
Rule
(click to expand)
let template = Resources.*[ Type == 'AWS::New::Service']
rule TEST_SUBSTRING when %template !empty {
%template.Properties.Arn exists
let arn = %template.Properties.Arn
let res = substring(%arn, 0, 3)
%res == "arn"
}
7. url_decode()
This function accepts a single argument:
- this argument can either be a query that resolves to a string or a string literal.
The return value for this function is a query that contains each url decoded version of every string value from the input
The following rule shows how you could url_decode the string This%20string%20will%20be%20URL%20encoded
Rule
(click to expand)
let template = Resources.*[ Type == 'AWS::New::Service']
rule SOME_RULE when %template !empty {
%template.Properties.Encoded exists
let ...
v2.1.4
What's Changed
- Added OS-specific cargo targets to release workflow by @akshayrane in #310
- [Code Quality]: Rust-fmt action + formatting project by @joshfried-aws in #315
- [Code Quality]: Implementing custom writer, bug fixes, new integration test framework, and adding initial tests for all commands by @joshfried-aws in #325
- Bump tokio from 1.21.2 to 1.24.2 by @dependabot in #327
- +[fancy-regex] Added support for advanced regular expressions by @akshayrane in #326
- improved safety of serde_yaml::Value -> value conversion by @joshfried-aws in #328
- PR to add Thiserror to cfn-guard by @joshfried-aws in #329
- Redirected verbose output from stdout to custom writer and added unit… by @akshayrane in #332
- Addit cargo-audit to CI + bump up clap to 3.0 by @joshfried-aws in #330
- Implemented custom reader, increasing test coverage for validate command. by @joshfried-aws in #334
- Update CONTRIBUTING.md by @swiercek in #335
- Clap4 by @joshfried-aws in #336
- Added integration tests against aws-guard-rules-registry on Ubuntu by @akshayrane in #337
- Update check-tags-present.guard by @Aishwarya4400 in #313
- Added deprecated short flag for print-json in parse-tree by @akshayrane in #345
- Bump enumflags2 to 0.7.7 by @akshayrane in d10ed9c
New Contributors
- @swiercek made their first contribution in #335
- @Aishwarya4400 made their first contribution in #313
Full Changelog: 2.1.3...2.1.4
Details
Added support for advanced regular expressions
Supports usage of advanced regular expressions such as lookaround and backreferences.
Rules file (advanced_regex_negative_lookbehind_rule.guard)
NotAwsAccessKey != /(?<![A-Z0-9])[A-Z0-9]{20}(?![A-Z0-9])/
NotSecretAccessKey != /(?<![A-Za-z0-9\\/+=])[A-Za-z0-9\\/+=]{40}(?![A-Za-z0-9\\/+=])/
Data file (advanced_regex_negative_lookbehind_non_compliant.yaml) (click to expand)
NotAwsAccessKey: AKIAIOSFODNN7EXAMPLE
NotSecretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Command (click to expand)
cfn-guard validate \
-d guard/resources/validate/data-dir/advanced_regex_negative_lookbehind_non_compliant.yaml \
-r guard/resources/validate/rules-dir/advanced_regex_negative_lookbehind_rule.guard \
--show-summary all
Output with non-compliant template (click to expand)
advanced_regex_negative_lookbehind_non_compliant.yaml Status = FAIL
FAILED rules
advanced_regex_negative_lookbehind_rule.guard/default FAIL
---
Evaluation of rules advanced_regex_negative_lookbehind_rule.guard against data advanced_regex_negative_lookbehind_non_compliant.yaml
--
Property [/NotAwsAccessKey] in data [advanced_regex_negative_lookbehind_non_compliant.yaml] is not compliant with [advanced_regex_negative_lookbehind_rule.guard/default] because provided value ["AKIAIOSFODNN7EXAMPLE"] did match expected value ["/(?<![A-Z0-9])[A-Z0-9]{20}(?![A-Z0-9])/"]. Error Message []
Property [/NotSecretAccessKey] in data [advanced_regex_negative_lookbehind_non_compliant.yaml] is not compliant with [advanced_regex_negative_lookbehind_rule.guard/default] because provided value ["wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"] did match expected value ["/(?<![A-Za-z0-9\\/+=])[A-Za-z0-9\\/+=]{40}(?![A-Za-z0-9\\/+=])/"]. Error Message []
v3.0.0-alpha
New Features
- Added support for advanced regular expressions
- Improved handling for intrinsic functions in test command
- Added
--structured
flag to validate command to emit JSON/YAML parseable output
What's Changed
- Added OS-specific cargo targets to release workflow by @akshayrane in #310
- [Code Quality]: Rust-fmt action + formatting project by @joshfried-aws in #315
- [Code Quality]: Implementing custom writer, bug fixes, new integration test framework, and adding initial tests for all commands by @joshfried-aws in #325
- Bump tokio from 1.21.2 to 1.24.2 by @dependabot in #327
- +[fancy-regex] Added support for advanced regular expressions by @akshayrane in #326
- improved safety of serde_yaml::Value -> value conversion by @joshfried-aws in #328
- Improve handling of function references for test command by @joshfried-aws in #331
- PR to add Thiserror to cfn-guard by @joshfried-aws in #329
- Redirected verbose output from stdout to custom writer and added unit… by @akshayrane in #332
- Addit cargo-audit to CI + bump up clap to 3.0 by @joshfried-aws in #330
- Implemented custom reader, increasing test coverage for validate command. by @joshfried-aws in #334
- Update CONTRIBUTING.md by @swiercek in #335
- Clap4 by @joshfried-aws in #336
- Added integration tests against aws-guard-rules-registry on Ubuntu by @akshayrane in #337
- Update check-tags-present.guard by @Aishwarya4400 in #313
- Adding structured evaluator by @joshfried-aws in #339
- Added deprecated short flag for print-json in parse-tree by @akshayrane in #345
- bumping up to 3.0.0-alpha by @joshfried-aws in #347
New Contributors
- @swiercek made their first contribution in #335
- @Aishwarya4400 made their first contribution in #313
Full Changelog: 2.1.3...3.0.0-alpha
Details
1. Added support for advanced regular expressions
Supports usage of advanced regular expressions such as lookaround and backreferences.
Rules file (advanced_regex_negative_lookbehind_rule.guard)
NotAwsAccessKey != /(?<![A-Z0-9])[A-Z0-9]{20}(?![A-Z0-9])/
NotSecretAccessKey != /(?<![A-Za-z0-9\\/+=])[A-Za-z0-9\\/+=]{40}(?![A-Za-z0-9\\/+=])/
Data file (advanced_regex_negative_lookbehind_non_compliant.yaml) (click to expand)
NotAwsAccessKey: AKIAIOSFODNN7EXAMPLE
NotSecretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Command (click to expand)
cfn-guard validate \
-d guard/resources/validate/data-dir/advanced_regex_negative_lookbehind_non_compliant.yaml \
-r guard/resources/validate/rules-dir/advanced_regex_negative_lookbehind_rule.guard \
--show-summary all
Output with non-compliant template (click to expand)
advanced_regex_negative_lookbehind_non_compliant.yaml Status = FAIL
FAILED rules
advanced_regex_negative_lookbehind_rule.guard/default FAIL
---
Evaluation of rules advanced_regex_negative_lookbehind_rule.guard against data advanced_regex_negative_lookbehind_non_compliant.yaml
--
Property [/NotAwsAccessKey] in data [advanced_regex_negative_lookbehind_non_compliant.yaml] is not compliant with [advanced_regex_negative_lookbehind_rule.guard/default] because provided value ["AKIAIOSFODNN7EXAMPLE"] did match expected value ["/(?<![A-Z0-9])[A-Z0-9]{20}(?![A-Z0-9])/"]. Error Message []
Property [/NotSecretAccessKey] in data [advanced_regex_negative_lookbehind_non_compliant.yaml] is not compliant with [advanced_regex_negative_lookbehind_rule.guard/default] because provided value ["wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"] did match expected value ["/(?<![A-Za-z0-9\\/+=])[A-Za-z0-9\\/+=]{40}(?![A-Za-z0-9\\/+=])/"]. Error Message []
2. Improved handling for intrinsic functions in test command
With the test command, the intrinsic functions now get resolved to their equivalent JSON syntax.
Unit test file (intrinsic_fn_tests.yaml) (click to expand)
- name: a redshift cluster with short hand functions
input:
Resources:
myCluster:
Type: "AWS::Redshift::Cluster"
Properties:
DBName: "mydb"
KmsKeyId:
Fn::ImportValue:
!Sub "${pSecretKmsKey}"
expectations:
rules:
REDSHIFT_ENCRYPTED_CMK: PASS
Rule file (intrinsic_fn_rule.guard)
let redshift_clusters = Resources.*[ Type == 'AWS::Redshift::Cluster']
rule REDSHIFT_ENCRYPTED_CMK when %redshift_clusters !empty {
%redshift_clusters.Properties.KmsKeyId exists
%redshift_clusters.Properties.KmsKeyId == {"Fn::ImportValue": {"Fn::Sub":"${pSecretKmsKey}"}}
}
Command (click to expand)
cfn-guard test \
-t intrinsic_fn_tests.yaml \
-r intrinsic_fn_rule.guard
Output (click to expand)
Test Case #1
Name: a redshift cluster with short hand functions
PASS Rules:
REDSHIFT_ENCRYPTED_CMK: Expected = PASS
3. Added --structured
flag to validate command to emit JSON/YAML parseable output
Emits an output that could be directly parsed using native JSON and YAML parsers, in case of multiple files or directories passed as input with the new flag.
Command
cfn-guard validate \
-d guard/resources/validate/data-dir/s3-public-read-prohibited-template-non-compliant.yaml \
-d guard/resources/validate/data-dir/s3-public-read-prohibited-template-compliant.yaml \
-r guard/resources/validate/rules-dir/s3_bucket_public_read_prohibited.guard \
--structured -o json --show-summary none
Output (click to expand)
[
{
"name": "",
"metadata": {},
"status": "FAIL",
"not_compliant": [
{
"Rule": {
"name": "S3_BUCKET_PUBLIC_READ_PROHIBITED",
"metadata": {},
"messages": {
"custom_message": null,
"error_message": null
},
"checks": [
{
"Clause": {
"Unary": {
"context": " %s3_bucket_public_read_prohibited[*].Properties.PublicAccessBlockConfiguration EXISTS ",
"messages": {
"custom_message": "",
"error_message": "Check was not compliant as property [PublicAccessBlockConfiguration] is missing. Value traversed to [Path=/Resources/MyBucket/Properties[L:13,C:6] Value={\"BucketEncryption\":{\"ServerSideEncryptionConfiguration\":[{\"ServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"AES256\"}}]},\"VersioningConfiguration\":{\"Status\":\"Enabled\"}}]."
},
"check": {
"UnResolved": {
"value": {
"traversed_to": {
"path": "/Resources/MyBucket/Properties",
"value": {
"BucketEncryption": {
"ServerSideEncryptionConfiguration": [
{
"ServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
},
"VersioningConfiguration": {
"Status": "Enabled"
}
}
},
"remaining_query": "PublicAccessBlockConfiguration",
"reason": "Could not find key PublicAccessBlockConfiguration inside struct at path /Resources/MyBucket/Properties[L:13,C:6]"
},
"comparison": [
"Exists",
false
]
}
}
}
}
},
{
"Clause": {
"Binary": {
"context": " %s3_bucket_public_read_prohibited[*].Properties.PublicAccessBlockConfiguration.BlockPublicAcls EQUALS true",
"messages": {
"custom_message": "",
"error_message": "Check was not compliant as property [PublicAccessBlockConfiguration.BlockPublicAcls]...