From dc330dac2d0848d36b5b88956c3b35659827d0f2 Mon Sep 17 00:00:00 2001 From: Joshua Donovan <104018981+Joshua-Donovan@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:43:35 -0600 Subject: [PATCH 1/6] Create validate-policy-id.yaml --- .github/workflows/validate-policy-id.yaml | 194 ++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 .github/workflows/validate-policy-id.yaml diff --git a/.github/workflows/validate-policy-id.yaml b/.github/workflows/validate-policy-id.yaml new file mode 100644 index 00000000..71a29bfb --- /dev/null +++ b/.github/workflows/validate-policy-id.yaml @@ -0,0 +1,194 @@ +name: Confirm Policy Definition has Unique ID and does not conflict with Built-In Policies + +on: + pull_request: + branches: + - main + +jobs: + # ------------------------------------------------------------- + # Using GitHub's API + # ------------------------------------------------------------- + # Event `pull_request`: Returns all changed pull request files. + # -------------------------------------------------------------- + validate-built-in-policy-id: + name: Validate Policy Definition Unique ID + runs-on: ubuntu-latest + permissions: + pull-requests: read + steps: + - uses: actions/checkout@v3 + + - name: Get changed files + id: changed_files + uses: tj-actions/changed-files@v37 + with: + separator: "§" # we need a character which isn't used within a file name or path + + - name: Validate Policy Definition Unique ID & Check for Built-In Policy Conflicts + if: ${{ steps.changed_files.outputs.any_changed }} == 'true' + env: + GH_SEARCH_TOKEN: ${{ secrets.GH_SEARCH_TOKEN }} + shell: bash + run: > + echo 'Step 1: Checking if azurepolicy.json file exists...' + + filesString="${{ steps.changed_files.outputs.all_changed_files }}" + + echo " Info: found changed files - $filesString" + + IFS='§' read -ra files <<< "$filesString" + + echo " Info: changed files converted to array, ready to check each file..." + + for file in "${files[@]}"; do + echo " Checking file name: ${file}" + if echo "$file" | grep -q 'azurepolicy.json'; then + policyFile=$file + echo " Success: azurepolicy.json file found... policyFile <-- $file" + break + fi + done + + if [ ! -f "$policyFile" ]; then + echo "" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - VALIDATION FAILED - |' + echo ' | File NOT FOUND: azurepolicy.json |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - NEXT STEPS - |' + echo ' | Please make sure your main Policy Definition file is included, |' + echo ' | and the file is named azurepolicy.json. |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo "" + exit 1 + fi + + echo "Step 2: Attempting to return policy name from $policyFile" + + policyName=$(jq -r '.name' "${policyFile}") + + echo " Success: name field found in azurepolicy.json... policyName <-- ${policyName}" + + if [ -z "$policyName" ]; then + echo "" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - VALIDATION FAILED - |' + echo ' | Policy Name not found in azurepolicy.json file |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - NEXT STEPS - |' + echo ' | Please make sure a name is present in azurepolicy.json |' + echo ' | Please make sure the name is a valid GUID |' + echo ' | |' + echo ' | What is a GUID? https://www.rfc-editor.org/rfc/rfc4122 |' + echo ' | Make a new GUID in PowerShell: https://aka.ms/new-guid |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo "" + exit 1 + elif [[ ! $policyName =~ ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ ]]; then + echo "" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - VALIDATION FAILED - |' + echo ' | Policy name is not a valid GUID |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - NEXT STEPS - |' + echo ' | Please change the policy name to a unique GUID |' + echo ' | |' + echo ' | What is a GUID? https://www.rfc-editor.org/rfc/rfc4122 |' + echo ' | Make a new GUID in PowerShell: https://aka.ms/new-guid |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo "" + exit 1 + else + echo " Success: Policy Name $policyName exists and is a valid GUID." + echo 'Step 3: Sending request to GitHub API to search for Policy Name in Azure Policy Repo...' + + response=$(curl -s \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token $GH_SEARCH_TOKEN" \ + "https://api.github.com/search/code?q=$policyName+in:file+language:json+repo:Azure/azure-policy") + + if [ -z "$response" ]; then + echo ' Error: API Response - No response from GitHub API.' + exit 1 + else + echo ' Success: Response from GitHub API received.' + fi + + if [ "$(echo $response | jq '.message')" = '"Bad credentials"' ]; then + echo ' Error: API Response - Bad credentials. Please check the GH_SEARCH_TOKEN secret.' + echo ' Next Steps: This one is on us, please open an issue if you see this error.' + exit 1 + elif [ "$(echo $response | jq '.message')" = '"Requires authentication"' ]; then + echo ' Error: API Response - API requires authentication. Please make sure we are passing the Authorization Header.' + echo ' Next Steps: This one is on us, please open an issue if you see this error.' + exit 1 + elif [ -z "$(echo $response | jq '.total_count')" ]; then + echo ' Error: API Response - Something went wrong... No total_count found in response body.' + echo ' Next Steps: This one is on us, please open an issue if you see this error.' + exit 1 + fi + if [ "$(echo $response | jq '.total_count')" == 0 ]; then + echo ' Success: GUID not found in Built-In Azure Policy Repo.' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - VALIDATION SUCCESS - |' + echo ' | Policy name is a valid GUID |' + echo ' | and does not match existing built-in Policy Definition |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + exit 0 + else + echo "" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - VALIDATION FAILED - |' + echo ' | Policy name exists in the Built-In Azure Policy Repo |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo " Built-in Policy URL: $(echo $response | jq -r '.items[0].html_url')" + echo "" + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - NEXT STEPS - |' + echo ' | Please change the policy name to a unique GUID |' + echo ' | Please do not submit only slightly altered built-in policies |' + echo ' | |' + echo ' | What is a GUID? https://www.rfc-editor.org/rfc/rfc4122 |' + echo ' | Make a new GUID in PowerShell: https://aka.ms/new-guid |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo "" + echo "" + exit 1 + fi + fi From 81486ef00b600b7a870762adb2d900583a4d98af Mon Sep 17 00:00:00 2001 From: Joshua Donovan <104018981+Joshua-Donovan@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:45:34 -0600 Subject: [PATCH 2/6] Update validate-policy-id.yaml --- .github/workflows/validate-policy-id.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/validate-policy-id.yaml b/.github/workflows/validate-policy-id.yaml index 71a29bfb..9c7733b8 100644 --- a/.github/workflows/validate-policy-id.yaml +++ b/.github/workflows/validate-policy-id.yaml @@ -4,6 +4,7 @@ on: pull_request: branches: - main + - guid-validation jobs: # ------------------------------------------------------------- From a3342036065f3c63bd95a16af3430eb097d54ec6 Mon Sep 17 00:00:00 2001 From: Joshua Donovan <104018981+Joshua-Donovan@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:51:02 -0600 Subject: [PATCH 3/6] Update validate-policy-id.yaml --- .github/workflows/validate-policy-id.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/validate-policy-id.yaml b/.github/workflows/validate-policy-id.yaml index 9c7733b8..6d5af069 100644 --- a/.github/workflows/validate-policy-id.yaml +++ b/.github/workflows/validate-policy-id.yaml @@ -44,6 +44,24 @@ jobs: for file in "${files[@]}"; do echo " Checking file name: ${file}" + if echo "$file" | grep -q '.github/workflows'; then + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - VALIDATION EXEMPT - |' + echo ' | .github/workflows directory detected |' + echo ' | This directory is exempt from policy validation |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + exit 0 + if echo "$file" | grep -q 'Scripts/'; then + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + echo ' | |' + echo ' | - VALIDATION EXEMPT - |' + echo ' | Scripts directory detected |' + echo ' | This directory is exempt from policy validation |' + echo ' | |' + echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' + exit 0 if echo "$file" | grep -q 'azurepolicy.json'; then policyFile=$file echo " Success: azurepolicy.json file found... policyFile <-- $file" From 5aac02067f66698a72eee99178c239bf11aded0b Mon Sep 17 00:00:00 2001 From: Joshua Donovan <104018981+Joshua-Donovan@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:53:41 -0600 Subject: [PATCH 4/6] Update validate-policy-id.yaml --- .github/workflows/validate-policy-id.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/validate-policy-id.yaml b/.github/workflows/validate-policy-id.yaml index 6d5af069..20aa894c 100644 --- a/.github/workflows/validate-policy-id.yaml +++ b/.github/workflows/validate-policy-id.yaml @@ -44,7 +44,7 @@ jobs: for file in "${files[@]}"; do echo " Checking file name: ${file}" - if echo "$file" | grep -q '.github/workflows'; then + if echo "$file" | grep -q 'github/workflows'; then echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' echo ' | |' echo ' | - VALIDATION EXEMPT - |' @@ -53,6 +53,7 @@ jobs: echo ' | |' echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' exit 0 + if echo "$file" | grep -q 'Scripts/'; then echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' echo ' | |' @@ -62,6 +63,7 @@ jobs: echo ' | |' echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' exit 0 + if echo "$file" | grep -q 'azurepolicy.json'; then policyFile=$file echo " Success: azurepolicy.json file found... policyFile <-- $file" From e2e95bbe45798ae07be5641762e7a8b62f1ce562 Mon Sep 17 00:00:00 2001 From: Joshua Donovan <104018981+Joshua-Donovan@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:01:56 -0600 Subject: [PATCH 5/6] Update validate-policy-id.yaml --- .github/workflows/validate-policy-id.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/validate-policy-id.yaml b/.github/workflows/validate-policy-id.yaml index 20aa894c..1b7b4bb1 100644 --- a/.github/workflows/validate-policy-id.yaml +++ b/.github/workflows/validate-policy-id.yaml @@ -53,7 +53,7 @@ jobs: echo ' | |' echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' exit 0 - + fi if echo "$file" | grep -q 'Scripts/'; then echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' echo ' | |' @@ -63,7 +63,7 @@ jobs: echo ' | |' echo ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////' exit 0 - + fi if echo "$file" | grep -q 'azurepolicy.json'; then policyFile=$file echo " Success: azurepolicy.json file found... policyFile <-- $file" From 0a3ef615da461a96f16ee2942181fe26d7be6933 Mon Sep 17 00:00:00 2001 From: Joshua Donovan <104018981+Joshua-Donovan@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:09:47 -0600 Subject: [PATCH 6/6] Update validate-policy-id.yaml Remove guid-validation branch from triggers, was used in testing. --- .github/workflows/validate-policy-id.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/validate-policy-id.yaml b/.github/workflows/validate-policy-id.yaml index 1b7b4bb1..5b1788f8 100644 --- a/.github/workflows/validate-policy-id.yaml +++ b/.github/workflows/validate-policy-id.yaml @@ -4,7 +4,6 @@ on: pull_request: branches: - main - - guid-validation jobs: # -------------------------------------------------------------