Skip to content

Commit b3fee1f

Browse files
tetsuo-cppdi
andauthored
treewide: Replace ambient credential detection with id (#535)
* treewide: Replace ambient credential detection with `id` Signed-off-by: Alex Cameron <[email protected]> * CHANGELOG: Update changelog Signed-off-by: Alex Cameron <[email protected]> * README: Amend docs to reflect that we are using `id` for ambient credentials Signed-off-by: Alex Cameron <[email protected]> * README: Wording Signed-off-by: Alex Cameron <[email protected]> --------- Signed-off-by: Alex Cameron <[email protected]> Co-authored-by: Dustin Ingram <[email protected]>
1 parent c03092f commit b3fee1f

File tree

12 files changed

+31
-682
lines changed

12 files changed

+31
-682
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ All versions prior to 0.9.0 are untracked.
1010

1111
## [1.1.1]
1212

13+
### Changed
14+
15+
* Replaced ambient credential detection logic with the `id` package
16+
([#535](https://github.com/sigstore/sigstore-python/pull/535))
17+
1318
### Fixed
1419

1520
* Fixed a bug in TUF target handling revealed by changes to the production

README.md

+2-9
Original file line numberDiff line numberDiff line change
@@ -338,15 +338,8 @@ provided below.
338338
### Signing with ambient credentials
339339
340340
For environments that support OpenID Connect, natively `sigstore` supports ambient credential
341-
detection. This includes many popular CI platforms and cloud providers.
342-
343-
| Service | Status | Notes |
344-
|-----------------------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
345-
| GitHub Actions | Supported | Requires the `id-token` permission; see [the docs](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) and [this example](https://github.com/sigstore/sigstore-python/blob/main/.github/workflows/release.yml) |
346-
| Google Compute Engine (GCE) | Supported | Automatic |
347-
| Google Cloud Build (GCB) | Supported | Requires setting `GOOGLE_SERVICE_ACCOUNT_NAME` to an appropriately configured service account name; see [the docs](https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials#sa-credentials-direct) and [this example](https://github.com/sigstore/sigstore-python/blob/main/cloudbuild.yaml) |
348-
| GitLab CI | Planned | See [#31](https://github.com/sigstore/sigstore-python/issues/31) |
349-
| CircleCI | Planned | See [#31](https://github.com/sigstore/sigstore-python/issues/31) |
341+
detection. This includes many popular CI platforms and cloud providers. See the full list of
342+
supported environments [here](https://github.com/di/id#supported-environments).
350343
351344
Sign a single file (`foo.txt`) using an ambient OpenID Connect credential,
352345
saving the signature and certificate to `foo.txt.sig` and `foo.txt.crt`:

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ classifiers = [
2828
dependencies = [
2929
"appdirs ~= 1.4",
3030
"cryptography >= 39",
31+
"id >= 1.0.0",
3132
"importlib_resources ~= 5.7; python_version < '3.11'",
3233
"pydantic ~= 1.10",
3334
"pyjwt >= 2.1",

sigstore/_cli.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
from typing import Optional, TextIO, Union, cast
2525

2626
from cryptography.x509 import load_pem_x509_certificates
27+
from id import GitHubOidcPermissionCredentialError, detect_credential
2728
from sigstore_protobuf_specs.dev.sigstore.bundle.v1 import Bundle
2829

2930
from sigstore import __version__
3031
from sigstore._internal.ctfe import CTKeyring
3132
from sigstore._internal.fulcio.client import DEFAULT_FULCIO_URL, FulcioClient
3233
from sigstore._internal.keyring import Keyring
34+
from sigstore._internal.oidc import DEFAULT_AUDIENCE
3335
from sigstore._internal.rekor.client import (
3436
DEFAULT_REKOR_URL,
3537
RekorClient,
@@ -40,9 +42,7 @@
4042
from sigstore.oidc import (
4143
DEFAULT_OAUTH_ISSUER_URL,
4244
STAGING_OAUTH_ISSUER_URL,
43-
GitHubOidcPermissionCredentialError,
4445
Issuer,
45-
detect_credential,
4646
)
4747
from sigstore.sign import Signer
4848
from sigstore.transparency import LogEntry
@@ -1012,7 +1012,7 @@ def _get_identity_token(args: argparse.Namespace) -> Optional[str]:
10121012
token = None
10131013
if not args.oidc_disable_ambient_providers:
10141014
try:
1015-
token = detect_credential()
1015+
token = detect_credential(DEFAULT_AUDIENCE)
10161016
except GitHubOidcPermissionCredentialError as exception:
10171017
# Provide some common reasons for why we hit permission errors in
10181018
# GitHub Actions.

sigstore/_internal/oidc/__init__.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
"""
1818

1919
import jwt
20-
21-
from sigstore.oidc import IdentityError
20+
from id import IdentityError
2221

2322
# See: https://github.com/sigstore/fulcio/blob/b2186c0/pkg/config/config.go#L182-L201
2423
_KNOWN_OIDC_ISSUERS = {

sigstore/_internal/oidc/ambient.py

-193
This file was deleted.

sigstore/_internal/oidc/oauth.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828
import uuid
2929
from typing import Any, Dict, List, Optional, cast
3030

31+
from id import IdentityError
32+
3133
from sigstore._utils import B64Str
32-
from sigstore.oidc import IdentityError, Issuer
34+
from sigstore.oidc import Issuer
3335

3436
logger = logging.getLogger(__name__)
3537

sigstore/oidc.py

+1-45
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
import time
2424
import urllib.parse
2525
import webbrowser
26-
from typing import Callable, List, Optional
2726

2827
import requests
28+
from id import IdentityError
2929
from pydantic import BaseModel, StrictStr
3030

3131
DEFAULT_OAUTH_ISSUER_URL = "https://oauth2.sigstore.dev/auth"
@@ -169,47 +169,3 @@ def identity_token( # nosec: B107
169169
raise IdentityError(f"Error response from token endpoint: {token_error}")
170170

171171
return str(token_json["access_token"])
172-
173-
174-
class IdentityError(Exception):
175-
"""
176-
Raised on any OIDC token format or claim error.
177-
"""
178-
179-
pass
180-
181-
182-
class AmbientCredentialError(IdentityError):
183-
"""
184-
Raised when an ambient credential should be present, but
185-
can't be retrieved (e.g. network failure).
186-
"""
187-
188-
pass
189-
190-
191-
class GitHubOidcPermissionCredentialError(AmbientCredentialError):
192-
"""
193-
Raised when the current GitHub Actions environment doesn't have permission
194-
to retrieve an OIDC token.
195-
"""
196-
197-
pass
198-
199-
200-
def detect_credential() -> Optional[str]:
201-
"""
202-
Try each ambient credential detector, returning the first one to succeed
203-
or `None` if all fail.
204-
205-
Raises `AmbientCredentialError` if any detector fails internally (i.e.
206-
detects a credential, but cannot retrieve it).
207-
"""
208-
from sigstore._internal.oidc.ambient import detect_gcp, detect_github
209-
210-
detectors: List[Callable[..., Optional[str]]] = [detect_github, detect_gcp]
211-
for detector in detectors:
212-
credential = detector()
213-
if credential is not None:
214-
return credential
215-
return None

test/unit/conftest.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@
2020
from typing import Iterator
2121

2222
import pytest
23+
from id import (
24+
AmbientCredentialError,
25+
GitHubOidcPermissionCredentialError,
26+
detect_credential,
27+
)
2328
from sigstore_protobuf_specs.dev.sigstore.bundle.v1 import Bundle
2429
from tuf.api.exceptions import DownloadHTTPError
2530
from tuf.ngclient import FetcherInterface
2631

2732
from sigstore._internal import tuf
28-
from sigstore.oidc import (
29-
AmbientCredentialError,
30-
GitHubOidcPermissionCredentialError,
31-
detect_credential,
32-
)
33+
from sigstore._internal.oidc import DEFAULT_AUDIENCE
3334
from sigstore.verify import VerificationMaterials
3435
from sigstore.verify.policy import VerificationSuccess
3536

@@ -42,7 +43,7 @@
4243

4344
def _is_ambient_env():
4445
try:
45-
token = detect_credential()
46+
token = detect_credential(DEFAULT_AUDIENCE)
4647
if token is None:
4748
return False
4849
except GitHubOidcPermissionCredentialError:

0 commit comments

Comments
 (0)