From 321a2e32c179a67f180173a40f50d401c540523a Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Wed, 3 Jul 2024 11:00:08 -0500 Subject: [PATCH 1/8] Initial transformation from GDoc into Markdown Signed-off-by: Seth Michael Larson --- docs/imgs/trusted-publishers-flow.png | Bin 0 -> 45827 bytes ...publishers-for-all-package-repositories.md | 122 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 docs/imgs/trusted-publishers-flow.png create mode 100644 docs/trusted-publishers-for-all-package-repositories.md diff --git a/docs/imgs/trusted-publishers-flow.png b/docs/imgs/trusted-publishers-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..4c2674a2c3e34588d1ad7c9b9610fe0ba038c898 GIT binary patch literal 45827 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 Date: Fri, 5 Jul 2024 09:10:02 -0500 Subject: [PATCH 2/8] More backticks Co-authored-by: Dustin Ingram Signed-off-by: Seth Michael Larson --- .../trusted-publishers-for-all-package-repositories.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/trusted-publishers-for-all-package-repositories.md b/docs/trusted-publishers-for-all-package-repositories.md index ff47bf9..31a2fc0 100644 --- a/docs/trusted-publishers-for-all-package-repositories.md +++ b/docs/trusted-publishers-for-all-package-repositories.md @@ -38,11 +38,11 @@ A high-level overview of how PyPI verifies the OIDC token against a pre-configur * Using the JWKs, [verify the JWT signature and claims](https://www.criipto.com/blog/jwt-validation-guide) (claims like `nbf`, `exp`, `jti`, etc). * Verify that the audience claim (`aud`) is equal to a service-specific value (i.e. `pypi` and `testpypi`). This requires that the IdP supports configuring the audience of the emitted OIDC token. * Using the claims, check the values against the pre-configured trust policy for the Trusted Publisher. For example, a GitHub workflow would check the following claims: - * `sub` (Subject) is of the form “example-owner/example-repo:.*” - * repository is “example-repo” - * repository_owner is “example-owner” - * repository_owner_id is “12345” - * job_workflow_ref is “example-owner/example-repo/.github/workflows/publish.yml@abcdef” + * `sub` (Subject) is of the form `example-owner/example-repo:.*` + * `repository` is `example-repo` + * `repository_owner` is `example-owner` + * `repository_owner_id` is `12345` + * `job_workflow_ref` is `example-owner/example-repo/.github/workflows/publish.yml@abcdef` Once this is complete, the package repository can authorize publications by delegating to a repository-managed token. From f76d8128b3d8a421d535bbdf61f2edf9650bd581 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Fri, 5 Jul 2024 09:10:48 -0500 Subject: [PATCH 3/8] Apply suggestions from code review Co-authored-by: William Woodruff Signed-off-by: Seth Michael Larson --- docs/trusted-publishers-for-all-package-repositories.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/trusted-publishers-for-all-package-repositories.md b/docs/trusted-publishers-for-all-package-repositories.md index 31a2fc0..6511c90 100644 --- a/docs/trusted-publishers-for-all-package-repositories.md +++ b/docs/trusted-publishers-for-all-package-repositories.md @@ -73,9 +73,9 @@ For packaging ecosystems where there are multiple artifacts per release or multi ### Identity Providers and Claims -OIDC tokens are implemented as [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) (JWTs) and come with a set of claims, which are a mix of standard OIDC claims and provider-specific claims +OIDC tokens are implemented as [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) (JWTs) and come with a set of claims, which are a mix of standard OIDC claims and provider-specific claims. -IdPs must support customizing the audience claim (`aud`) and Trusted Publisher implementations must only accept OIDC tokens with a service-specific audience claim (ie “pypi”). +IdPs must support customizing the audience claim (`aud`) and Trusted Publisher implementations must only accept OIDC tokens with a service-specific audience claim (e.g. “pypi”). IdPs all have their own claim sets for their OIDC tokens. Creating a Trusted Publisher for a provider requires knowledge about the provider’s internal implementation and behavior when determining which subsets constitute a sufficiently trusted set to provide to users. Trusted Publisher implementations must not rely exclusively on a generic set of claims (i.e. only `sub` + `iss` + `aud`) as these do not constitute a sufficiently trusted set for many IdPs. @@ -89,7 +89,7 @@ IdPs may allow customizing other claims, like validity time of the OIDC token. T Package repositories should not use OIDC tokens for directly authenticating with package publishing APIs. Instead, package repositories should exchange the OIDC token for a repository-controlled API token that is used for authenticating with publishing APIs. Below are a list of reasons for the exchange: -* If the package repository already supports token-based authentication, OIDC tokens won’t plug into the existing authentication and authorization implementations. This will lead to needing to reimplement them for OIDC tokens, effectively having two token types and potentially leading to more bugs. +* If the package repository already supports token-based authentication, OIDC tokens won’t plug into the pre-existing existing authentication and authorization implementations. This will lead to needing to reimplement them for OIDC tokens, effectively having two token types and potentially leading to more bugs. * JWTs can contain any information that the provider decides to include, like private or personally identifiable information (i.e. names and email addresses). Using a separate token avoids holding on to this information for extended periods of time to reduce potential exposure or persistence. * Identity Providers can change the expiration and other policies around their tokens without notice. Creating your own temporary token makes the repository resilient to these changes. * Repository-managed tokens are more pluggable into existing tooling for publishing packages. From 7deb306d99e111a7f01f04c676345dfbe14bc763 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Mon, 8 Jul 2024 07:08:57 -0500 Subject: [PATCH 4/8] Use "OIDC ID token" uniformly Co-authored-by: Fredrik Skogman Signed-off-by: Seth Michael Larson --- docs/trusted-publishers-for-all-package-repositories.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/trusted-publishers-for-all-package-repositories.md b/docs/trusted-publishers-for-all-package-repositories.md index 6511c90..6c710ec 100644 --- a/docs/trusted-publishers-for-all-package-repositories.md +++ b/docs/trusted-publishers-for-all-package-repositories.md @@ -24,7 +24,7 @@ Package repositories which don’t host separate artifacts (such as pkg.go.dev) Trusted Publishers allow a package repository like the Python Package Index (PyPI) to authenticate an identity from an Identity Provider (IdP) like GitHub Actions or GitLab Pipelines, and using a technology called OpenID Connect (OIDC). -Trusted Publishers works by requiring users to pre-configure a trust policy on the receiving package repository which will be later used as part of authenticating a publish request. When new artifacts are being published to the registry, the OIDC token (implemented as a JWT token) will be verified by [checking the JWT claims and signature against the IdP’s JSON Web Keyset (JWK)](https://www.criipto.com/blog/jwt-validation-guide) and checked to ensure the OIDC token’s issuer and claims match the [pre-configured trust policy for the package](https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions). +Trusted Publishers works by requiring users to pre-configure a trust policy on the receiving package repository which will be later used as part of authenticating a publish request. When new artifacts are being published to the registry, the OIDC ID token (implemented as a JWT token) will be verified by [checking the JWT claims and signature against the IdP’s JSON Web Keyset (JWK)](https://www.criipto.com/blog/jwt-validation-guide) and checked to ensure the OIDC token’s issuer and claims match the [pre-configured trust policy for the package](https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions). The trust policy doesn’t necessarily need to have a _direct_ link to a package, for example some package repositories may want to assign trust policies to package namespaces, the trust policy determines whether a given package can be published by a given workload identity. @@ -73,7 +73,7 @@ For packaging ecosystems where there are multiple artifacts per release or multi ### Identity Providers and Claims -OIDC tokens are implemented as [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) (JWTs) and come with a set of claims, which are a mix of standard OIDC claims and provider-specific claims. +OIDC ID tokens are implemented as [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) (JWTs) and come with a set of claims, which are a mix of standard OIDC claims and provider-specific claims. IdPs must support customizing the audience claim (`aud`) and Trusted Publisher implementations must only accept OIDC tokens with a service-specific audience claim (e.g. “pypi”). @@ -83,11 +83,11 @@ IdPs vary their sets of claims depending on the situation the OIDC token is used Trusted Publisher implementations may utilize the `jti` claim to prevent replaying of OIDC tokens by rejecting tokens which have been previously used. -IdPs may allow customizing other claims, like validity time of the OIDC token. Trusted Publisher implementations may decide to add further requirements to IdPs and their OIDC tokens (such as maximum validity time) to enforce more secure OIDC token handling where this is possible with the IdP. +IdPs may allow customizing other claims, like validity time of the OIDC ID token. Trusted Publisher implementations may decide to add further requirements to IdPs and their OIDC tokens (such as maximum validity time) to enforce more secure OIDC ID token handling where this is possible with the IdP. ### OIDC tokens and repository-controlled tokens -Package repositories should not use OIDC tokens for directly authenticating with package publishing APIs. Instead, package repositories should exchange the OIDC token for a repository-controlled API token that is used for authenticating with publishing APIs. Below are a list of reasons for the exchange: +Package repositories should not use OIDC ID tokens for directly authenticating with package publishing APIs. Instead, package repositories should exchange the OIDC token for a repository-controlled API token that is used for authenticating with publishing APIs. Below are a list of reasons for the exchange: * If the package repository already supports token-based authentication, OIDC tokens won’t plug into the pre-existing existing authentication and authorization implementations. This will lead to needing to reimplement them for OIDC tokens, effectively having two token types and potentially leading to more bugs. * JWTs can contain any information that the provider decides to include, like private or personally identifiable information (i.e. names and email addresses). Using a separate token avoids holding on to this information for extended periods of time to reduce potential exposure or persistence. From 2a80793eb96d7b5fbd8e2ed81f1f305cffdca12d Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Mon, 8 Jul 2024 08:54:50 -0500 Subject: [PATCH 5/8] Move OIDC ID token fixes, improve the introducton scoping Signed-off-by: Seth Michael Larson --- ...publishers-for-all-package-repositories.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/trusted-publishers-for-all-package-repositories.md b/docs/trusted-publishers-for-all-package-repositories.md index 6c710ec..295dfd6 100644 --- a/docs/trusted-publishers-for-all-package-repositories.md +++ b/docs/trusted-publishers-for-all-package-repositories.md @@ -1,6 +1,6 @@ # Trusted Publishers for All Package Repositories -Trusted Publishers is a new authentication mechanism using the OpenID Connect standard (OIDC) to exchange OIDC tokens for short-lived and tightly scoped API tokens for authenticating with package repository publishing APIs. Using short-lived API tokens removes the need to share long-lived and potentially highly privileged API tokens with external systems when publishing software. This capability is primarily beneficial for hosted, automated publishing workflows. +Trusted Publishers is a new authentication method that builds on the existing OpenID Connect standard (OIDC) for user infrastructure publishing to public package repositories (e.g. CI publishing to PyPI, as opposed to maintainers publishing from their system or Homebrew's centralized builds). Authentication is performed by exchanging OIDC tokens for short-lived and tightly scoped API tokens for authenticating with package repository publishing APIs. Using short-lived API tokens removes the need to share long-lived and potentially highly privileged API tokens with external systems when publishing software. ## Why Trusted Publishers? @@ -24,19 +24,19 @@ Package repositories which don’t host separate artifacts (such as pkg.go.dev) Trusted Publishers allow a package repository like the Python Package Index (PyPI) to authenticate an identity from an Identity Provider (IdP) like GitHub Actions or GitLab Pipelines, and using a technology called OpenID Connect (OIDC). -Trusted Publishers works by requiring users to pre-configure a trust policy on the receiving package repository which will be later used as part of authenticating a publish request. When new artifacts are being published to the registry, the OIDC ID token (implemented as a JWT token) will be verified by [checking the JWT claims and signature against the IdP’s JSON Web Keyset (JWK)](https://www.criipto.com/blog/jwt-validation-guide) and checked to ensure the OIDC token’s issuer and claims match the [pre-configured trust policy for the package](https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions). +Trusted Publishers works by requiring users to pre-configure a trust policy on the receiving package repository which will be later used as part of authenticating a publish request. When new artifacts are being published to the registry, the OIDC ID token (implemented as a JWT token) will be verified by [checking the JWT claims and signature against the IdP’s JSON Web Keyset (JWK)](https://www.criipto.com/blog/jwt-validation-guide) and checked to ensure the OIDC ID token’s issuer and claims match the [pre-configured trust policy for the package](https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions). The trust policy doesn’t necessarily need to have a _direct_ link to a package, for example some package repositories may want to assign trust policies to package namespaces, the trust policy determines whether a given package can be published by a given workload identity. The JWKs are discovered using the [well-known OpenID Connect Discovery URL](https://swagger.io/docs/specification/authentication/openid-connect-discovery/) which is based on the JWT’s issuer (“iss”) claim. For example, GitHub’s “iss” claim is “[https://token.actions.githubusercontent.com](https://token.actions.githubusercontent.com)” and thus it’s well-known OpenID Connect Discovery URL is “[https://token.actions.githubusercontent.com/.well-known/openid-configuration](https://token.actions.githubusercontent.com/.well-known/openid-configuration)”. -A high-level overview of how PyPI verifies the OIDC token against a pre-configured policy is below: +A high-level overview of how PyPI verifies the OIDC ID token against a pre-configured policy is below: * Parse the JWT without verifying the claims or signature to extract the issuer claim (`iss`). Be sure that this parsed JWT is discarded and that the JWT isn’t marked as verified by the service at this stage. * Checking this issuer against the supported list of OIDC identity providers for the package repository, select the implementation for verifying the token (e.g “GitHub” or “GitLab”). * Fetch the OpenID Connect discovery URL and JWKs for the issuer. * Using the JWKs, [verify the JWT signature and claims](https://www.criipto.com/blog/jwt-validation-guide) (claims like `nbf`, `exp`, `jti`, etc). -* Verify that the audience claim (`aud`) is equal to a service-specific value (i.e. `pypi` and `testpypi`). This requires that the IdP supports configuring the audience of the emitted OIDC token. +* Verify that the audience claim (`aud`) is equal to a service-specific value (i.e. `pypi` and `testpypi`). This requires that the IdP supports configuring the audience of the emitted OIDC ID token. * Using the claims, check the values against the pre-configured trust policy for the Trusted Publisher. For example, a GitHub workflow would check the following claims: * `sub` (Subject) is of the form `example-owner/example-repo:.*` * `repository` is `example-repo` @@ -46,11 +46,11 @@ A high-level overview of how PyPI verifies the OIDC token against a pre-configur Once this is complete, the package repository can authorize publications by delegating to a repository-managed token. -This document recommends exchanging the OIDC token for a separate repository-managed token, but this step is not required and the OIDC token may be used directly for authenticating the publish request. See the “Resulting Design Decisions” section for further reasoning behind this recommendation. +This document recommends exchanging the OIDC ID token for a separate repository-managed token, but this step is not required and the OIDC ID token may be used directly for authenticating the publish request. See the “Resulting Design Decisions” section for further reasoning behind this recommendation. ![Diagram of Trusted Publishers flow](./imgs/trusted-publishers-flow.png) -Every unique IdP that a package repository wishes to support will require its own implementation as the claims on each OIDC token vary depending on the provider (beyond the standard issuer, expiration, and audience claims of JWT tokens). The sets of claims chosen to check must constitute sufficiently trusted metadata to be checked against the trust policy on packages. Trusted Publisher implementations must not rely exclusively on a generic set of claims (i.e. only `sub` + `iss` + `aud`) as these do not constitute a sufficiently trusted set for many IdPs. +Every unique IdP that a package repository wishes to support will require its own implementation as the claims on each OIDC ID token vary depending on the provider (beyond the standard issuer, expiration, and audience claims of JWT tokens). The sets of claims chosen to check must constitute sufficiently trusted metadata to be checked against the trust policy on packages. Trusted Publisher implementations must not rely exclusively on a generic set of claims (i.e. only `sub` + `iss` + `aud`) as these do not constitute a sufficiently trusted set for many IdPs. ## Resulting Design Decisions @@ -58,7 +58,7 @@ Every unique IdP that a package repository wishes to support will require its ow Trusted Publishers represent a more secure authentication model than long-lived API tokens, however Trusted Publishers are not a panacea. The following security model must be followed by users to maintain a secure configuration: -* Short-lived tokens like OIDC tokens or repository-managed API tokens are still sensitive material and should not be disclosed. Either of these tokens being disclosed means they can be used by an attacker to publish malicious packages to the repository until they expire. +* Short-lived tokens like OIDC ID tokens or repository-managed API tokens are still sensitive material and should not be disclosed. Either of these tokens being disclosed means they can be used by an attacker to publish malicious packages to the repository until they expire. * Configuring a Trusted Publisher is a means of establishing trust in some external state. That external state (both the IdP itself and the resources managed by the IdP) must not be controllable by untrusted parties. It’s recommended to document this security model alongside provider-specific guides on how to adopt Trusted Publishers for the package repository. @@ -75,21 +75,21 @@ For packaging ecosystems where there are multiple artifacts per release or multi OIDC ID tokens are implemented as [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) (JWTs) and come with a set of claims, which are a mix of standard OIDC claims and provider-specific claims. -IdPs must support customizing the audience claim (`aud`) and Trusted Publisher implementations must only accept OIDC tokens with a service-specific audience claim (e.g. “pypi”). +IdPs must support customizing the audience claim (`aud`) and Trusted Publisher implementations must only accept OIDC ID tokens with a service-specific audience claim (e.g. “pypi”). -IdPs all have their own claim sets for their OIDC tokens. Creating a Trusted Publisher for a provider requires knowledge about the provider’s internal implementation and behavior when determining which subsets constitute a sufficiently trusted set to provide to users. Trusted Publisher implementations must not rely exclusively on a generic set of claims (i.e. only `sub` + `iss` + `aud`) as these do not constitute a sufficiently trusted set for many IdPs. +IdPs all have their own claim sets for their OIDC ID tokens. Creating a Trusted Publisher for a provider requires knowledge about the provider’s internal implementation and behavior when determining which subsets constitute a sufficiently trusted set to provide to users. Trusted Publisher implementations must not rely exclusively on a generic set of claims (i.e. only `sub` + `iss` + `aud`) as these do not constitute a sufficiently trusted set for many IdPs. -IdPs vary their sets of claims depending on the situation the OIDC token is used in, for example GitHub has special claims for reusable workflows or for different workflow trigger types. Providers have also been known to change their claims with varying amounts of fore-warning or documentation about the changes. +IdPs vary their sets of claims depending on the situation the OIDC ID token is used in, for example GitHub has special claims for reusable workflows or for different workflow trigger types. Providers have also been known to change their claims with varying amounts of fore-warning or documentation about the changes. -Trusted Publisher implementations may utilize the `jti` claim to prevent replaying of OIDC tokens by rejecting tokens which have been previously used. +Some IdPs support the `jti` claim. When supported by an IdP, Trusted Publisher implementations should utilize the `jti` claim to prevent replaying of OIDC ID tokens by rejecting tokens which have been previously used. -IdPs may allow customizing other claims, like validity time of the OIDC ID token. Trusted Publisher implementations may decide to add further requirements to IdPs and their OIDC tokens (such as maximum validity time) to enforce more secure OIDC ID token handling where this is possible with the IdP. +IdPs may allow customizing other claims, like validity time of the OIDC ID token. Trusted Publisher implementations may decide to add further requirements to IdPs and their OIDC ID tokens (such as maximum validity time) to enforce more secure OIDC ID token handling where this is possible with the IdP. -### OIDC tokens and repository-controlled tokens +### OIDC ID tokens and repository-controlled tokens -Package repositories should not use OIDC ID tokens for directly authenticating with package publishing APIs. Instead, package repositories should exchange the OIDC token for a repository-controlled API token that is used for authenticating with publishing APIs. Below are a list of reasons for the exchange: +Package repositories should not use OIDC ID tokens for directly authenticating with package publishing APIs. Instead, package repositories should exchange the OIDC ID token for a repository-controlled API token that is used for authenticating with publishing APIs. Below are a list of reasons for the exchange: -* If the package repository already supports token-based authentication, OIDC tokens won’t plug into the pre-existing existing authentication and authorization implementations. This will lead to needing to reimplement them for OIDC tokens, effectively having two token types and potentially leading to more bugs. +* If the package repository already supports token-based authentication, OIDC ID tokens won’t plug into the pre-existing existing authentication and authorization implementations. This will lead to needing to reimplement them for OIDC ID tokens, effectively having two token types and potentially leading to more bugs. * JWTs can contain any information that the provider decides to include, like private or personally identifiable information (i.e. names and email addresses). Using a separate token avoids holding on to this information for extended periods of time to reduce potential exposure or persistence. * Identity Providers can change the expiration and other policies around their tokens without notice. Creating your own temporary token makes the repository resilient to these changes. * Repository-managed tokens are more pluggable into existing tooling for publishing packages. From 07122039b24f6cf13a5f0b06336d353c90cd96ec Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Mon, 8 Jul 2024 09:01:03 -0500 Subject: [PATCH 6/8] Add link to docs/index.md Signed-off-by: Seth Michael Larson --- docs/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/index.md b/docs/index.md index cbf92e6..8001f6f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,6 +15,10 @@ This is a list of materials (surveys, documents, proposals, and so on) released * [Build Provenance for All Package Registries](https://repos.openssf.org/build-provenance-for-all-package-registries) - July 2023 > Guidance for package registries in adopting build provenance to verifiably link a package back to its source code and build instructions. +* [Trusted Publishers for All Package Repositories](https://repos.openssf.org/trusted-publishers-for-all-package-registries) - July 2024 + > Guidance for package registries in adopting Trusted Publishers to authenticate with package repositories from hosted build environments without using long-lived credentials. + + ## Proposals * [Build Provenance and Code-signing for Homebrew](https://repos.openssf.org/proposals/build-provenance-and-code-signing-for-homebrew) - July 2023 From 005b80e656c56e0af71c9373443c4591d237ce69 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Mon, 8 Jul 2024 11:37:37 -0500 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: William Woodruff Signed-off-by: Seth Michael Larson --- .../trusted-publishers-for-all-package-repositories.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/trusted-publishers-for-all-package-repositories.md b/docs/trusted-publishers-for-all-package-repositories.md index 295dfd6..476951e 100644 --- a/docs/trusted-publishers-for-all-package-repositories.md +++ b/docs/trusted-publishers-for-all-package-repositories.md @@ -1,18 +1,18 @@ # Trusted Publishers for All Package Repositories -Trusted Publishers is a new authentication method that builds on the existing OpenID Connect standard (OIDC) for user infrastructure publishing to public package repositories (e.g. CI publishing to PyPI, as opposed to maintainers publishing from their system or Homebrew's centralized builds). Authentication is performed by exchanging OIDC tokens for short-lived and tightly scoped API tokens for authenticating with package repository publishing APIs. Using short-lived API tokens removes the need to share long-lived and potentially highly privileged API tokens with external systems when publishing software. +Trusted Publishers is a new authentication method that builds on the existing OpenID Connect standard (OIDC) for user infrastructure publishing to public package repositories (e.g. CI publishing to PyPI, as opposed to maintainers publishing from their system or Homebrew's centralized builds). Authentication is performed by exchanging OIDC identity tokens for short-lived and tightly scoped API tokens for authenticating with package repository publishing APIs. Using short-lived API tokens removes the need to share long-lived and potentially highly privileged API tokens with external systems when publishing software. ## Why Trusted Publishers? **The goal of Trusted Publishers is to reduce the need for long-lived tokens or credentials to be shared with external systems when authenticating with package repositories.** Managing the lifecycle of long-lived tokens [poses additional security and management challenges](https://www.bleepingcomputer.com/news/security/over-12-million-auth-secrets-and-keys-leaked-on-github-in-2023/) for package indices and maintainers. -After configuration, Trusted Publishers require little to no user maintenance, providing an ergonomic and secure publishing experience for users, since they no longer need to manage long-lived secrets manually. Trusted publishers also allow maintainers to centralize authorization in a machine/workload identity, rather than additionally requiring managing users and authentication in the package repository. +After configuration, Trusted Publishers require little to no user maintenance. They provide an ergonomic and secure publishing experience for users, since users no longer need to manage long-lived secrets manually. Trusted publishers also allow maintainers to centralize authorization in a machine/workload identity, rather than additionally requiring managing users and authentication in the package repository. Trusted Publishers are popular with users when they’re available, for example PyPI added support for Trusted Publishers in April of 2023 and has since seen [over 13,000 projects](https://p.datadoghq.com/sb/7dc8b3250-b3f27ea9680eb560a2a1fb8ee12ff00b?fromUser=false&refresh_mode=sliding&from_ts=1716921809407&to_ts=1719513809407&live=true) voluntarily adopt Trusted Publishers. Trusted Publishers ensures a package is coming from a specific CI system, workflow, hosted machine or build pipeline, reducing the window for exfiltration abuse, unlike a long-lived API token. -For some Trusted Publishing providers, Trusted Publishers allow binding verifiable metadata like the source repository URL to a published artifact, allowing package repositories to avoid “[Star-Jacking](https://capec.mitre.org/data/definitions/693.html)” and similar attacks to confuse users about the trustworthiness of a project. +For some Trusted Publishing providers, Trusted Publishers allow binding verifiable metadata like the source repository URL to a published artifact, allowing package repositories to avoid “[Star-Jacking](https://capec.mitre.org/data/definitions/693.html)” and similar attacks that confuse users about the trustworthiness of a project. Trusted Publishers are ideal for package repositories that accept user-built packages, like PyPI and RubyGems, as opposed to package repositories that have centralized build infrastructure like Homebrew. @@ -24,7 +24,7 @@ Package repositories which don’t host separate artifacts (such as pkg.go.dev) Trusted Publishers allow a package repository like the Python Package Index (PyPI) to authenticate an identity from an Identity Provider (IdP) like GitHub Actions or GitLab Pipelines, and using a technology called OpenID Connect (OIDC). -Trusted Publishers works by requiring users to pre-configure a trust policy on the receiving package repository which will be later used as part of authenticating a publish request. When new artifacts are being published to the registry, the OIDC ID token (implemented as a JWT token) will be verified by [checking the JWT claims and signature against the IdP’s JSON Web Keyset (JWK)](https://www.criipto.com/blog/jwt-validation-guide) and checked to ensure the OIDC ID token’s issuer and claims match the [pre-configured trust policy for the package](https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions). +Trusted Publishers works by requiring users to pre-configure a trust policy on the receiving package repository which will be later used as part of authenticating a publish request. When new artifacts are being published to the registry, the OIDC ID token (implemented as a JWT) will be verified by [checking the JWT claims and signature against the IdP’s JSON Web Keyset (JWK)](https://www.criipto.com/blog/jwt-validation-guide) and checked to ensure the OIDC ID token’s issuer and claims match the [pre-configured trust policy for the package](https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions). The trust policy doesn’t necessarily need to have a _direct_ link to a package, for example some package repositories may want to assign trust policies to package namespaces, the trust policy determines whether a given package can be published by a given workload identity. @@ -111,7 +111,7 @@ There are limits to this approach, as not all resources will have IDs (for examp Trusted Publishers as described above are linked to _existing_ resources in a package repository, either packages themselves or package namespaces, etc. But this leaves a casualty dilemma for package repositories that can only _create a new package_ upon the first upload of an artifact (PyPI does this, for example). For package repositories with this property, it wouldn’t be possible to create a new package using a Trusted Publisher, because the package has to exist before a Trusted Publisher is configured for it. Leaving this situation as-is would mean that other, less secure publishing methods need to be used before users can adopt Trusted Publishers which is both an ergonomics and security problem. -One solution to this issue is to implement “Pending” Trusted Publishers, which are only tied to a specific account or organization until after they’re used for the first time, at which point they are bound further to a specific package or package namespace. When being used to authenticate an upload for the first time, the “pending” model is converted into a normal Trusted Publisher and associated with the authenticated resource in the database. This is done within the same database transaction as persisting the models to avoid scenarios where there’s partial success during the upload process. +One solution to this issue is to implement [“Pending” Trusted Publishers](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/), which are only tied to a specific account or organization until after they’re used for the first time, at which point they are bound further to a specific package or package namespace. When being used to authenticate an upload for the first time, the “pending” model is converted into a normal Trusted Publisher and associated with the authenticated resource in the database. This is done within the same database transaction as persisting the models to avoid scenarios where there’s partial success during the upload process. ## References From 80c3a8bb658d6636602af44e86de64e52d931c5c Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Thu, 11 Jul 2024 12:09:36 -0500 Subject: [PATCH 8/8] Registries -> Repositories Co-authored-by: Zach Steindler Signed-off-by: Seth Michael Larson --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 8001f6f..b28559a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,8 +15,8 @@ This is a list of materials (surveys, documents, proposals, and so on) released * [Build Provenance for All Package Registries](https://repos.openssf.org/build-provenance-for-all-package-registries) - July 2023 > Guidance for package registries in adopting build provenance to verifiably link a package back to its source code and build instructions. -* [Trusted Publishers for All Package Repositories](https://repos.openssf.org/trusted-publishers-for-all-package-registries) - July 2024 - > Guidance for package registries in adopting Trusted Publishers to authenticate with package repositories from hosted build environments without using long-lived credentials. +* [Trusted Publishers for All Package Repositories](https://repos.openssf.org/trusted-publishers-for-all-package-repositories) - July 2024 + > Guidance for package repositories in adopting Trusted Publishers to authenticate publishing from hosted build environments without using long-lived credentials. ## Proposals