From 72352d1e5414e496ab75fae216119e65d8e61d53 Mon Sep 17 00:00:00 2001 From: George Rolston Date: Thu, 1 Sep 2022 16:16:39 -0600 Subject: [PATCH] feat: resource map (#222) * adding in all rules build * doc update * bump version --- .github/workflows/build.yml | 9 ++++++-- .github/workflows/ci.yml | 9 ++++++-- .github/workflows/publish.yml | 8 ++++--- docs/Guard-Rules-Dev-Guide.md | 5 ++-- mappings/build.py | 43 +++++++++++++++++++++++++++++++++-- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f109a10..b8abec8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,9 @@ on: branches: - main +env: + VERSION: "1.0.2" + jobs: testRules: runs-on: ubuntu-latest @@ -30,10 +33,12 @@ jobs: uses: actions/checkout@v2 - run: | chmod +x ./mappings/build.py - python3 ./mappings/build.py + python3 ./mappings/build.py -r $VERSION shell: bash - uses: actions/upload-artifact@v3 with: name: ruleset-build - path: docker/output/ + path: | + docker/output/ + mappings/rule_set_guard_rules_registry_all_rules.json if-no-files-found: error \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c5de43..7d69cab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ on: branches: - main +env: + VERSION: "1.0.2" + jobs: testRules: runs-on: ubuntu-latest @@ -30,10 +33,12 @@ jobs: uses: actions/checkout@v2 - run: | chmod +x ./mappings/build.py - python3 ./mappings/build.py + python3 ./mappings/build.py -r $VERSION shell: bash - uses: actions/upload-artifact@v3 with: name: ruleset-build - path: docker/output/ + path: | + docker/output/ + mappings/rule_set_guard_rules_registry_all_rules.json if-no-files-found: error diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c9d2285..11c6f98 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,7 +12,7 @@ env: ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }} ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }} ## publish version for docker image - VERSION: "1.0.1" + VERSION: "1.0.2" jobs: testRules: @@ -38,12 +38,14 @@ jobs: - name: Check out repo uses: actions/checkout@v2 - run: | - python3 ./mappings/build.py + python3 ./mappings/build.py -r $VERSION shell: bash - uses: actions/upload-artifact@v3 with: name: ruleset-build - path: docker/output/ + path: | + docker/output/ + mappings/rule_set_guard_rules_registry_all_rules.json if-no-files-found: error buildDockerRelease: diff --git a/docs/Guard-Rules-Dev-Guide.md b/docs/Guard-Rules-Dev-Guide.md index 4d5124d..2346196 100644 --- a/docs/Guard-Rules-Dev-Guide.md +++ b/docs/Guard-Rules-Dev-Guide.md @@ -1,6 +1,6 @@ # Guard Rule Contribution Guide -The following details the development requirements to submit individual Guard rules for use in the Guard Rules Registry. The development conventions and standards allow Guard Rule Registry to be a modular and support Guard Rule Sets builds via the Guard Map process. All Guard Rule contributions must follow the standards in order for pull-request to be approved. +The following details the development requirements to submit individual Guard rules for use in the Guard Rules Registry. The development conventions and standards allow Guard Rule Registry to be modular and support Guard Rule Set builds via the Guard Map process. All Guard Rule contributions must follow the standards in order for pull-request to be approved. ## Guidelines and Conventions Summary @@ -29,7 +29,6 @@ This section provides general rules and conventions to follow when developing a * All Guard rule files will have a corresponding test file. (reference example [Writing Unit Tests](#writing-unit-tests)) * The tests sub-directory contains unit tests for some of the corner cases we expect a Guard rule to have a status of `PASS`/`FAIL`/`SKIP`. Each status should be tested for all guard rules - ## Rules Directory Structure 1. All Guard rules in this repository are stored under the `rules` directory. @@ -86,7 +85,7 @@ The following outlines the general process to develop individual AWS Guard Rules # c) FAIL: when all dynamodb table resources do not have the ObjectLockEnabled property is set to true or is missing # d) SKIP: when metadata has rule suppression for DYNAMODB_PITR_ENABLED ``` -5. Below the header, define the assignments required for a given rule and add comments to the rule wherever possible to make it easier for humans to understand. **AWS Guard Rules support rule suppression and requires you to add the guard rule name during variable assignment.** By adding in the `SuppressedRules` metadata, you override the rule within the code-base give ability to express rule exceptions at the code-level. **Assignment names should be try to unique within the Rules Registry. Be verbose and detailed in naming the assignment.** +5. Below the header, define the assignments required for a given rule and add comments to the rule wherever possible to make it easier for humans to understand. **AWS Guard Rule Registry supports rule suppression and requires you to add the guard rule name during variable assignment as shown below.** By adding in the `SuppressedRules` metadata, you override the rule within the code-base giving ability to express rule exceptions at the code-level. **Assignment names should be unique within the Guard Rules Registry. Be verbose and detailed in naming the assignment.** ``` # # Select all DynamoDB Table resources from incoming template (payload) diff --git a/mappings/build.py b/mappings/build.py index 4489a5e..e439c3b 100644 --- a/mappings/build.py +++ b/mappings/build.py @@ -5,6 +5,42 @@ import json import glob import re +import urllib.request + +def download_resource_type_list(): + url = "https://cloudformation-schema.s3.us-west-2.amazonaws.com/resourcetypelist.json" + response = urllib.request.urlopen(url) + data = json.loads(response.read()) + return data + +def create_guard_rules_registry_all_rules(dirName, version): + aws_rules_directory = dirName + '/rules/aws/**/*.guard' + controls = ["all rules in AWS Guard Rules Registry"] + mappings = [] + resource_list = download_resource_type_list() + for build_file in glob.iglob(aws_rules_directory, recursive=True): + reports_on = [] + build_file_relative_path = os.path.relpath(build_file) + for resource in resource_list: + with open(build_file) as build_file_contents: + if re.search(resource, build_file_contents.read()) is not None: + reports_on.append(resource) + rule_json = { + "guardFilePath": build_file_relative_path, + "reportsOn": reports_on, + "controls": controls + } + mappings.append(rule_json) + all_rules_json = { + "owner": "AWS", + "ruleSetName": "guard-rules-registry-all-rules", + "version": version, + "description": "All AWS Guard Rules Registry in single rule set", + "contact": "aws-guard-rules-registry@amazon.com", + "mappings": mappings + } + with open('mappings/rule_set_guard_rules_registry_all_rules.json', 'w', encoding='utf-8') as outfile: + json.dump(all_rules_json, outfile, ensure_ascii=False, indent=2) def create_output_directory(): path = "./docker/output/" @@ -36,7 +72,8 @@ def build_custom_message(rule_set, control_list ): '''.format(ruleset=rule_set, Control_List=control_list ) return message -def main(directory): +def main(directory, version): + create_guard_rules_registry_all_rules(directory, version) basedirectory = directory + '/mappings/rule_set_*.json' create_output_directory() for build_file in glob.iglob(basedirectory, recursive=True): @@ -63,6 +100,8 @@ def main(directory): if __name__ == '__main__': parser = argparse.ArgumentParser(description='Guard Rules Registry Build') parser.add_argument("-d","--directory", required=False,default=os.getcwd(),help="Directory to download the audio to") + parser.add_argument("-r","--release", required=True,default="1.0.0",help="The release version for all rules file") args = parser.parse_args() directory = args.directory - main(directory) + version = args.release + main(directory, version)