Skip to content

Commit ade57f5

Browse files
committed
Merge PRs #174 #175 and #172 into unstable/v1
4 parents 413a8d5 + 326f9ad + 637917e + adef75a commit ade57f5

File tree

3 files changed

+61
-12
lines changed

3 files changed

+61
-12
lines changed

README.md

+15-10
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ tag, or opt-in to [use a full Git commit SHA] and Dependabot.
2525

2626
### Trusted publishing
2727

28-
> **NOTE**: Trusted publishing is sometimes referred to by its
28+
> [!NOTE]
29+
> Trusted publishing is sometimes referred to by its
2930
> underlying technology -- OpenID Connect, or OIDC for short.
3031
> If you see references to "OIDC publishing" in the context of PyPI,
3132
> this is what they're referring to.
@@ -61,10 +62,11 @@ jobs:
6162
uses: pypa/gh-action-pypi-publish@release/v1
6263
```
6364
64-
> **Pro tip**: instead of using branch pointers, like `unstable/v1`, pin
65-
versions of Actions that you use to tagged versions or sha1 commit identifiers.
66-
This will make your workflows more secure and better reproducible, saving you
67-
from sudden and unpleasant surprises.
65+
> [!NOTE]
66+
> Pro tip: instead of using branch pointers, like `unstable/v1`, pin versions of
67+
> Actions that you use to tagged versions or sha1 commit identifiers.
68+
> This will make your workflows more secure and better reproducible, saving you
69+
> from sudden and unpleasant surprises.
6870

6971
Other indices that support trusted publishing can also be used, like TestPyPI:
7072

@@ -76,7 +78,8 @@ Other indices that support trusted publishing can also be used, like TestPyPI:
7678
```
7779
_(don't forget to update the environment name to `testpypi` or similar!)_
7880

79-
> **Pro tip**: only set the `id-token: write` permission in the job that does
81+
> [!NOTE]
82+
> Pro tip: only set the `id-token: write` permission in the job that does
8083
> publishing, not globally. Also, try to separate building from publishing
8184
> — this makes sure that any scripts maliciously injected into the build
8285
> or test environment won't be able to elevate privileges while flying under
@@ -96,7 +99,8 @@ This GitHub Action [has nothing to do with _building package
9699
distributions_]. Users are responsible for preparing dists for upload
97100
by putting them into the `dist/` folder prior to running this Action.
98101

99-
> **IMPORTANT**: Since this GitHub Action is docker-based, it can only
102+
> [!IMPORTANT]
103+
> Since this GitHub Action is docker-based, it can only
100104
> be used from within GNU/Linux based jobs in GitHub Actions CI/CD
101105
> workflows. This is by design and is unlikely to change due to a number
102106
> of considerations we rely on.
@@ -187,9 +191,10 @@ default) setting as follows:
187191
skip-existing: true
188192
```
189193

190-
> **Pro tip**: try to avoid enabling this setting where possible. If you
191-
have steps for publishing to both PyPI and TestPyPI, consider only using
192-
it for the latter, having the former fail loudly on duplicates.
194+
> [!NOTE]
195+
> Pro tip: try to avoid enabling this setting where possible. If you
196+
> have steps for publishing to both PyPI and TestPyPI, consider only using
197+
> it for the latter, having the former fail loudly on duplicates.
193198

194199
### For Debugging
195200

oidc-exchange.py

+45-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import base64
2+
import json
13
import os
24
import sys
35
from http import HTTPStatus
@@ -50,6 +52,25 @@
5052
Token request failed: the server refused the request for the following reasons:
5153
5254
{reasons}
55+
56+
This generally indicates a trusted publisher configuration error, but could
57+
also indicate an internal error on GitHub or PyPI's part.
58+
59+
{rendered_claims}
60+
"""
61+
62+
_RENDERED_CLAIMS = """
63+
The claims rendered below are **for debugging purposes only**. You should **not**
64+
use them to configure a trusted publisher unless they already match your expectations.
65+
66+
If a claim is not present in the claim set, then it is rendered as `MISSING`.
67+
68+
* `sub`: `{sub}`
69+
* `repository`: `{repository}`
70+
* `repository_owner`: `{repository_owner}`
71+
* `repository_owner_id`: `{repository_owner_id}`
72+
* `job_workflow_ref`: `{job_workflow_ref}`
73+
* `ref`: `{ref}`
5374
"""
5475

5576
# Rendered if the package index's token response isn't valid JSON.
@@ -121,6 +142,23 @@ def assert_successful_audience_call(resp: requests.Response, domain: str):
121142
)
122143

123144

145+
def render_claims(token: str) -> str:
146+
_, payload, _ = token.split(".", 2)
147+
claims = json.loads(base64.urlsafe_b64decode(payload))
148+
149+
def _get(name: str) -> str: # noqa: WPS430
150+
return claims.get(name, "MISSING")
151+
152+
return _RENDERED_CLAIMS.format(
153+
sub=_get("sub"),
154+
repository=_get("repository"),
155+
repository_owner=_get("repository_owner"),
156+
repository_owner_id=_get("repository_owner_id"),
157+
job_workflow_ref=_get("job_workflow_ref"),
158+
ref=_get("ref"),
159+
)
160+
161+
124162
repository_url = get_normalized_input("repository-url")
125163
repository_domain = urlparse(repository_url).netloc
126164
token_exchange_url = f"https://{repository_domain}/_/oidc/github/mint-token"
@@ -165,7 +203,13 @@ def assert_successful_audience_call(resp: requests.Response, domain: str):
165203
for error in mint_token_payload["errors"]
166204
)
167205

168-
die(_SERVER_REFUSED_TOKEN_EXCHANGE_MESSAGE.format(reasons=reasons))
206+
rendered_claims = render_claims(oidc_token)
207+
208+
die(
209+
_SERVER_REFUSED_TOKEN_EXCHANGE_MESSAGE.format(
210+
reasons=reasons, rendered_claims=rendered_claims,
211+
),
212+
)
169213

170214
pypi_token = mint_token_payload.get("token")
171215
if pypi_token is None:

requirements/runtime.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ cffi==1.15.1
1414
# via cryptography
1515
charset-normalizer==3.2.0
1616
# via requests
17-
cryptography==41.0.2
17+
cryptography==41.0.3
1818
# via secretstorage
1919
docutils==0.20.1
2020
# via readme-renderer

0 commit comments

Comments
 (0)