Comments (9)
IMO, we need actual user stories here.
This bug is likely the wrong place for this but I'll still go ahead:
I'm a Python project maintainer and I want to provide other developers (and CI automation and myself) an easy to understand, single command verification asserting that
- what is being offered as pypi or github artifact download is built from auditable source code using an auditable build system
- compromised maintainer accounts cannot be used to compromise artifacts without leaving an audit trail in source code
Or expressed in another way: I want a low-cost way to reach SLSA level 2+ (https://slsa.dev/spec/v0.1/levels) in my python project
(Ive said it before but I'll repeat just in case: the above functionality does not need to be part of sigstore-python... but it would be nice if the required extension values are exposed somehow for another tool to implement the specific functionality)
from sigstore-python.
That's a helpful categorization scheme, thanks.
IMO, we need actual user stories here. How do we expect actual human beings to use sigstore-python
?
The actual use that I think is most likely is the "purely implicit" workflow: users continue to pip install ...
as they've always done, and pip
and PyPI do the lifting under the hood.
On the PyPI side, that means:
- A package should be configurable to only accept releases with associated signatures/certificates -- releases missing those are rejected (and changes to the package's policy are auditable security events)
- The uploaded release's signature and certificate must:
- Either match one of the associated OIDC connectors (e.g. GitHub), or
- Match an email associated with one of the PyPI accounts authorized for the project
In this way, PyPI automatically provides the "dynamic" security variables you've described.
Then, on the pip
side:
- We should consider a PEP that extends PEP 508, allowing the client to specify a policy marker that enforces certificate and signature presence. In other words: even if a project has authentically disabled its signature requirements for a particular release, a user should be able to reject that release as a matter of policy.
pip
attempts to retrieve the release's associated certificate and signature from PyPI, and verify them in one of two ways:- "Naive" by default, meaning that PyPI's own enforcement is trusted;
- "Comprehensive", requiring that the user's dependency source include the static and dynamic variables you mentioned
In this use case, users default to a higher degree of trust in individual packages (modulo trust in PyPI, which is assumed as part of the model and is addressed separately by ongoing integrity work with TUF) but not certainty about the particulars of verification until they manually opt into explicit checks.
from sigstore-python.
Thinking about this a bit more, one bundle that handles multiple files might be a bit unwieldy/unexpected for folks that expect verification materials to be per-artifact. There's also a lot of complexity about when it's OK to add to this file or when it should be regenerated.
Perhaps instead, to add to my original idea, these should be per-artifact (but still include the hash), and we'd support an --add
or --append
for a situation when we're combining multiple signatures.
So the CLI would be something like:
# For multiple artifacts:
$ python -m sigstore verify --verification-materials verification_materials/* artifacts_to_verify/*
# Same bundle, but works for a single artifact:
$ python -m sigstore verify --verification-materials verification_materials/artifact.ext.sigstore artifacts_to_verify/artifact.ext
from sigstore-python.
This does have some advantages over my suggestion of github specific verify command:
- avoids being service specific (apart from requiring specific extensions being supported)
- allows more complex configuration in case it's needed. As an example (not saying this is a good design for SAN, just making an example):
"config": {
"cert-oidc-issuer": "https://token.actions.githubusercontent.com",
"subject-alternative-name": {
"type": "URI",
"value": "https://github.com/sigstore/sigstore-python/.github/workflows/release.yml@refs/tags/v0.5.1"
},
},
The only complaint I have with formats like these is that in practice as a user I'm still going to produce this file at time of use -- in the github case I would want to fill in at least git tag and git hash at invocation time. That said a simple script (possibly that one actually should be github specific) that produces this json would not be hard to make.
from sigstore-python.
Yeah, I think this is a good idea. Some thoughts:
-
We should version and schematize this! It'll effectively override the CLI's options, so we should produce a reasonable backing model that can be populated both from the CLI and from an input bundle.
-
Re: "additional verification": IMO it makes sense to have it be overridable, with both global and per-artifact settings, if we think that users will regularly need to verify bundles with heterogenous policies. One circumstance that I can imagine is a bundle containing one artifact signed via GitHub Actions and another with an email identity, but is that expected to be common?
-
Re: creating/editing: I think one good initial approach might be to add an
--output-bundle
option tosigstore sign
, generating a "barebones" bundle with just the inputs, certificates, and signatures. In terms of an editing workflow, something interactive on the CLI perhaps?
from sigstore-python.
So I've played with this idea a bit. I think it's useful to recognise that from a verifying users perspective (note that this example is purely WRT verifying GitHub build provenance, not generic sigstore verification) there are three types of variables here:
- dynamic (or per release variables): tag name, sha
- static (or per project variables): org name, project name, workflow path, oidc provider
- artifact defining variables: hash, sig, cert
The last group is just values that verifying user takes as granted: this is the yet untrusted data we have downloaded... but the first two groups are something user definitely wants to define and does not want to let an untrusted downloaded file define.
I understand the usefulness of the "artifact related" data -- it eases the annoying busy work of managing sets of connected files. But I am not sure it makes sense to put them in the same file as the variables that the verifying user wants to define (groups 1 & 2)?
from sigstore-python.
(I mention PEP 508 specifically because we don't want to extend pip
's own extension of 508 in the requirements format, since other packaging tools don't handle those extensions (like --hash
))
from sigstore-python.
There is some parallel/related design work being done here that folks following this thread might be interested in reviewing.
from sigstore-python.
I believe this is now a dupe of #251, since we've committed to using the "sigstore" bundle format.
from sigstore-python.
Related Issues (20)
- lint fails on main HOT 2
- Custom hash for intoto payload HOT 14
- Public API: Expose `ClientTrustConfig`
- Allow setting of redirect uri port HOT 2
- Refactor: replace `requests` with `urllib3`
- Refactor: remove `sigstore.hashes`, merge into `sigstore.models` HOT 1
- Refactor: remove `betterproto` dep HOT 1
- Allow TUF initialization outside of `$HOME`
- Convert in-toto `Statement` to Sigstore DSSE Statement via a single call HOT 4
- [CI] Integration failure: staging instance HOT 1
- Some 0.1 bundles fail to verify HOT 5
- Support for DSSE signatures over binary payloads HOT 19
- Set user-agent in all HTTP requests HOT 2
- Add a switch to test suite to skip staging tests HOT 1
- Circular import on latest commit HOT 3
- Switch to towncrier or similar for CHANGELOG automation
- [CI] Integration failure: staging instance
- Tests: re-enable staging tests in CI
- Tests: make our fixtures/pytest usage less magical
- Expose DSSE verification in the CLI HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sigstore-python.