From 96e9ff5889f2a1b1bf0304e52073499c80d51e3d Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Wed, 10 Jul 2024 13:02:13 -0400 Subject: [PATCH 1/7] add action for pushing policies --- .github/workflows/{lint.yml => main.yml} | 15 ++++- .github/workflows/upload.py | 74 ++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) rename .github/workflows/{lint.yml => main.yml} (67%) create mode 100644 .github/workflows/upload.py diff --git a/.github/workflows/lint.yml b/.github/workflows/main.yml similarity index 67% rename from .github/workflows/lint.yml rename to .github/workflows/main.yml index 55c4192..fe25178 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/main.yml @@ -1,11 +1,10 @@ -name: Lint policies - on: push: workflow_dispatch: jobs: lint: + name: Lint policies runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,3 +26,15 @@ jobs: - name: Regal Lint if: ${{ !cancelled() }} run: regal lint --format github . + + deploy: + name: Deploy policies + runs-on: ubuntu-latest + needs: lint + if: success() && github.ref == 'refs/heads/main' + + steps: + - uses: actions/checkout@v4 + + - name: Upload + run: .github/workflows/upload.py diff --git a/.github/workflows/upload.py b/.github/workflows/upload.py new file mode 100644 index 0000000..4e052a9 --- /dev/null +++ b/.github/workflows/upload.py @@ -0,0 +1,74 @@ +""" +Script to upload a set of policy files to Phylum. +""" + +import io +import json +import os +from pathlib import Path +import shutil +from urllib.error import HTTPError +from urllib.parse import quote +from urllib.request import Request, urlopen +import uuid + +# Set the group name if you are uploading policies for a group. +GROUP_NAME = None +token = os.environ["PHYLUM_TOKEN"] +version = os.environ.get("GITHUB_SHA", None) +BASE_ADDRESS = "https://api.staging.phylum.io/api/" + +# Build a multipart form body. +boundary = uuid.uuid4().hex +body = io.BytesIO() + +for file in Path.cwd().glob("*.rego"): + body.write(f"--{boundary}\r\n".encode("ascii")) + body.write( + f'Content-Disposition: form-data; name="{file.stem}"; filename="{file.name}"\r\n'.encode( + "ascii" + ) + ) + body.write(b"Content-Type: text/plain\r\n\r\n") + + with file.open("rb") as f: + shutil.copyfileobj(f, body) + + body.write(b"\r\n") + +body.write(f"--{boundary}--".encode("ascii")) + +# Send the request. +if GROUP_NAME is None: + endpoint = f"{BASE_ADDRESS}v0/available-policies" +else: + endpoint = ( + f"{BASE_ADDRESS}v0/groups/{quote(GROUP_NAME, safe='')}/available-policies" + ) + +if version is not None: + endpoint = f"{endpoint}?version={quote(version, safe='')}" + +request = Request( + endpoint, + data=body.getbuffer(), + headers={ + "Authorization": f"Bearer {token}", + "Content-Type": f'multipart/form-data;boundary="{boundary}"', + }, + method="PUT", +) + +try: + with urlopen(request) as f: + pass +except HTTPError as error: + response = error.read().decode("utf8", errors="replace") + try: + # Phylum's API returns JSON error descriptions. + # If that's what we got, reformat it to be more readable. + response = json.dumps(json.loads(response), indent=2) + except json.JSONDecodeError: + pass + print(response) + exit(1) From 746ad609cb4cd155a2de84ad840ed647dea306b3 Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Mon, 10 Feb 2025 11:42:18 -0500 Subject: [PATCH 2/7] point to prod --- .github/workflows/upload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/upload.py b/.github/workflows/upload.py index 4e052a9..6c5ee64 100644 --- a/.github/workflows/upload.py +++ b/.github/workflows/upload.py @@ -16,7 +16,7 @@ GROUP_NAME = None token = os.environ["PHYLUM_TOKEN"] version = os.environ.get("GITHUB_SHA", None) -BASE_ADDRESS = "https://api.staging.phylum.io/api/" +BASE_ADDRESS = "https://api.phylum.io/api/" # Build a multipart form body. boundary = uuid.uuid4().hex From 9235fd23996920b1329e86a2407914b6794f76f5 Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Mon, 10 Feb 2025 11:59:59 -0500 Subject: [PATCH 3/7] restrict token permissions --- .github/workflows/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2b0b670..720a63e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,6 +6,8 @@ jobs: lint: name: Lint policies runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v4 @@ -30,6 +32,8 @@ jobs: deploy: name: Deploy policies runs-on: ubuntu-latest + permissions: + contents: read needs: lint if: success() && github.ref == 'refs/heads/main' From a3991a8160c1aaeb6727008c48bf7185722e3805 Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Mon, 10 Feb 2025 12:00:35 -0500 Subject: [PATCH 4/7] connect secret to step --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 720a63e..3f62c56 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -41,4 +41,6 @@ jobs: - uses: actions/checkout@v4 - name: Upload + env: + PHYLUM_TOKEN: ${{ secrets.PHYLUM_TOKEN }} run: .github/workflows/upload.py From 7048d08f4f7813ac76e25eccd15d02e0e65db01b Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Mon, 10 Feb 2025 12:01:53 -0500 Subject: [PATCH 5/7] python script is not an executable --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3f62c56..de37173 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,4 +43,4 @@ jobs: - name: Upload env: PHYLUM_TOKEN: ${{ secrets.PHYLUM_TOKEN }} - run: .github/workflows/upload.py + run: python3 .github/workflows/upload.py From e3b5a7e6b3725285135800122869a11167e7fc02 Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Mon, 10 Feb 2025 14:22:08 -0500 Subject: [PATCH 6/7] rename secret --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index de37173..7c56007 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,5 +42,5 @@ jobs: - name: Upload env: - PHYLUM_TOKEN: ${{ secrets.PHYLUM_TOKEN }} + PHYLUM_TOKEN: ${{ secrets.PHYLUM_POLICY_TOKEN }} run: python3 .github/workflows/upload.py From d6027780b1685fe7528a647b08c297d43af7b246 Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Mon, 10 Feb 2025 15:41:22 -0500 Subject: [PATCH 7/7] fix lints Co-authored-by: Charles Coggins --- .github/workflows/upload.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/upload.py b/.github/workflows/upload.py index 6c5ee64..b3d0056 100644 --- a/.github/workflows/upload.py +++ b/.github/workflows/upload.py @@ -2,6 +2,7 @@ Script to upload a set of policy files to Phylum. """ +import contextlib import io import json import os @@ -11,6 +12,7 @@ from urllib.parse import quote from urllib.request import Request, urlopen import uuid +import sys # Set the group name if you are uploading policies for a group. GROUP_NAME = None @@ -64,11 +66,9 @@ pass except HTTPError as error: response = error.read().decode("utf8", errors="replace") - try: + with contextlib.suppress(json.JSONDecodeError): # Phylum's API returns JSON error descriptions. # If that's what we got, reformat it to be more readable. response = json.dumps(json.loads(response), indent=2) - except json.JSONDecodeError: - pass print(response) - exit(1) + sys.exit(1)