Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ jobs:
steps.filter.outputs.shared == 'true' }}
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/ci.yml | head -250

Repository: ByronWilliamsCPA/python-libs

Length of output: 9248


Disable persisted Git credentials in all PR-executed checkout actions.

Lines 45, 74, 122, 166, and 191 perform checkout in pull_request workflows. Since none of the subsequent steps require authenticated git operations, add persist-credentials: false to each checkout action to follow the principle of least privilege and reduce attack surface.

Required changes
       - name: Checkout repository
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false

Apply this change to lines 45, 74, 122, 166, and 191.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 45, Update each GitHub Actions checkout
step that runs in pull_request workflows to disable persisted Git credentials by
adding the option persist-credentials: false to the checkout action invocations;
specifically modify the occurrences of "uses:
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" (the checkout steps
present at the referenced locations) so they include a keys block with
persist-credentials: false to prevent supplying repo credentials to subsequent
steps.


- name: Detect path changes
uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3.0.3
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
Comment on lines +45 to +48
id: filter
with:
filters: |
Expand All @@ -71,10 +71,10 @@ jobs:
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand Down Expand Up @@ -102,7 +102,7 @@ jobs:

- name: Upload coverage artifact
if: matrix.python-version == '3.12'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: coverage-cloudflare-auth
path: coverage-cloudflare-auth.xml
Expand All @@ -119,10 +119,10 @@ jobs:
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand Down Expand Up @@ -150,7 +150,7 @@ jobs:

- name: Upload coverage artifact
if: matrix.python-version == '3.12'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: coverage-gcs-utilities
path: coverage-gcs-utilities.xml
Expand All @@ -163,10 +163,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand All @@ -188,16 +188,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Download coverage artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: coverage-*
merge-multiple: true

- name: Upload to Codecov
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
with:
files: coverage-cloudflare-auth.xml,coverage-gcs-utilities.xml
fail_ci_if_error: false
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,31 @@ jobs:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.12"

- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

- name: Install dependencies
run: uv sync --no-dev

- name: Initialize CodeQL
uses: github/codeql-action/init@0daab03d71ff584ef619d027a3fd9146679c5d84 # v3.35.3
uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
with:
languages: python
build-mode: none
queries: security-extended,security-and-quality

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@0daab03d71ff584ef619d027a3fd9146679c5d84 # v3.35.3
uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
with:
category: "/language:python"
4 changes: 2 additions & 2 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Dependency Review
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
fail-on-severity: high
allow-licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, MPL-2.0, LGPL-2.1, LGPL-3.0, Python-2.0, Unlicense, CC0-1.0, GPL-3.0-or-later
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ jobs:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# Find and examine the workflow file
find . -path "./.github/workflows/pr-validation.yml" -type f

Repository: ByronWilliamsCPA/python-libs

Length of output: 110


🏁 Script executed:

# Read the workflow file to see the context around line 64
cat -n .github/workflows/pr-validation.yml | head -80

Repository: ByronWilliamsCPA/python-libs

Length of output: 3282


🏁 Script executed:

# Check the entire workflow for any authenticated git operations
cat -n .github/workflows/pr-validation.yml | tail -20

Repository: ByronWilliamsCPA/python-libs

Length of output: 971


🏁 Script executed:

# Also check if there are any other checkout actions or git operations in this file
grep -n "git\|push\|commit\|credentials" .github/workflows/pr-validation.yml

Repository: ByronWilliamsCPA/python-libs

Length of output: 331


Harden checkout by disabling credential persistence.

This job executes repository code from pull requests; keep the GITHUB_TOKEN out of git config since no authenticated git operations are performed.

Suggested hardening
       - name: Checkout repository
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-validation.yml at line 64, The checkout step currently
uses "uses: actions/checkout@de0fac2e4500d..." without disabling credential
persistence; update the checkout action invocation (the actions/checkout usage)
to include a with: persist-credentials: false setting so the GITHUB_TOKEN is not
written into git config for PR workflows.


- name: Install UV
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/publish-artifact-registry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0

Expand Down Expand Up @@ -169,12 +169,12 @@ jobs:
# export-type: env

- name: Authenticate to Google Cloud
uses: google-github-actions/auth@c200f3691d83b41bf9bbd8638997a462592937ed # v2
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3
with:
credentials_json: ${{ secrets.GCP_SA_KEY_BASE64 }}

Comment on lines +172 to 175
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat .github/workflows/publish-artifact-registry.yml

Repository: ByronWilliamsCPA/python-libs

Length of output: 8895


🏁 Script executed:

cat .github/workflows/publish-artifact-registry.yml | head -200

Repository: ByronWilliamsCPA/python-libs

Length of output: 6976


🏁 Script executed:

cat .github/workflows/publish-artifact-registry.yml

Repository: ByronWilliamsCPA/python-libs

Length of output: 8895


🌐 Web query:

google-github-actions/auth credentials_json format documentation

💡 Result:

The credentials_json input for the google-github-actions/auth GitHub Action expects the raw content of a Google Cloud Service Account Key JSON file [1][2]. To use this input correctly: 1. Format: The value must be the valid JSON object exported from the Google Cloud Console for a Service Account [2]. 2. Storage: It is strongly recommended to store this JSON as a GitHub Actions Secret [1][2]. 3. Best Practice: The documentation advises minifying the JSON into a single-line string before saving it as a GitHub Secret [1]. This prevents issues where GitHub Actions might aggressively sanitize or mask characters (such as curly braces or brackets) if the secret contains multiple lines [1]. 4. Usage in YAML: Reference the secret in your workflow file as follows [1][2]: - uses: 'google-github-actions/auth@v3' with: credentials_json: '${{ secrets.YOUR_SECRET_NAME }}' Important Security Note: Google and the maintainers of google-github-actions/auth strongly prefer using Workload Identity Federation over Service Account Key JSONs [1][3][4]. Workload Identity Federation eliminates the need for long-lived keys, which are a significant security risk if compromised [3][4]. If you must use credentials_json, ensure the service account has the roles/iam.serviceAccountTokenCreator role on itself [1][2].

Citations:


Fix credentials_json to receive raw JSON, not base64-encoded.

The credentials_json parameter for google-github-actions/auth expects the raw JSON content of a Service Account Key. The secret is base64-encoded (as evidenced by the base64 -d decoding on line 192), which will cause authentication to fail at this step.

Store the raw JSON key (minified) as a separate secret (e.g., GCP_SA_KEY_JSON), or decode the base64 before passing it: credentials_json: ${{ fromJSON(base64ToJson(secrets.GCP_SA_KEY_BASE64)) }} if using base64.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/publish-artifact-registry.yml around lines 172 - 175, The
workflow is passing a base64-encoded secret into the google-github-actions/auth
step's credentials_json input (the step using google-github-actions/auth), but
credentials_json must receive raw JSON; either replace the secret with a
raw-minified JSON secret (e.g., GCP_SA_KEY_JSON) and set credentials_json to
that secret, or decode the base64 before passing it by using GitHub Actions
functions (e.g., convert base64 to JSON and feed the result) so the
credentials_json parameter receives the actual Service Account JSON rather than
the encoded string.

- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@e427ad8a34f8676edf47cf7d7925499adf3eb74f # v2
uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3

- name: Configure Artifact Registry authentication
env:
Expand All @@ -190,7 +190,7 @@ jobs:
echo "📦 Registry URL: $AR_URL"

- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand All @@ -70,13 +70,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
token: "${{ secrets.GITHUB_TOKEN }}"

- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand All @@ -88,7 +88,7 @@ jobs:

- name: Python Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@0dc72ac9058a62054a45f6344c83a423d7f906a8 # v9.21.1
uses: python-semantic-release/python-semantic-release@350c48fcb3ffcdfd2e0a235206bc2ecea6b69df0 # v10.5.3
with:
github_token: "${{ secrets.GITHUB_TOKEN }}"

Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/slsa-provenance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ jobs:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.12"

- name: Install UV
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand All @@ -81,14 +81,14 @@ jobs:
echo "hashes=$HASHES" >> $GITHUB_OUTPUT

- name: Upload build artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: dist-${{ steps.version.outputs.version }}
path: dist/
retention-days: 90

- name: Generate artifact attestation
uses: actions/attest-build-provenance@def455f501ff622b3e6c35f7b7d1c8712b81d7e1 # v1.5.2
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: 'dist/*'

Expand Down
Loading