Skip to content

Commit

Permalink
Sign releases with ambient credentials via Github Actions (#60)
Browse files Browse the repository at this point in the history
* Use ambient credential detection when not explicitly supplied

Signed-off-by: Alex Cameron <asc@tetsuo.sh>

* Use ambient credentials in Github Actions release signing

Signed-off-by: Alex Cameron <asc@tetsuo.sh>

* Specify audience

Signed-off-by: Alex Cameron <asc@tetsuo.sh>

* Fix ambient unit tests

Signed-off-by: Alex Cameron <asc@tetsuo.sh>

* Update sigstore/_cli.py

Co-authored-by: Dustin Ingram <di@users.noreply.github.com>

* sigstore, test: build audience parameter programmatically

Signed-off-by: William Woodruff <william@trailofbits.com>

Co-authored-by: William Woodruff <william@trailofbits.com>
Co-authored-by: Dustin Ingram <di@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 30, 2022
1 parent 5960edf commit 46715c4
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 14 deletions.
12 changes: 2 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,8 @@ jobs:
# until things are stabilized further
python -m pip install .
# retrieve the OIDC identity
identity_token=$( \
curl -H \
"Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sigstore" \
| jq -r .value \
)
# sign all package distributions using the OIDC identity
python -m sigstore sign --identity-token=${identity_token} dist/*
# sign all package distributions using the ambient OIDC identity
python -m sigstore sign dist/*
- name: publish
uses: pypa/gh-action-pypi-publish@master
Expand Down
8 changes: 8 additions & 0 deletions sigstore/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import click

from sigstore import sign, verify
from sigstore._internal.oidc.ambient import detect_credential
from sigstore._internal.oidc.oauth import get_identity_token


Expand All @@ -37,6 +38,13 @@ def main():
"files", metavar="FILE [FILE ...]", type=click.File("rb"), nargs=-1, required=True
)
def _sign(files, identity_token, ctfe_pem):
# The order of precedence is as follows:
#
# 1) Explicitly supplied identity token
# 2) Ambient credential detected in the environment
# 3) Interactive OAuth flow
if not identity_token:
identity_token = detect_credential()
if not identity_token:
identity_token = get_identity_token()

Expand Down
6 changes: 5 additions & 1 deletion sigstore/_internal/oidc/ambient.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ def detect_github() -> Optional[str]:
"GitHub: missing or insufficient OIDC token permissions?"
)

resp = requests.get(req_url, headers={"Authorization": f"bearer {req_token}"})
resp = requests.get(
req_url,
params={"audience": "sigstore"},
headers={"Authorization": f"bearer {req_token}"},
)
try:
resp.raise_for_status()
except requests.HTTPError as http_error:
Expand Down
18 changes: 15 additions & 3 deletions test/internal/oidc/test_ambient.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ def test_detect_github_request_fails(monkeypatch):
):
ambient.detect_github()
assert requests.get.calls == [
pretend.call("fakeurl", headers={"Authorization": "bearer faketoken"})
pretend.call(
"fakeurl",
params={"audience": "sigstore"},
headers={"Authorization": "bearer faketoken"},
)
]


Expand All @@ -88,7 +92,11 @@ def test_detect_github_bad_payload(monkeypatch):
):
ambient.detect_github()
assert requests.get.calls == [
pretend.call("fakeurl", headers={"Authorization": "bearer faketoken"})
pretend.call(
"fakeurl",
params={"audience": "sigstore"},
headers={"Authorization": "bearer faketoken"},
)
]
assert resp.json.calls == [pretend.call()]

Expand All @@ -107,6 +115,10 @@ def test_detect_github(monkeypatch):

assert ambient.detect_github() == "fakejwt"
assert requests.get.calls == [
pretend.call("fakeurl", headers={"Authorization": "bearer faketoken"})
pretend.call(
"fakeurl",
params={"audience": "sigstore"},
headers={"Authorization": "bearer faketoken"},
)
]
assert resp.json.calls == [pretend.call()]

0 comments on commit 46715c4

Please sign in to comment.