Code of Conduct
What article on docs.github.com is affected?
https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app#example-using-python-to-generate-a-jwt
What part(s) of the article would you like to see updated?
Example: Using Python to generate a JWT
The Note: may be updated to mention both PyJWT and jwt. Both Python modules use the same namespace, and if the Python environment where this is being run has PyJWT installed, the script does not work.
To fix this, we introduce two functions from the cryptography module, and before the script runs the loaded jwt module has its attributes evaluated to determine whether it's PyJWT or jwt. The condition may be improved upon, but I've tested the following that works:
isPyJwt = hasattr(jwt,"name") and hasattr(jwt,"PyJWT")
The remaining changes can be identified by looking for the conditions that reference isPyJwt.
Updated script:
#!/usr/bin/env python3
import jwt
import time
import sys
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.backends import default_backend
# Determine what module JWT is coming from (PyJWT and jwt share the same namespace)
isPyJwt = hasattr(jwt,"__name__") and hasattr(jwt,"PyJWT")
# Get PEM file path
if len(sys.argv) > 1:
pem = sys.argv[1]
else:
pem = input("Enter path of private PEM file: ")
# Get the App ID
if len(sys.argv) > 2:
app_id = sys.argv[2]
else:
app_id = input("Enter your APP ID: ")
# Open PEM
with open(pem, 'rb') as pem_file:
if isPyJwt:
signing_key = load_pem_private_key(pem_file.read(), None, default_backend())
else:
signing_key = jwt.jwk_from_pem(pem_file.read())
payload = {
# Issued at time
'iat': int(time.time()),
# JWT expiration time (10 minutes maximum)
'exp': int(time.time()) + 600,
# GitHub App's identifier
'iss': app_id
}
# Create JWT
if isPyJwt:
encoded_jwt = jwt.encode(payload, signing_key, algorithm='RS256')
else:
jwt_instance = jwt.JWT()
encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')
print(f"{encoded_jwt}")
Additional information
This has been tested in two scenarios - one in which the system only has only PyJWT, and the other that has the jwt module installed.
Code of Conduct
What article on docs.github.com is affected?
https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app#example-using-python-to-generate-a-jwt
What part(s) of the article would you like to see updated?
Example: Using Python to generate a JWT
The
Note:may be updated to mention bothPyJWTandjwt. Both Python modules use the same namespace, and if the Python environment where this is being run has PyJWT installed, the script does not work.To fix this, we introduce two functions from the
cryptographymodule, and before the script runs the loadedjwtmodule has its attributes evaluated to determine whether it'sPyJWTorjwt. The condition may be improved upon, but I've tested the following that works:The remaining changes can be identified by looking for the conditions that reference
isPyJwt.Updated script:
Additional information
This has been tested in two scenarios - one in which the system only has only
PyJWT, and the other that has thejwtmodule installed.