fix: cast gh_app_id to string for JWT encoding compatibility#705
fix: cast gh_app_id to string for JWT encoding compatibility#705
Conversation
Relates to github-community-projects/evergreen#508 ## What Cast gh_app_id to str() when passing it to login_as_app_installation, which internally calls jwt.encode expecting the iss claim to be a string. Updated tests to pass integer app IDs and assert the string conversion occurs. ## Why Since v2.0.0, GitHub App authentication fails with "TypeError: Issuer (iss) must be a string" because newer versions of PyJWT enforce that the iss claim is a string, but gh_app_id was being passed as an integer. ## Notes - Tests now use assert_called_once_with instead of assert_called_once to verify the exact arguments, preventing this class of regression - Test inputs changed from strings to integers to mirror real-world usage where env vars are parsed as ints Signed-off-by: jmeridth <jmeridth@gmail.com>
There was a problem hiding this comment.
Pull request overview
Fixes GitHub App authentication failures caused by PyJWT requiring the JWT iss claim to be a string, by ensuring the GitHub App ID is passed as a string when authenticating.
Changes:
- Cast
gh_app_idtostrwhen callinglogin_as_app_installation. - Tighten unit tests to assert exact call arguments and use integer app IDs as inputs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
auth.py |
Casts gh_app_id to str in the login_as_app_installation call to satisfy PyJWT issuer requirements. |
test_auth.py |
Updates tests to pass integer app IDs and asserts exact authentication call arguments via assert_called_once_with. |
Signed-off-by: jmeridth <jmeridth@gmail.com>
There was a problem hiding this comment.
The parameter order in test_auth.py lines 87-89 is swapped - b"gh_private_token" is in the gh_app_id position and "gh_app_id" is in the gh_app_private_key_bytes position. I believe it passes because create_jwt_headers is mocked so the wrong types never get exercised.
# Current (incorrect order):
result = get_github_app_installation_token(
mock_ghe, b"gh_private_token", "gh_app_id", "gh_installation_id"
)
# Should be:
result = get_github_app_installation_token(
mock_ghe, "gh_app_id", b"gh_private_token", "gh_installation_id"
)Also, the type annotations for gh_app_id and gh_app_installation_id in get_github_app_installation_token (auth.py line 54) say str, but get_int_env_var("GH_APP_ID") returns int | None in config.py, and issue_metrics.py line 271 passes them as ints. Might want to update these to int to match reality (or keep str and add the str() cast at the call site like you did in auth_to_github).
What
Cast gh_app_id to str() when passing it to login_as_app_installation, which internally calls jwt.encode expecting the iss claim to be a string. Updated tests to pass integer app IDs and assert the string conversion occurs.
Why
Since v2.0.0, GitHub App authentication fails with "TypeError: Issuer (iss) must be a string" because newer versions of PyJWT enforce that the iss claim is a string, but gh_app_id was being passed as an integer.
Notes