Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add summaries for the security models of attestations and trusted publishing #17242

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
46 changes: 33 additions & 13 deletions docs/user/attestations/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ title: Security Model and Considerations

# Security model and considerations

Since attestations are a framework for asserting certain facts about a package,
the security model of attestations depends on which types of facts are being
asserted.

The most basic type of attestation (the type enabled by default in
[`pypa/gh-action-pypi-publish`][gh-action-pypi-publish]) asserts that the
package was built by an authorized build process such as a particular CI
provider in a particular code repository. This is primarily designed to protect
against modification of a package *after* it was built such as while it is
stored in a package index.

More advanced types of attestations can assert more things about the package
such as whether it was tampered with *before* it was built, but these
attestations require specialized build processes and are rarer as a result. See
"[What about reproducible builds?]" in the SLSA FAQ.

## General considerations

PyPI's support for attestations is built on top of a combination
Expand All @@ -14,27 +30,27 @@ See below for security considerations for each.

!!! note

TL;DR: An attestation will tell you **who** produced a
PyPI package, but not **whether** you should trust them.
TL;DR: An attestation will tell you **where** a PyPI package came from, but
not **whether** you should trust it.

Like with all signing schemes, it's tempting to treat the *presence* of
an attestation as proof of a package's *trustworthiness*.

However, this is **not** what an attestation (or any kind of signature)
conveys. At its core, a valid signature for some identity conveys a
proof of **authenticity**: if the signature is verifiable against a key,
then we know that the identity that controls that key produced the signature
and is saying *something* about the signed-over data.
However, this is **not** what an attestation (or any kind of signature) conveys.
At its core, a valid signature for an identity on a package conveys a proof of
access to that identity while the package was built.

In other words: a valid signature asserts **authenticity**, but it does **not**
tell the verifying party (e.g., a user installing packages from PyPI) **whether**
they should trust the identity that holds the key.
In other words: a valid signature does **not** tell the verifying party (e.g., a
user installing packages from PyPI) **whether** they should trust the identity
that holds the key or whether they should trust that malicious/vulnerable code
was added before or during the build.

As a concrete example: PyPI serves `sampleproject-4.0.0.tar.gz`, which is
[attested] by [pypa/sampleproject] on GitHub. This is a proof that
`sampleproject-4.0.0.tar.gz` is authentic for that identity, but it does **not**
tell the user **whether** they should trust [pypa/sampleproject]. To determine
trust, the user *must* make a trust decision about [pypa/sampleproject].
`sampleproject-4.0.0.tar.gz` came from that identity unmodified, but it does
**not** tell the user **whether** they should trust [pypa/sampleproject]. To
determine trust, the user *must* make a trust decision about
[pypa/sampleproject].

This trust decision can have a time dimension: a user might decide to trust
[pypa/sampleproject] because it was the first identity seen for the
Expand Down Expand Up @@ -116,6 +132,10 @@ PyPI's attestations feature makes full use of these trust-reduction techniques:
attestations are not considered verified unless they include an inclusion proof
from Rekor, as well as an inclusion proof from Fulcio's CT log.

[gh-action-pypi-publish]: https://github.com/pypa/gh-action-pypi-publish

[What about reproducible builds?]: https://slsa.dev/spec/v1.0/faq#q-what-about-reproducible-builds

[Trusted Publishing]: /trusted-publishers/

[Sigstore's "keyless signing"]: https://docs.sigstore.dev/cosign/signing/overview/
Expand Down
48 changes: 37 additions & 11 deletions docs/user/trusted-publishers/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,43 @@ title: Security Model and Considerations

# Security model and considerations

Trusted publishing is primarily designed to be a more secure alternative than
the long-lived API tokens that have traditionally been used for publishing to
PyPI.

In recent years, theft of credentials such as API tokens has [played a major
role in cyber attacks]. The reason for this is the unfortunate reality that
managing credentials can be unexpectedly difficult. Trusted publishing addresses
this risk by using short-lived tokens instead of long-lived tokens that can
easily get misplaced, leaked in logs, stolen by malware, or any number of other
ways.

However, it is important to still be aware of the kinds of risks that
trusted publishing does not cover. You should think of trusted publishing as one
tool in the toolbelt for securing packages.

## General considerations

While more secure than passwords and long-lived API tokens, OIDC publishing
is not a panacea. In particular:
* Trusted publishing asserts that a package was published to PyPI by someone
or something that had access to an API token that was created within 15
minutes of a valid OIDC authentication flow. It does not assert anything about
the safety of the code or the trustworthiness of the authors.

* Trusted publishing does not address whether the package has been modified
before or after it was built. [Attestations] can address those risks.

* Short-lived API tokens are still sensitive material, and should not be
disclosed (ideally not at all, but certainly not before they expire).
* Short-lived API tokens are sensitive material that must be protected from
getting stolen or leaked.

* OIDC tokens themselves are sensitive material, and should not be disclosed.
OIDC tokens are also short-lived, but an attacker who successfully intercepts
one can mint API tokens against it for as long as it lives.
* OIDC tokens themselves are also sensitive material that must be protected
from getting stolen or leaked. OIDC tokens expire quickly, but an attacker who
successfully intercepts one can use it to generate API tokens until it
expires.

* Configuring a trusted publisher means establishing trust in a particular piece
of external state (such as a GitHub Actions workflow); that state **must not**
be controllable by untrusted parties.
* Configuring a trusted publisher means trusting in the auth system of a
particular OIDC provider (such as GitHub Actions). Trusted publishing relies
on that auth system not being contolled by attackers and not containing
vulnerabilities.

In summary: treat your trusted publishers *as if* they were API tokens. If you
wouldn't let a user or piece of code access your API token, then they shouldn't
Expand Down Expand Up @@ -147,7 +169,7 @@ own security model and considerations.
When using trusted publishing with Google Cloud, you must trust the service account
and _any service which uses it as the default ephemeral identity_.

Specifically, it is not recommened to configure the [default service
Specifically, it is not recommended to configure the [default service
accounts](https://cloud.google.com/iam/docs/service-account-types#default), as
they are provided by default to every service when they are created.

Expand Down Expand Up @@ -258,6 +280,10 @@ own security model and considerations.
access the OIDC token to a bare minimum. This prevents both accidental
and malicious disclosure.

[played a major role in cyber attacks]: https://verizon.com/dbir

[Attestations]: /attestations/

[fundamentally dangerous]: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/

[Use a dedicated environment]: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment
Expand Down
Loading