Skip to content
Merged
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
45 changes: 43 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ concurrency:

permissions:
contents: read
pull-requests: write
checks: write

jobs:
# Detect which packages have changed
detect-changes:
name: Detect Changed Packages
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
cloudflare-auth: ${{ steps.filter.outputs.cloudflare-auth }}
gcs-utilities: ${{ steps.filter.outputs.gcs-utilities }}
Expand All @@ -41,6 +42,11 @@ jobs:
steps.filter.outputs.gcs-utilities == 'true' ||
steps.filter.outputs.shared == 'true' }}
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

Expand All @@ -65,11 +71,18 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.cloudflare-auth == 'true' || needs.detect-changes.outputs.shared == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

Expand Down Expand Up @@ -113,11 +126,18 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.gcs-utilities == 'true' || needs.detect-changes.outputs.shared == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

Expand Down Expand Up @@ -161,7 +181,14 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.any-package == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

Expand All @@ -186,7 +213,14 @@ jobs:
needs: [test-cloudflare-auth, test-gcs-utilities]
if: always() && (needs.test-cloudflare-auth.result == 'success' || needs.test-gcs-utilities.result == 'success')
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

Expand All @@ -212,7 +246,14 @@ jobs:
runs-on: ubuntu-latest
needs: [detect-changes, test-cloudflare-auth, test-gcs-utilities, security, coverage]
if: always()
permissions:
contents: read
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Check all jobs
env:
NEEDS_JSON: ${{ toJSON(needs) }}
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
name: Upload Coverage
# Only run on successful CI completion
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: ByronWilliamsCPA/.github/.github/workflows/python-codecov.yml@main
uses: ByronWilliamsCPA/.github/.github/workflows/python-codecov.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
with:
artifact-name: 'coverage-reports'
coverage-files: '*.xml'
Expand All @@ -37,7 +37,14 @@ jobs:
name: Report CI Failure
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
permissions:
contents: read
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Report status
run: |
echo "## Coverage Upload Skipped" >> $GITHUB_STEP_SUMMARY
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
upload-coverage:
name: Upload Coverage to Qlty
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
uses: ByronWilliamsCPA/.github/.github/workflows/python-qlty-coverage.yml@main
uses: ByronWilliamsCPA/.github/.github/workflows/python-qlty-coverage.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
with:
coverage-artifact-name: coverage-reports
coverage-file-path: coverage.xml
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ on:

permissions:
contents: read
pull-requests: write

jobs:
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

Expand Down
10 changes: 6 additions & 4 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ on:
workflow_dispatch:

permissions:
contents: write
pages: write
id-token: write
contents: read

jobs:
docs:
uses: ByronWilliamsCPA/.github/.github/workflows/python-docs.yml@main
permissions:
contents: write
pages: write
id-token: write
uses: ByronWilliamsCPA/.github/.github/workflows/python-docs.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
with:
python-version: '3.12'
docs-directory: 'docs'
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/fips-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ concurrency:

permissions:
contents: read
pull-requests: write

jobs:
fips-check:
uses: ByronWilliamsCPA/.github/.github/workflows/python-fips-compatibility.yml@main
permissions:
contents: read
pull-requests: write
uses: ByronWilliamsCPA/.github/.github/workflows/python-fips-compatibility.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
with:
strict-mode: ${{ github.event.inputs.strict_mode == 'true' }}
include-tests: true
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/publish-artifact-registry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ concurrency:

permissions:
contents: read
id-token: write

env:
UV_VERSION: "0.5.x"
Expand All @@ -58,7 +57,15 @@ jobs:
publish:
name: Build and Publish
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ permissions:

jobs:
compatibility:
uses: ByronWilliamsCPA/.github/.github/workflows/python-compatibility.yml@main
uses: ByronWilliamsCPA/.github/.github/workflows/python-compatibility.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
with:
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
operating-systems: '["ubuntu-latest"]'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/qlty.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ concurrency:
jobs:
qlty:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: ByronWilliamsCPA/.github/.github/workflows/python-qlty-coverage.yml@main
uses: ByronWilliamsCPA/.github/.github/workflows/python-qlty-coverage.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
permissions:
contents: read
actions: read
Expand Down
20 changes: 17 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ concurrency:
cancel-in-progress: false

permissions:
contents: write
issues: write
pull-requests: write
contents: read

# Standalone release workflow
jobs:
test:
name: Pre-Release Tests
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
Expand All @@ -68,7 +73,16 @@ jobs:
name: Semantic Release
needs: test
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- name: Harden the runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/sbom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ on:

permissions:
contents: read
security-events: write

jobs:
sbom:
name: SBOM & Security
uses: ByronWilliamsCPA/.github/.github/workflows/python-sbom.yml@main
permissions:
contents: read
security-events: write
uses: ByronWilliamsCPA/.github/.github/workflows/python-sbom.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
with:
python-version: '3.12'
fail-on-vulnerabilities: true
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/slsa-provenance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ on:
type: string

permissions:
contents: write
id-token: write
actions: read
attestations: write
contents: read

jobs:
# ==========================================================================
Expand All @@ -35,6 +32,11 @@ jobs:
name: Build Package
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
permissions:
contents: read
id-token: write
actions: read
attestations: write
outputs:
hashes: ${{ steps.hashes.outputs.hashes }}
version: ${{ steps.version.outputs.version }}
Expand Down Expand Up @@ -98,7 +100,7 @@ jobs:
slsa:
name: SLSA Level 3
needs: [build]
uses: ByronWilliamsCPA/.github/.github/workflows/python-slsa.yml@main
uses: ByronWilliamsCPA/.github/.github/workflows/python-slsa.yml@e8fc83c98c2971ad1ece71573d28171463e30c16 # main
with:
base64-subjects: ${{ needs.build.outputs.hashes }}
upload-assets: true
Expand Down
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Security

- Hardened `CloudflareJWTValidator`: enforce an allowlist of asymmetric
JWT algorithms (`RS*`/`ES*`/`PS*`) at construction and against the
unverified token header, rejecting `none` and HS* to block
algorithm-confusion attacks.
- JWT decode now explicitly enables `verify_signature`, `verify_exp`,
`verify_nbf`, `verify_iat`, and a `require` set for `exp`/`iat`/
`iss`/`sub`/`aud`. Added 30s leeway for clock skew. Removed the
`verify_exp=False` keyword from `validate_token` /
`validate_token_async`.
- Replaced blanket `except Exception` in JWT validation with specific
PyJWT exception handlers; `get_unverified_claims` now logs a warning
on every call.
- Hardened `GCSClient._sanitize_gcs_path`: reject control characters,
backslashes, and `.`/`..` segments. Reject null bytes in local paths.
- `GCSClient.upload_directory` re-sanitizes the joined GCS path so
unusual filenames cannot reintroduce traversal sequences.
- `GCSClient.delete_directory` rejects empty / whitespace-only prefixes
to prevent accidental bucket-wide wipes.
- Pinned all `ByronWilliamsCPA/.github` reusable-workflow references in
`.github/workflows/*.yml` to a commit SHA instead of `@main`.
- Reduced workflow-level `permissions:` to `contents: read` and granted
elevated rights only to the jobs that need them.
- Added `step-security/harden-runner` with `egress-policy: audit` to
every workflow job that runs inline steps.
- Added `SECURITY-NOTES.md` documenting the unbounded `>=` dependency
ranges and the three highest-risk dependencies (`pyjwt`,
`cryptography`, `google-cloud-storage`).

### Documentation

- Filled in remaining missing docstrings to reach 100% interrogate coverage
Expand Down
Loading
Loading