Skip to content

Commit bfabba3

Browse files
authored
Emit metrics on GitHub event_name claim (#18887)
* Emit metrics on GitHub event_name claim * Assert on the metrics call
1 parent faf778f commit bfabba3

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

tests/unit/oidc/models/test_github.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ def test_github_publisher_missing_claims(self, monkeypatch, missing):
338338
]
339339
assert scope.fingerprint == [missing]
340340

341-
def test_github_publisher_missing_optional_claims(self, monkeypatch):
341+
def test_github_publisher_missing_optional_claims(self, metrics, monkeypatch):
342342
publisher = github.GitHubPublisher(
343343
repository_name="fakerepo",
344344
repository_owner="fakeowner",
@@ -352,6 +352,7 @@ def test_github_publisher_missing_optional_claims(self, monkeypatch):
352352

353353
service_ = pretend.stub(
354354
jwt_identifier_exists=pretend.call_recorder(lambda s: False),
355+
metrics=metrics,
355356
)
356357

357358
signed_claims = {
@@ -433,6 +434,23 @@ def test_check_repository(self, truth, claim, valid):
433434
check = github.GitHubPublisher.__required_verifiable_claims__["repository"]
434435
assert check(truth, claim, pretend.stub()) == valid
435436

437+
def test_check_event_name_emits_metrics(self, metrics):
438+
check = github.GitHubPublisher.__required_verifiable_claims__["event_name"]
439+
publisher_service = pretend.stub(metrics=metrics)
440+
441+
assert check(
442+
"throwaway",
443+
"pull_request_target",
444+
pretend.stub(),
445+
publisher_service=publisher_service,
446+
)
447+
assert metrics.increment.calls == [
448+
pretend.call(
449+
"warehouse.oidc.claim",
450+
tags=["publisher:GitHub", "event_name:pull_request_target"],
451+
),
452+
]
453+
436454
@pytest.mark.parametrize(
437455
("claim", "ref", "sha", "valid", "expected"),
438456
[

warehouse/oidc/models/github.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
if typing.TYPE_CHECKING:
2929
from sqlalchemy.orm import Session
3030

31+
from warehouse.oidc.services import OIDCPublisherService
32+
3133
GITHUB_OIDC_ISSUER_URL = "https://token.actions.githubusercontent.com"
3234

3335
# This expression matches the workflow filename component of a GitHub
@@ -152,6 +154,18 @@ def _check_sub(
152154
return f"{org}:{repo}".lower() == ground_truth.lower()
153155

154156

157+
def _check_event_name(
158+
ground_truth: str, signed_claim: str, _all_signed_claims: SignedClaims, **kwargs
159+
) -> bool:
160+
# Log the event name
161+
publisher_service: OIDCPublisherService = kwargs["publisher_service"]
162+
publisher_service.metrics.increment(
163+
"warehouse.oidc.claim", tags=["publisher:GitHub", f"event_name:{signed_claim}"]
164+
)
165+
# Always permit all event names for now
166+
return True
167+
168+
155169
class GitHubPublisherMixin:
156170
"""
157171
Common functionality for both pending and concrete GitHub OIDC publishers.
@@ -170,6 +184,7 @@ class GitHubPublisherMixin:
170184
"repository_owner_id": check_claim_binary(str.__eq__),
171185
"job_workflow_ref": _check_job_workflow_ref,
172186
"jti": check_existing_jti,
187+
"event_name": _check_event_name,
173188
}
174189

175190
__required_unverifiable_claims__: set[str] = {"ref", "sha"}
@@ -186,7 +201,6 @@ class GitHubPublisherMixin:
186201
"run_attempt",
187202
"head_ref",
188203
"base_ref",
189-
"event_name",
190204
"ref_type",
191205
"repository_id",
192206
"workflow",
@@ -275,6 +289,11 @@ def jti(self) -> str:
275289
"""Placeholder value for JTI."""
276290
return "placeholder"
277291

292+
@property
293+
def event_name(self) -> str:
294+
"""Placeholder value for event_name (not used)"""
295+
return "placeholder"
296+
278297
def publisher_url(self, claims: SignedClaims | None = None) -> str:
279298
base = self.publisher_base_url
280299
sha = claims.get("sha") if claims else None

0 commit comments

Comments
 (0)