I needed to review a Pull Request that was fixing a reported issue with a sample and while tests were passing, it felt like there must be something more going on with the sample that needed to change.
I've known about JSON Web Tokens (JWTs pronounced "jots") for a while, I don't know them. Seeing this PR gave me a reason to dig into them more.
JWTs are an open standard method for securely transmitting information between parties. They are often used to authenticate users and authorize access to resources. They consist of 3 parts, a header, payload, and signature.
The IAM Service Account Credentials API creates short-lived credentials for impersonating IAM service accounts. The signJwtmethod will sign the JWT using a service account's system-managed private key. Within the request body of the signJwt method, the payload field should contain a serialized JSON object that contains a JWT claims set.
Claims are the core information that the JWT transmits.
Here is an example of a valid claims set:
{ "iss": "https://cloud.google.com/iam", "sub": "projects/-/serviceAccounts/[email protected]", "aud": "https://my-iap-protected-app.example.com", "iat": 1694003600, "exp": 1694007200 }
This claims set includes the following fields:
By including these claims in the payload of your JWT, you can ensure that it is valid and can be used to access IAP-protected resources.
The original code looked like
iat = datetime.datetime.now(tz=datetime.timezone.utc) exp = iat 3600 return json.dumps( { "iss": service_account_email, "sub": service_account_email, "aud": resource_url, "iat": iat, "exp": exp, } )
I know something is up with the testing but I don't want to block getting the underlying issue with this code resolved.
The PR author submitted the change
iat = datetime.datetime.now(tz=datetime.timezone.utc).timestamp()
This seemed like it would be an incomplete fix. Based on the documentation for the API, I realized that the submitted fix still wouldn't set iat to type int and would still fail. I proposed a slight change that would resolve the PR's issue of
now_utc = datetime.datetime.now(tz=datetime.timezone.utc) iat = int(now_utc.timestamp())
The more I thought about it, I realized that Datetime isn't useful for this sample. The Datetime module supplies classes for manipulating dates and times which are useful when you want dates. We literally need an integer in UTC so the Time module is more useful.
Insetad, we can do this
now = int(time.time()) return json.dumps( { "iss": service_account_email, "sub": service_account_email, "aud": resource_url, "iat": now, "exp": now 3600, } )
Find the complete (updated!) code for this sample here.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3