Skip to content

project: Pin Python dependencies#802

Closed
pdgendt wants to merge 4 commits into
zephyrproject-rtos:mainfrom
pdgendt:ci-pin-deps
Closed

project: Pin Python dependencies#802
pdgendt wants to merge 4 commits into
zephyrproject-rtos:mainfrom
pdgendt:ci-pin-deps

Conversation

@pdgendt
Copy link
Copy Markdown
Collaborator

@pdgendt pdgendt commented Apr 9, 2025

Generate pinned requirement files from pyproject.toml for tox.

Additionally create pinned requirement files for the Github workflows.

@pdgendt pdgendt changed the title project: Pin dependencies for tox project: Pin Python dependencies Apr 9, 2025
@pdgendt pdgendt force-pushed the ci-pin-deps branch 2 times, most recently from 9700c68 to d01c275 Compare April 9, 2025 16:43
Copy link
Copy Markdown
Collaborator

@marc-hb marc-hb left a comment

Choose a reason for hiding this comment

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

first impressions

Comment thread requirements-tox.txt
--hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \
--hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970
# via tox
colorama==0.4.6 \
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can colorama really affect release output? That sounds like serious security design attack surface issues if it can.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not sure what you mean with this comment, colorama is a dependency of tox, this file was generated with only tox as the package to install.

Copy link
Copy Markdown
Collaborator

@marc-hb marc-hb May 8, 2025

Choose a reason for hiding this comment

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

If colorama is a dependency of tox only, then it does not need to be pinned to a specific SHA because tox should NEVER be in a position to affect source code or releases, or have any side effect. It should simply not be part of that attack surface.

Same for this entire requirements-tox.txt file.

Comment thread .github/workflows/package.yml Outdated
Comment thread requirements-build.txt
--hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \
--hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \
--hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \
--hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Any idea why some dependencies need a crazy number of hashes?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

They can have different pre-built binaries for different platforms, and because of that all the hashes need to be added.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Every distribution of a package (specific python version, platform, output format like wheels vs tarball) needs to be added to the list of hashes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isn't there a way to "checksum the list of checksums" and reduce the number?

Checksums are meant to be compared, that's their only purpose. Often enough, they need to be compared by humans but no one is going to compare dozens of checksums visually.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think so, not at least where other tooling (dependabot) can still parse them.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

not at least where other tooling (dependabot) can still parse them.

It does not have to be mutually exclusive. We could have both the list and its sum (if there were such a sum)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not sure what to do here, this is generated using tools I frequently use.

Comment thread requirements-ci.txt Outdated
@@ -0,0 +1,346 @@
# This file was autogenerated by uv via the following command:
# uv pip compile --universal --python-version 3.9 --generate-hashes --group ci -o requirements-ci.txt pyproject.toml
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why do we need the same hashes 4 times? Is there no way to include and re-use?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

What do you mean with the same hashes? For the different requirements files? These are generated with the entire chain of sub-dependencies, not sure if common packages could be extracted.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Also installing all the different requirement files would simply skip already installed packages. The hashes are identical.

Copy link
Copy Markdown
Collaborator

@marc-hb marc-hb Apr 9, 2025

Choose a reason for hiding this comment

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

Thanks for your patience, I'm slowly making sense of all this.

I don't see why we need to pin tox dependencies. I hope tox is not involved in the release process, is it? I mean, I hope there is no way a compromised tox could affect the release output in any way, correct? If it were capable of that, that would be a much bigger problem.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It's one of the medium security issues checked by the OpenSSF tool: https://github.com/zephyrproject-rtos/west/security/code-scanning/26

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Even in the "read-only" case we want to ensure that our simplest CI actions are running the tools we expect them to run. Be it setuptools, build, colorama, tox, ... really any tool or package.

That's just a statement without a rationale.

Apologies, this was not intentional, I guess I am unable to answer your initial question.

As @kartben mentioned, access to CI already opens that "read-only" view. So if that's what you're referring to as "least privilege" then I guess we can't trust Github for that matter.

It's not about "trusting GitHub.com" in general, I agree there is not a lot we can do there. It's about trusting project-specific, automated workflows and controlling their respective access levels.

So are you saying that all GitHub workflows must have the same, full access level no matter what side effects they need? In other words, running pylint or creating a new, official release requires the same level of complete access? Not having something that simple and that effective would be very sad, even more sad when compared to the incredibly fine-grained docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization that no one ever fully understands and to all the incoming CodeQL, pinning and Dependabot complexity.

@marc-hb I appreciate your efforts and value your opinion, but in the context of the PR, I have no clue what to do with this comment. Is this a showstopper? Can you give any suggestions on what would be a better workflow/solution?
I'd like to move forward with this, as I think it is an improvement, both for testing and packaging. It follows best practices. It relies on tooling, yes, but alongside automation that should help maintainers.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

So are you saying that all GitHub workflows must have the same, full access level no matter what side effects they need? In other words, running pylint or creating a new, official release requires the same level of complete access?

Do you know the answer?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So are you saying that all GitHub workflows must have the same, full access level no matter what side effects they need? In other words, running pylint or creating a new, official release requires the same level of complete access?

Do you know the answer?

The closest, I can find, is this: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idpermissions

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks @henrikbrixandersen . So it does look indeed possible to de-privilege test runs and code scanners. Unlike rubber-stamping dozens of checksums, this looks like actual security.

Copy link
Copy Markdown
Collaborator Author

@pdgendt pdgendt Apr 11, 2025

Choose a reason for hiding this comment

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

Yes, this is already applied to all current workflows with:

permissions:
  contents: read

Any other permission is defaulted to none:

If you specify the access for any of these permissions, all of those that are not specified are set to none.

@pdgendt pdgendt force-pushed the ci-pin-deps branch 6 times, most recently from 7376504 to a93bb9d Compare April 10, 2025 14:08
Comment thread requirements-tox.txt
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm confused by the file names: requirements-tox.txt is used in .github/ CI while requirements-ci.txt is used in tox.ini... is this intended?

Automation aside, after this PR how can I simply test the latest version of all dependencies and in my workspace and detect any new incompatibility or regression in them?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, the file names maybe aren't clear, currently:
requirements-tox.txt -> the dependency chain to install tox itself
requirements-ci.txt -> the dependencies to run tox
requirements.txt -> the dependencies of west
requirements-build.txt -> the dependencies to create a package

Automation aside, after this PR how can I simply test the latest version of all dependencies and in my workspace and detect any new incompatibility or regression in them?

I was thinking about making this easier too, I can add a script that would create/update the requirements files (without dependabot).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Renamed the files, now:

requirements.txt -> the dependencies of west
requirements-tox.txt -> the dependencies to run tox
requirements-install-build.txt -> the dependencies to create a package
requirements-install-tox.txt -> the dependencies to install tox

@pdgendt pdgendt force-pushed the ci-pin-deps branch 2 times, most recently from ee89738 to af66ce0 Compare April 11, 2025 07:02
@marc-hb
Copy link
Copy Markdown
Collaborator

marc-hb commented Apr 12, 2025

I have no clue what to do with this comment. Is this a showstopper? Can you give any suggestions on what would be a better workflow/solution?

Let me try to clarify.

  • Least privilege: this is the most important, much more than pinning. All dependencies must have the minimum possible level of access to do their job. Because of configuration complexity, this does not come for free but it is much more important than pinning dependencies and it is also much better security "value" as it reduces attacks surface completely and permanently: no routine reviews of changes needed. Looks like you just checked that?

  • "If it's not tested then it does not work": because GitHub permission levels seem complex, after configuring workflow permissions "someone" should attempt to perform side effects or expose secrets and make sure access is actually denied. This should be done again every time GitHub makes some change to how permissions work (hopefully: rarely).

  • Privileged dependencies that do have a need to perform any side-effect ("write" access) or that have "read" access to any secret token or any other non-public data should absolutely be pinned like this PR does. I never questioned that. I'm afraid I might simplify GitHub access levels but you should get the idea.

  • The number of complexity of privileged dependencies should be reduced to an absolute minimum in the first place.

  • Other, de-privileged dependencies maybe be pinned to some major version for functional reasons but they should IMHO not be micro-managed with checksums etc. because this unnecessarily and considerably increases the workload of routine updates and steals precious time from other, actually effective security tasks - like detailed and very time-consuming reviews of changes in privileged dependencies.

"Security theater" sounds harmless and even fun maybe. But it is actually a dangerous distraction because it steals scarce attention and brain cycles and because routine tasks are mind-numbing.

Speaking of scarce attention and distractions, OS images of runners offer a much larger attack surface. Are those all pinned too and who's going to review updates of entire images like Ubuntu and others? I noticed that GitHub performs "continuous" updates of its default runners.
actions/runner-images#741 (comment)
Not sure these can even be pinned?

@marc-hb
Copy link
Copy Markdown
Collaborator

marc-hb commented Apr 12, 2025

Other, de-privileged dependencies maybe be pinned to some major version for functional reasons but they should IMHO not be micro-managed with checksums etc. because ...

Even if you disagree with this, you'll agree the risk level is much lower. So these could be done later - after learning from experience with privileged dependencies. "Smaller PRs".

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.06%. Comparing base (4638712) to head (5c0ac31).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #802   +/-   ##
=======================================
  Coverage   84.06%   84.06%           
=======================================
  Files          11       11           
  Lines        3345     3345           
=======================================
  Hits         2812     2812           
  Misses        533      533           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@carlescufi
Copy link
Copy Markdown
Member

carlescufi commented Apr 30, 2025

@marc-hb @henrikbrixandersen @kartben is anything here not ready for merging? It'd be great to move this forward.

@marc-hb in particular, I am not sure by reading your comments whether you are OK with this change or not.

@kartben kartben requested a review from carlescufi May 8, 2025 07:34
Copy link
Copy Markdown
Collaborator

@marc-hb marc-hb left a comment

Choose a reason for hiding this comment

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

@marc-hb in particular, I am not sure by reading your comments whether you are OK with this change or not.

I'm OK with only "half" of it. Pinning requirements.txt makes sense, pinning requirements-tox.txt does not.

I'm very concerned about the perception that pinning is the latest security silver bullet. For years we were told to "update, update and update" to stay secure. Now it's the opposite. Which is it? Neither, it's complicated. And it can never be that "cheap".

EDIT: Pinning is only one tool in the box. It's not a hammer that sees everything as a nail.

Comment thread requirements-tox.txt
--hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \
--hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970
# via tox
colorama==0.4.6 \
Copy link
Copy Markdown
Collaborator

@marc-hb marc-hb May 8, 2025

Choose a reason for hiding this comment

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

If colorama is a dependency of tox only, then it does not need to be pinned to a specific SHA because tox should NEVER be in a position to affect source code or releases, or have any side effect. It should simply not be part of that attack surface.

Same for this entire requirements-tox.txt file.

@pdgendt
Copy link
Copy Markdown
Collaborator Author

pdgendt commented May 9, 2025

I'm OK with only "half" of it. Pinning requirements.txt makes sense, pinning requirements-tox.txt does not.

I have to disagree here, pinning requirements-tox.txt is no different than pinning requirements.txt IMO. It both only has effect in CI. If anything, pinning requirements-tox.txt makes sure, that if a user tests locally and succeeds, it will do too in CI.
We should not burden users that are fixing bugs or introducing features in west itself, with fixing dependency issues. Those would need separate attention.

I'm very concerned about the perception that pinning is the latest security silver bullet. For years we were told to "update, update and update" to stay secure. Now it's the opposite. Which is it? Neither, it's complicated. And it can never be that "cheap".

EDIT: Pinning is only one tool in the box. It's not a hammer that sees everything as a nail.

It isn't a silver bullet, this has never been stated. It is an improvement as it pins the "current" state of what is thought to be an accepted version of the tool. I would argue we still do "update, update, update", but I prefer to offload that to tooling, and in this case dependabot.
We can better track what dependencies would cause issues as they are treated outside of the other changes.

@pdgendt
Copy link
Copy Markdown
Collaborator Author

pdgendt commented May 9, 2025

As a side-note: west has been on Homebrew for years, a super popular package manager, primarily for macOS. It is super automated and pins EVERYTHING. It updates the dependencies in their west formula.

@marc-hb
Copy link
Copy Markdown
Collaborator

marc-hb commented May 9, 2025

I have to disagree here, pinning requirements-tox.txt is no different than pinning requirements.txt IMO.

I tried to phrase the difference in 2 or 3 different ways. Maybe none were well written, but your reply does not even try to mention any of them. I give up!

@pdgendt
Copy link
Copy Markdown
Collaborator Author

pdgendt commented May 9, 2025

I tried to phrase the difference in 2 or 3 different ways. Maybe none were well written, but your reply does not even try to mention any of them. I give up!

I'm sorry, I may have difficulties explaining this, but requirements.txt is only relevant during CI, as is requirements-tox.txt. During installation of west itself, it isn't used.

@marc-hb
Copy link
Copy Markdown
Collaborator

marc-hb commented May 9, 2025

I'm sorry, I may have difficulties explaining this, but requirements.txt is only relevant during CI, as is requirements-tox.txt. During installation of west itself, it isn't used.

I think that is still besides my main point.

I would argue we still do "update, update, update", but I prefer to offload that to tooling, and in this case dependabot.

dependabot is nice but it does absolutely nothing to help with actual security audits. Except giving a bit of a false sense maybe.

@marc-hb
Copy link
Copy Markdown
Collaborator

marc-hb commented May 9, 2025

It [homebrew] is super automated and pins EVERYTHING.

Off-topic but since this thread is doomed anyway...

I've used homebrew on my mac since forever. Once, I tried to make a one-line change in one of the packages. That's the "essential" litmus test. I tried for hours and gave up. Probably unrelated to pinning but really not impressed.

pdgendt added 4 commits May 10, 2025 15:22
Generate pinned requirement files from pyproject.toml for tox.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
Create pinned requirement files for both build/setuptools and tox and
use these in the Github workflows.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
Let dependabot check for python pinned dependency updates on a monthly
schedule.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
The helper script uses the uv command to create universal requirement
files.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
@carlescufi
Copy link
Copy Markdown
Member

@marc-hb this has been now open for a while. My impression when reading your comments is that you disagree with pinning everything as a rule, but are not strictly opposed to using pinning as tool.

So here's my question: if @pdgendt only pinned requirements.txt but not requirements-tox.txt you'd be OK with this proposed change? If that's the case then I suggest @pdgendt makes a call on whether to pin only one or both. Also, if you are strictly opposed to pinning both then please NACK the PR. Thanks!

@pdgendt
Copy link
Copy Markdown
Collaborator Author

pdgendt commented May 10, 2025

I'm not in favour of doing only one, but not the other. I'll close this and not include it in v1.4, maybe try to come up with something for v2.0.
Not a hill I want to die on.

@pdgendt pdgendt closed this May 10, 2025
@pdgendt pdgendt deleted the ci-pin-deps branch May 12, 2025 10:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants