From 3b5b4c3c97d4b856e2a1f4b55ff08bbd7adf21fa Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 04:56:11 -0700 Subject: [PATCH 01/16] Harden Github Actions --- .github/workflows/ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be7cfb3..efc5d58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,9 @@ name: ci on: [push, pull_request] +permissions: + contents: read + jobs: test: @@ -9,15 +12,16 @@ jobs: strategy: matrix: - python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10' ] + python-version: [ '3.10', '3.11' ] steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@28f2168f4d98ee0445e3c6321f6e6616c83dd5ec with: python-version: ${{ matrix.python-version }} + cache: 'pip' - name: Install requirements run: | python -m pip install -r requirements.txt From 5bf2c3094142d7c9b00892ee35302848cd2e8f6c Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:03:35 -0700 Subject: [PATCH 02/16] Harden workflow to be supply chain safe and remove old patterns --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efc5d58..0d116f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,12 +25,12 @@ jobs: - name: Install requirements run: | python -m pip install -r requirements.txt - python setup.py install + pip install . - name: Check source files if: matrix.python-version == '3.10' run: | - python -m pip install pytest-pycodestyle - python -m pip install pytest-flakes + python -m pip install pytest-pycodestyle --require-hashes --hash=sha256:dd0060039e12a59b521da8e57e17133c965566dd8d17631e589e7545238829ac + python -m pip install pytest-flakes --require-hashes --hash=sha256:953134e97215ae31f6879fbd7368c18d43f709dc2fab5b7777db2bb2bac3a924 py.test --pycodestyle ftw py.test --flakes ftw - name: Run tests From c99479a28c46448604c0dcf9c19585d38d9e1060 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:08:11 -0700 Subject: [PATCH 03/16] Pin dependencies --- requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index b46f7dc..bb8e598 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -Brotli==1.0.9 -IPy==1.01 -PyYAML==6.0 -pytest==6.2.5 -python-dateutil==2.8.2 +Brotli==1.2.0 --hash=sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a +IPy==1.01 --hash=sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a +PyYAML==6.0.3 --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f +pytest==9.0.2 --hash=sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11 +python-dateutil==2.9.0 --hash=sha256:cbf2f1da5e6083ac2fbfd4da39a25f34312230110440f424a14c7558bb85d82e From 7fec59e38a059ad55d029c748dbac42cfc185420 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:12:28 -0700 Subject: [PATCH 04/16] Harden publish workflow --- .github/workflows/publish.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 87ce4bb..7e146f8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,21 +4,23 @@ on: release: types: [created] + + jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@28f2168f4d98ee0445e3c6321f6e6616c83dd5ec with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine + python -m pip install --require-hashes -r requirements-build.txt - name: Build and publish env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} From aa3a209d2b3100458ad58c0bc6785ab8011d385a Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:12:46 -0700 Subject: [PATCH 05/16] Update publish.yml --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7e146f8..c590827 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Python uses: actions/setup-python@28f2168f4d98ee0445e3c6321f6e6616c83dd5ec with: - python-version: '3.x' + python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip From 2a05fb1e5b776996ac455bb24465acb1607b6cb4 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:13:18 -0700 Subject: [PATCH 06/16] Replace old commands --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c590827..c28439f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,5 +26,5 @@ jobs: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - python setup.py sdist bdist_wheel + python -m build twine upload dist/* From bd3b556b50e543279c0bccf2522508f257d2d3f8 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:16:55 -0700 Subject: [PATCH 07/16] Create requirements-build.txt --- requirements-build.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 requirements-build.txt diff --git a/requirements-build.txt b/requirements-build.txt new file mode 100644 index 0000000..f73c15d --- /dev/null +++ b/requirements-build.txt @@ -0,0 +1,3 @@ +twine==6.2.0 --hash sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8 +wheel==0.46.3 --hash sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +setuptools=82.0.1 --hash sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 From e16d80b3c02592e046774b5f5fea0dda9e83421c Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:18:17 -0700 Subject: [PATCH 08/16] Add forgetten --require-hashes --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d116f8..532e6db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: cache: 'pip' - name: Install requirements run: | - python -m pip install -r requirements.txt + python -m pip install --require-hashes -r requirements.txt pip install . - name: Check source files if: matrix.python-version == '3.10' From d7c4da13b25f959987eb5a5930dc31a1486423e6 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 05:20:54 -0700 Subject: [PATCH 09/16] Final supply chain hardening for ftw --- .github/workflows/publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c28439f..3e07f9a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,7 +4,8 @@ on: release: types: [created] - +permissions: + contents: read jobs: deploy: From 7d131a88485775e980ac5887c20f310a23cbdd6e Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 11:27:41 -0700 Subject: [PATCH 10/16] Update setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 59309d0..eab61f3 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ "Framework :: Pytest", ], packages=["ftw"], - python_requires=">=3.6", + python_requires=">=3.10", use_scm_version=True, setup_requires=['setuptools_scm'], install_requires=[ From 94f70e4976971ff587cdfa1be3e902410f3d7b45 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 11:29:44 -0700 Subject: [PATCH 11/16] Add --no-deps for pip install . Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 532e6db..146a85f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - name: Install requirements run: | python -m pip install --require-hashes -r requirements.txt - pip install . + pip install . --no-deps - name: Check source files if: matrix.python-version == '3.10' run: | From 25e929cb34a716709622c40e61fbbb06751f065b Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 11:30:38 -0700 Subject: [PATCH 12/16] Pin the version Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 146a85f..1ae02c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,8 +29,8 @@ jobs: - name: Check source files if: matrix.python-version == '3.10' run: | - python -m pip install pytest-pycodestyle --require-hashes --hash=sha256:dd0060039e12a59b521da8e57e17133c965566dd8d17631e589e7545238829ac - python -m pip install pytest-flakes --require-hashes --hash=sha256:953134e97215ae31f6879fbd7368c18d43f709dc2fab5b7777db2bb2bac3a924 + python -m pip install pytest-pycodestyle==2.3.1 --require-hashes --hash=sha256:dd0060039e12a59b521da8e57e17133c965566dd8d17631e589e7545238829ac + python -m pip install pytest-flakes==4.0.5 --require-hashes --hash=sha256:953134e97215ae31f6879fbd7368c18d43f709dc2fab5b7777db2bb2bac3a924 py.test --pycodestyle ftw py.test --flakes ftw - name: Run tests From 3a6322de218adeecfc0fa44819d4e48df54cee08 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 11:35:59 -0700 Subject: [PATCH 13/16] Add build --- requirements-build.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements-build.txt b/requirements-build.txt index f73c15d..0bd8158 100644 --- a/requirements-build.txt +++ b/requirements-build.txt @@ -1,3 +1,4 @@ twine==6.2.0 --hash sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8 wheel==0.46.3 --hash sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 -setuptools=82.0.1 --hash sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 +setuptools==82.0.1 --hash sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 +build==1.4.0 --hash=sha512:4c24accb4c1ad3352c5a528841b9950869ddfae88ec83dbc05bc06a28035751c9d54e209eabecc171f72905f84f38e505af9d866d9a0083a57a800ed4d85a878 From a6d0cf828a01ac8bbaff9da57e151727eb095289 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 11:40:52 -0700 Subject: [PATCH 14/16] Fix yaml identation --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3e07f9a..8ea8572 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Python uses: actions/setup-python@28f2168f4d98ee0445e3c6321f6e6616c83dd5ec with: - python-version: '3.11' + python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip From bb7d86bc1a094046c99562e3ed41b516a17251e1 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 11:46:35 -0700 Subject: [PATCH 15/16] Update pinning to use SHA512 Because of quantum future attacks will reduce SHA256 collision to 64 bit via Grover but SHA512 will be reduced to 128 bit and it still strong --- requirements-build.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-build.txt b/requirements-build.txt index 0bd8158..a643f96 100644 --- a/requirements-build.txt +++ b/requirements-build.txt @@ -1,4 +1,4 @@ -twine==6.2.0 --hash sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8 -wheel==0.46.3 --hash sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 -setuptools==82.0.1 --hash sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 +twine==6.2.0 --hash=sha512:e0b7826a32625654ffe1f262c5b022c8026aea3f642a2a0d58bad5e0215c115e085ee7345d1953ca50fcc661f95f3943d036ef7974a0401f803a2b5a2951a796 +wheel==0.46.3 --hash=sha512:2ca4b84603344b8a29a2bd2850188751666a9f840c49869da644bd63eebfab097df32dd7086b85e6e93a7a9e161f6df3ece9fe1a42e622b6a8834ef444fd378b +setuptools==82.0.1 --hash=sha512:24132d3af7054ea6e75e3bc4fd90bbb845dd146a0f38d7411c3e7c183fe1c08e210c06c3f1302a41d639eb15467dc6312d1f22ba49c438296058e2dfd2ca9d8f build==1.4.0 --hash=sha512:4c24accb4c1ad3352c5a528841b9950869ddfae88ec83dbc05bc06a28035751c9d54e209eabecc171f72905f84f38e505af9d866d9a0083a57a800ed4d85a878 From 45d25cbd9674304b34b4df5d3f86a94d63475cc4 Mon Sep 17 00:00:00 2001 From: RelunSec Date: Tue, 24 Mar 2026 11:51:21 -0700 Subject: [PATCH 16/16] Update pinning to use SHA512 Because of quantum future attacks will reduce SHA256 collision to 64 bit via Grover but SHA512 will be reduced to 128 bit and it still strong --- requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index bb8e598..be31dc0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -Brotli==1.2.0 --hash=sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a -IPy==1.01 --hash=sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a -PyYAML==6.0.3 --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f -pytest==9.0.2 --hash=sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11 -python-dateutil==2.9.0 --hash=sha256:cbf2f1da5e6083ac2fbfd4da39a25f34312230110440f424a14c7558bb85d82e +Brotli==1.2.0 --hash=sha512:e197edc1fc9097a77d6ba0fa48cf8b0f23fe7ce0b89d941bddc71c4bb35184823fdbb12d73e086a4c1b29913052db774a1a6bc8da9697bd9c4bbf8fdf2b4a322 +IPy==1.01 --hash=sha512:f0983254523025a1819d543877d9651fb6a9e39dabd3b043488495f681b02e43b544a0121658a0430a418a1c39b360a59db1699af87a75a16a2bdc29fcb2b74c +PyYAML==6.0.3 --hash=sha512:ffcb8aa66e6a09a70c08025006744d7a0948cdbfd5cd3b78bc50deb6416afca7d1dbcccef58804d2328d39a264b74cc15e9a08dd8f7305725b0a48a3585e6db4 +pytest==9.0.2 --hash=sha512:fabfaf0ed5c328b9f596a90f4b11f673b8bd25f0cdd80c1d3a4858ac699c2c2059a57d9eefd0cb10d3195bca341bb081c03045e1b30fcc799c302d069ec2b030 +python-dateutil==2.9.0 --hash=sha512:68c13dcfeef8f2b9e06fe6bbbd5f59367069f76718e9ffedfcfcf632c5ddb6bbd85bb94bddb1439f9793dc56066aa05b7ff4cc29e41dec6a6b0a5014c8f71334