From 9880ff3dee0135980c59b42d1300f6ae83455eca Mon Sep 17 00:00:00 2001 From: Andreas Olsson Date: Sun, 12 Jan 2025 10:34:38 +0100 Subject: [PATCH] Switch to using the GitHub App's Client ID Seems to be the direction that GitHub is moving in. * https://github.blog/changelog/2024-05-01-github-apps-can-now-use-the-client-id-to-fetch-installation-tokens/ * https://github.blog/changelog/2024-08-23-client-ids-are-now-included-in-app-api-responses/ Since I'm likely the only user of this library I'm skipping the deprecation cycle, instead making it a hard clean cutover. --- .github/helpers/gen-compose-env | 2 +- README.md | 4 ++-- hv4gha/entry.py | 9 +++------ hv4gha/helpers.py | 6 +++--- hv4gha/vault.py | 6 +++--- integration/.local.sops.env | 6 +++--- integration/testrun.py | 4 ++-- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/.github/helpers/gen-compose-env b/.github/helpers/gen-compose-env index 45aae61..19c4ec3 100755 --- a/.github/helpers/gen-compose-env +++ b/.github/helpers/gen-compose-env @@ -4,7 +4,7 @@ set -o nounset cat < str: return base64.b64encode(data).decode() -def prepare_gh_app_jwt(app_id: str, now: datetime) -> str: +def prepare_gh_app_jwt(app_client_id: str, now: datetime) -> str: """ Prepares the JWT payload needed to authenticate as a GitHub App - :param app_id: The GitHub App's ID + :param app_client_id: The GitHub App's client ID :param now: Current UTC time :return: The header-and-claims part of a JWT token @@ -46,7 +46,7 @@ def prepare_gh_app_jwt(app_id: str, now: datetime) -> str: claims = { "iat": timestamp, "exp": expire, - "iss": app_id, + "iss": app_client_id, } b64_header = b64str(json.dumps(header), urlsafe=True) diff --git a/hv4gha/vault.py b/hv4gha/vault.py index d8f44c3..0c46fe8 100644 --- a/hv4gha/vault.py +++ b/hv4gha/vault.py @@ -239,20 +239,20 @@ def import_key(self, *, key_name: str, pem_app_key: bytes) -> ImportResponse: return key_import - def sign_jwt(self, *, key_name: str, key_version: int, app_id: str) -> str: + def sign_jwt(self, *, key_name: str, key_version: int, app_client_id: str) -> str: """ Sign JWT token to authenticate towards GitHub :param key_name: Transit Engine key name. :param key_version: Transit Engine key version. - :param app_id: GitHub App ID. + :param app_client_id: GitHub App client ID. :return: GitHub App JWT token """ now = datetime.now(timezone.utc) - header_and_claims = prepare_gh_app_jwt(app_id, now) + header_and_claims = prepare_gh_app_jwt(app_client_id, now) api_path = f"/v1/{self.transit_backend}/sign/{key_name}" payload = { diff --git a/integration/.local.sops.env b/integration/.local.sops.env index 75d06ca..cf53267 100644 --- a/integration/.local.sops.env +++ b/integration/.local.sops.env @@ -1,11 +1,11 @@ HV4GHA_ACCOUNT=andreaso -HV4GHA_APP_ID=368468 +HV4GHA_APP_CLIENT_ID=Iv1.bc01362e9d72c72a HV4GHA_APP_KEY_B64=ENC[AES256_GCM,data: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,iv:8nhW3XAPn8anR5OR4V8/gtn/J8XTZofNck0IFsuczuo=,tag:btBex56eQw1Y/H0Z7wceWA==,type:str] HV4GHA_REVOKED_APP_KEY_B64=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBMEFFYTFDV212UitaQ3p1QmFYeFNnc1pDcjVvL0JhOEJ1dVNYWXYreXhhNTk4cktDCkFwQThHNHpSNys3cTM2UHNFYmJRZTgrS081L2ZqRGhZOXZuTHBrTlBZV2pGQ0wxSTlMcWZYekwyYi9iUmFzYUUKMklXemlZaEZ0TnBoK2lDeXZpZG55VnM2TmsrRnJmYXFKUVlCbG9MRXcycWZ3WVdsVEgvUDNibXFMQnAwWitkdgpob1MybmZzUlRlVWJTK2tEbXBYWFFHcmJGRWdRazVSeldLZ0JQVzNYalprMHBOTVpPbjZ3Sk5JYXdTbGZUdUczCjdVZEtsN2FacC9SV3E4Tk1TZTNSSTl2cE9ZRVVibHh6RHRPMUlpUUQwT2RiUXlHM3Y3TjNjN1lvNmFuQ2Z5SjMKWWVTOVVVcDZFQ0VKUlF3N013RFVvbXI1c3l5WGZicG0zVFRxMHdJREFRQUJBb0lCQVFDTkNoSzlBd0s2Zm5CeAowMWwrdzFQWFpNUFcra245ZXBzN3RNQ0oya1BJRXZkSDE0NmNXbHpIZVlib29DSVducm4xa1BadzNWc243dEhQCjdHMDJtazVpWUlXMDBTdTVMMUFHMFh3N092MHJFanNSb2FaMmdzSW9ZWVNTaXZtZ2R3ZDhOSkFGVXB4NE14ZTcKeStPMjB3bkVtc3I4anBIZzBOUXl1UCtqb3I4bXcxaGtNUWZJSkZMdzlLSWZ4NzJtVVhQTkZYWnRDTmc2cWVDTwp3bWNCV0lRcFhRTXRmQjY3RXlPN3FIZDVpZktiUm00Zmw5WGl6cUxiUWJjcUV0V0NpRGJ1RU5meGUyNC8zbVhrCngxa0paNnppc01NWUM3M3c4MlkxTXM4L3B1TlcyUDllN0xGZ2tDSk83QWxSbTdpbjdHUWhVNnlRVXlGT0lnaFMKODFHemdPbWhBb0dCQU91K2xzaEMzRk4yNVVnMEw4SVkwK1F5emFhMlNERjFhSk5RRFpTRU1nZjRSR01VMlM4UwpCQzVZWCtZeDFSVlJpYnFzR3JoNXJkdjFVWXFGQm5sSmxuanAwZVZZdmhJNysxbHV6YmNWY2Q2V2NUdDJ3anU2CmIwZElQTDg3c1V2eCtVVWx2ZW9WMTJ5cTRHS0hSQjhJekxLQzd0cTlNUUk2OHowV1k4cHZzY1RaQW9HQkFPSGcKV0l1K2FMWmExTlRvWW9peEIvUGxmOHBPRU12MVFCZHJpVHZWbE1rV1ZNTUdDR2xEZTNrUlQ5ZHoyWjFDOWFyWQpqSmoyYk1hdS93VlNPY0tyRzk1dlF1a01wTmM4ZndEUUZNUlZwTVFLTDIvVGxCOSswNlpOMFkzTEdwWmFUU3Z0CkRkeDBpcjhYT0pyZlIvQXhzRFE4VFRXdWJsNk82ZjAreTYzU0hiR0xBb0dCQUtQRjl3aE84ck9GUU1vRmZ6d3YKZFZ6dU1sSmtCZ2xlRUhWdXd0QnZlalp4TWtsSEhZNkd6S0xKd0cyeUp0ODFreUk5R0I4YVlUOFMwVUFUSkNrMApoeldlOHJPTEVCaW8xUGdQY3hpQzdHVi9URkRNTXltOVhqcytJdjJUWVp0cUVnc0lxa1FxUWt0NjlvRmNpV1dwCi9sTHhoVEF2Q1JJTWxCalhLaUpqc0RNWkFvR0JBTFI2ZXFXbURhcnZKckc3d01keGxHWW4wUlRIalpvNkt1ekwKcXNxWlhKblQ4d1FsTk9GTzMwQ2NPWXh3YjhlOU1laEJ3UTJUa05Tc0RPNm1oYXBxNkFpeUkrZHNoK1hHMjcrOQpnMnBnK0JjQUFHazh5RlRtRkowRC90VnFIS05ZSWVOZ05Ud2FEcWFqR2tKODk5RVBFcmlhR2lNemJkSzJKSGFLCkQxcWkwY0VEQW9HQVRudFNmUEtJeEhlRk5hTkRaT0pTdkhUOGtFblJhd2lKd2haZUZrVkdORWgzaHlrRks1aUIKb0lob0RpNWZCOTNiQTB0ZnN1Ujd1dHF2U1ExS0FKbWRFWVdpSWpBT3VxbHlYcFlUTVR3dVo3VTN5SWtWdThBWApJaDJSaEZHQ2pwOWd3UnNxN1ZMd3hGMm9iMzFVU3BiazFwaVJET2Q3T25xTGZHK3A5bEsyZmJzPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= HV4GHA_TEST_REPO=hv4gha sops_encrypted_regex=^HV4GHA_APP_KEY_B64$ -sops_lastmodified=2025-01-12T06:53:39Z -sops_mac=ENC[AES256_GCM,data:H3pzCZQ4f89oKWGBD+hhq4EhIpHTjS1WqrFWqWm/dKBI77qHvuiSFGL8gGMs4DpUTCSUZdoxrsLugYHjwihJrXKABkPBPImuvmaucJ85U7uxcIbaTFp6m8J4rOky/j7YFGM77fDSGHskr7KuJp+LAdEVX/BBVWOUVsp/VFXGC+Q=,iv:57OPDfzxbhYwc6ramD6i9YS1m5gpyb4ujW51y9aRjME=,tag:Gdcl5zJFlO7d3rdwMC/8Yg==,type:str] +sops_lastmodified=2025-01-12T09:24:39Z +sops_mac=ENC[AES256_GCM,data:X19RMxMrt2zHVxnpOk9BkwFMfBjROgjPmCHg7zsREt6Imb5v8i4PbrKpSdZCm/7N14oPV0bZ2A9/XmjIYJ+xd6eCjFl8z5e+lCv9PxpQahsm5/3P6KLK+92LTUcw3TmgM2MC9pP1uAVPD/Rrew/7MXcW6o7zxnEG5IYJl+6Rm1k=,iv:T4EktpnK6JH5+6ELyH5jPVsa+CdKG/xHDIV/DOrC7vU=,tag:TCVkCmCY4EXpReQb5BPkuw==,type:str] sops_pgp__list_0__map_created_at=2024-05-18T10:05:25Z sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nwV4D2VOvz+iLZv8SAQdARf9i6HtOiBdf+ugeHQ6YV3QKka/fQipO8ovZGY5AQQUw\nlyJ6ZB/W9EuPFTh1LwHZgqPhhC8Gy8c3A5Q5ysS1F1mNBYtRDJYGXPUa6m+f2+dE\n0lEBSlcdwsryiXgb0lrIgwDXoT1tmVf45vzUIzeLvnCleajycNZyHPprLLdkt52E\n1W2VdBFnr87wrcIErdEVyQbL25m/s3y5QvK9HASgMA/hT8k=\n=n7p3\n-----END PGP MESSAGE----- sops_pgp__list_0__map_fp=17E608319C69AE121E3D2DA4B8D8531495B2E77C diff --git a/integration/testrun.py b/integration/testrun.py index b8217f5..9c0401f 100644 --- a/integration/testrun.py +++ b/integration/testrun.py @@ -47,7 +47,7 @@ def issue() -> None: key_name=os.environ["HV4GHA_KEYNAME"], vault_addr=os.environ["HV4GHA_VAULT_ADDR"], vault_token=os.environ["HVGHA_VAULT_SIGN_TOKEN"], - app_id=os.environ["HV4GHA_APP_ID"], + app_client_id=os.environ["HV4GHA_APP_CLIENT_ID"], account=os.environ["HV4GHA_ACCOUNT"], ) @@ -61,7 +61,7 @@ def issue_scoped() -> None: key_name=os.environ["HV4GHA_KEYNAME"], vault_addr=os.environ["HV4GHA_VAULT_ADDR"], vault_token=os.environ["HVGHA_VAULT_SIGN_TOKEN"], - app_id=os.environ["HV4GHA_APP_ID"], + app_client_id=os.environ["HV4GHA_APP_CLIENT_ID"], account=os.environ["HV4GHA_ACCOUNT"], permissions=req_perms, repositories=[os.environ["HV4GHA_TEST_REPO"]],