Skip to content

Commit

Permalink
sigstore, test: add CircleCI credential detection
Browse files Browse the repository at this point in the history
See #31.

Signed-off-by: William Woodruff <[email protected]>
  • Loading branch information
woodruffw committed May 6, 2022
1 parent 6117638 commit f70f793
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
20 changes: 18 additions & 2 deletions sigstore/_internal/oidc/ambient.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def detect_credential() -> Optional[str]:
Raises `AmbientCredentialError` if any detector fails internally (i.e.
detects a credential, but cannot retrieve it).
"""
detectors: List[Callable[..., Optional[str]]] = [detect_github]
detectors: List[Callable[..., Optional[str]]] = [detect_github, detect_circleci]
for detector in detectors:
credential = detector()
if credential is not None:
Expand Down Expand Up @@ -76,7 +76,7 @@ def detect_github() -> Optional[str]:
req_url = os.getenv("ACTIONS_ID_TOKEN_REQUEST_URL")
if not req_token or not req_url:
raise AmbientCredentialError(
"GitHub: missing or insufficient OIDC token permissions?"
"GitHub: missing or insufficient OIDC token permissions"
)

resp = requests.get(
Expand All @@ -96,3 +96,19 @@ def detect_github() -> Optional[str]:
return _GitHubTokenPayload(**body).value
except Exception as e:
raise AmbientCredentialError("GitHub: malformed or incomplete JSON") from e


def detect_circleci() -> Optional[str]:
logger.debug("CircleCI: looking for OIDC credentials")

if not os.getenv("CIRCLECI"):
logger.debug("CircleCI: environment doesn't look right; giving up")
return None

token = os.getenv("CIRCLE_OIDC_TOKEN")
if not token:
raise AmbientCredentialError(
"CircleCI: missing or insufficient OIDC token permissions"
)

return token
27 changes: 23 additions & 4 deletions test/internal/oidc/test_ambient.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@


def test_detect_credential_none(monkeypatch):
detect_github = pretend.call_recorder(lambda: None)
monkeypatch.setattr(ambient, "detect_github", detect_github)
detect_noop = pretend.call_recorder(lambda: None)
for detector in ["detect_github", "detect_circleci"]:
monkeypatch.setattr(ambient, detector, detect_noop)
assert ambient.detect_credential() is None


Expand All @@ -32,7 +33,7 @@ def test_detect_credential(monkeypatch):
assert ambient.detect_credential() == "fakejwt"


def test_detect_github_bad_env(monkeypatch):
def test_detect_github_wrong_env(monkeypatch):
# We might actually be running in a CI, so explicitly remove this.
monkeypatch.delenv("GITHUB_ACTIONS", raising=False)

Expand All @@ -56,7 +57,7 @@ def test_detect_github_bad_permissions(monkeypatch):

with pytest.raises(
ambient.AmbientCredentialError,
match="GitHub: missing or insufficient OIDC token permissions?",
match="GitHub: missing or insufficient OIDC token permissions",
):
ambient.detect_github()
assert logger.debug.calls == [
Expand Down Expand Up @@ -136,3 +137,21 @@ def test_detect_github(monkeypatch):
)
]
assert resp.json.calls == [pretend.call()]


def test_detect_circleci_wrong_env(monkeypatch):
# We might actually be running in a CI, so explicitly remove this.
monkeypatch.delenv("CIRCLECI", raising=False)

assert ambient.detect_circleci() is None


def test_detect_circleci_bad_permissions(monkeypatch):
monkeypatch.setenv("CIRCLECI", "true")
monkeypatch.delenv("CIRCLE_OIDC_TOKEN", raising=False)

with pytest.raises(
ambient.AmbientCredentialError,
match="CircleCI: missing or insufficient OIDC token permissions",
):
ambient.detect_circleci()

0 comments on commit f70f793

Please sign in to comment.