There's a discussion thread for email attestations here[1]. Those would support local builds.
But to take a step back: if you want attested builds because you think attestation is itself a gold star, then you're working from the wrong priors. Attestations do not imply that a package is secure any more than a hash does; what they are is a cryptographic signature over a set of claims, which allows for authenticated auditing of a project's state over time.
I think PyPI's documentation does a good job of conveying this nuance[2], and that much of the opprobrium of attestations comes from people either not understanding that nuance or imputing conspiracies into it.
[1]: https://github.com/pypi/warehouse/issues/18007
[2]: https://docs.pypi.org/attestations/security-model/#trustwort...
Have you considered that perhaps you are working from the wrong priors?
I believe your prior is that you expect people who read the PyPI page to understand what attestation means. I believe your prior is they will see a notice about "not from a trusted publisher" and not treat it like demerit or warning. I believe your prior is that seeing this message will get people to do more due diligence than they currently do, and that the due diligence will be relevant and appropriate.
Based on my experience with my users, I don't have the same confidence.
I don't understand what "authenticated auditing" means, so why should they?
What project state do people think is important to audit? My code repo is private, hosted on Sourcehut. My build system is private, done locally. The only thing I release is the pre-built binary package. There's very little state to examine, and I can't figure out why anyone cares.
I also have customers who buy a source code license. They have never asked for an audit of the project's state over time.
I read the "Security model and considerations" document. I found it opaque, no doubt because the entire topic is foreign to me, but it doesn't do a good job of explaining. Take the second paragraph:
"The most basic type of attestation (the type enabled by default in pypa/gh-action-pypi-publish) asserts that the project was published by an authorized publisher such as a particular CI provider in a particular code repository.".
I know pypa/gh-action-pypi-publish is some sort of GitHub thing. I don't use GH or third-party CI so that clarification does not help.
It doesn't describe what "authorized publisher" means, other than a generic example of "particular CI provider in a particular code repository". That phrase exists only once in the document. Is it different from a "Trusted Publisher"?
Why are the terms "authorized" and "Trusted" used, instead of something like "affiliated"? If someone is not a trusted publisher or an authorized publisher it's is too easily misinterpreted as "untrusted publisher" or "unauthorized publisher", which seems scary. If someone is not an affiliated publisher, "unaffiliated publisher" sounds less scary. (I'm not saying "affiliated" is the right word, only an example of a roughly appropriate word where the negation of it is not so scary.)
Then later, "It protects against modification of a project after it was built".
I think that's supposed to be "modification of a release after it was built"?
My use of "project" matches the one at https://docs.pypi.org/using-pypi/pypi-basics/ "A project is a collection of releases and files, and information about them. ... A "release" on PyPI is a specific version of a project." I want to modify the project with updated metadata as things change, and to make new releases.
Oh, and I can't find a description of what "build" means in that document. It's used as if everyone expects to know what it means, but a few years ago I learned that modern Python packaging uses "build" different than I do.
When I compile my Python/C extension I "build" it. When I make a wheel I "package" it.
I believe that modern packaging calls the whole thing "build"? Or just the latter step?
Incidentally, "python -m build --sdist" on my project does not work as a replacement for "python setup.py sdist" because my setup.py includes a code generation step to get from a clean repo to the Python/C extension files included in the distribution. I haven't figured out the modern way to handle that. I think it's because of the differences in philosophy of what "build" means, and what actions are allowed during different stages of the distribution process, which is why I think "build" needs a specific definition, just like "project" and "release" have specific definitions.
[flagged]
> what they are is a cryptographic signature over a set of claims, which allows for authenticated auditing of a project's state over time.
Which is great--but does not in any way require that the attestation can only be produced by working through one of a small set of recognized "forges". You could do this just as easily by, for example, letting me upload to my PyPI account a public key (the same as forges like Github do to allow SSH access), and then letting me sign builds that I upload using the corresponding private key. But that kind of workflow is not being supported. Why not?