Skip to content

Cloud Pub/Sub: authenticated push in GAE Standard for Python 3 #2097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 8, 2019

Conversation

anguillanneuf
Copy link
Member

@anguillanneuf anguillanneuf commented Apr 5, 2019

TL;DR: Authenticated Push is a new Cloud Pub/Sub beta feature. After it has been set up as such, Cloud Pub/Sub generates a JWT and attaches it to the "Authorization" header in the push request. Users can verify the token using the Google Auth Python library to confirm that the push requests indeed come from Cloud Pub/Sub.

Things to check extra carefully in this PR:

  • main.py: receive_messages_handler
  • main_test.py: test_push_endpoint

I create a mock token using the private key in data/privatekey.pem. I monkeypatched the function to verify oauth2 tokens so that it doesn't get checked against the real Google public certs but what's in data/public_cert.pem. These pem files are the same as those from the tests in google-auth-library-python.

@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Apr 5, 2019
@anguillanneuf anguillanneuf requested review from engelke and lesv April 5, 2019 22:26
Copy link
Contributor

@engelke engelke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but consider if any of the above comments should be addressed.

token = bearer_token.split(' ')[1]
TOKENS.append(token)

header = jwt.decode_header(token)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this verifying the audience ('aud') field? Does it need to? This makes sure it is from pub/sub, but it could possibly be relayed from a push notification to a different app. Or do all push notifications use the same aud value?

Copy link
Member Author

@anguillanneuf anguillanneuf Apr 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it is not verifying the aud field. It decodes the JWT header as shown. (If --push-auth-token-audience isn't set when creating the push subscription, then the aud field will be set to the push endpoint.)

I don't have code that specifically checks the aud field, should I add?

# JWT header
{"alg":"RS256","kid":"7d680d8c70d44e947133cbd499ebc1a61c3d5abc","typ":"JWT"}

# JWT claim
{
   "aud":"https://example.com",
   "azp":"113774264463038321964",
   "email":"gae-gcp@appspot.gserviceaccount.com",
   "sub":"113774264463038321964",
   "email_verified":true,
   "exp":1550185935,
   "iat":1550182335,
   "iss":"https://accounts.google.com"
  }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't think so. This all looks very good to me. Go ahead and merge when you're ready, or let me know if you want me to do it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anguillanneuf I'm just getting started reading this, so apologies if you are doing this, but the rule of thumb on these things is to verify the signature before touching any of the fields, then look at the expires and then the audience. (in that order). Then everything else.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lesv 1. verifying signature and 2. checking expiration time are both done by the Google Auth Python library. I added 3. checking the audience field in the claim. Thanks for catching this!

Copy link
Contributor

@plamut plamut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anguillanneuf I found some time to review this. Did not actually run the example, just glanced over the code.

I see that this PR has already been approved in the meanwhile, thus if you feel the comments I gave are not significant enough to warrant a yet another review cycle, feel free to discard them. :)

Edit: I see that some of the comments have already been addressed in later commits - just ignore them, please (I was reviewing the PR commit by commit).

Copy link
Contributor

@lesv lesv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a couple nits

token = bearer_token.split(' ')[1]
TOKENS.append(token)

header = jwt.decode_header(token)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anguillanneuf I'm just getting started reading this, so apologies if you are doing this, but the rule of thumb on these things is to verify the signature before touching any of the fields, then look at the expires and then the audience. (in that order). Then everything else.

Copy link
Contributor

@lesv lesv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix README
Users should change the claim validation should also be called out in both the README and the code.

I'm going to click approve so that you can submit based on someone else's review, feel free to call me out specifically if you'd like me to review again.

@anguillanneuf
Copy link
Member Author

Thanks @lesv. I feel good to merge it now.
And thanks @engelke @plamut for reviewing my PR earlier.

@anguillanneuf anguillanneuf merged commit 3d1f403 into master Apr 8, 2019
@anguillanneuf anguillanneuf deleted the authenticated_push branch April 8, 2019 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants