service account auth to Calendar API stopped working Oct 20

268 views
Skip to first unread message

Eric G

unread,
Oct 24, 2016, 2:46:28 PM10/24/16
to Google App Engine

I have a GAE project (python 2.7 runtime) that uses the Google Calendar API v3. Up until last week, I had been using the default GAE service account to connect to the calendar API, and the service account was given read/write permission to the calendar under calendar sharing settings.


Since last Thursday Oct 20, the service account cannot write to the calendar (events.post or events.patch) -- returns a 403 Forbidden -- and reads (events.list) return 200, but no records. Checking the permissions for the account under calendar sharing, it has been changed to "See Free/Busy only".


I believe this is related to this announcement from Google about winding down OAuth 1.0 service accounts on Oct 20: https://developers.googleblog.com/2016/04/saying-goodbye-to-oauth-10-2lo.html


The recommendation seems to be to grant Domain Wide Delegation to the service account: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority


We have followed the instructions on this page, but it doesn't work using either AppAssertionCredentials or ServiceAccountCredentials.  

More details at this SO question:
http://stackoverflow.com/questions/40223292/google-app-engine-auth-for-google-apis-using-service-account

Thanks for any light you can shine on this problem.



George (Cloud Platform Support)

unread,
Oct 25, 2016, 4:33:25 PM10/25/16
to Google App Engine
Hello Eric!
More detail is needed, to investigate your problem: 
- About the client library: language, version (GData, API Client ?).  
- API scopes? 
- The actual URL posted in your app call. 
- Code (HTTP Request)? 
- Are there other accounts affected, or just one, or few? 
- In case an account works well, email address and user? 
- Any part of your code you deem significant.  
- Request output. 
- Eventual screenshots of the results, if relevant. 
- If possible, HTTP Request and Response headers, or full HTTP logs. 

Waiting for information; let me know if I may help otherwise. 

Eric G

unread,
Oct 29, 2016, 1:55:03 PM10/29/16
to Google App Engine
Details below. I also opened an issue on the apps-api-issues:
https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4870&colspec=Stars%20Opened%20ID%20Type%20Status%20Summary%20API%20Owner

I successfully switched the app to use 3-legged OAuth vs. service account OAuth, but still would like to get to the bottom of this, as I'd prefer to use service account OAuth for testing and maintenance programs that hit this API, and also for the benefit of others who may be having the problem.

G Suite tech support suggested after setting up DwD you may have to use credentials.create_delegated('some.re...@example.com')  -- as mentioned on this page (but without any indication that it's necessary, and very easy to miss). I have not tried that but will in the next day or two.


On Tuesday, October 25, 2016 at 4:33:25 PM UTC-4, George (Cloud Platform Support) wrote:
Hello Eric!
More detail is needed, to investigate your problem: 
- About the client library: language, version (GData, API Client ?).

- Python 2.7 App Engine runtime
- google-api-python-client==1.5.3
- oauth2client==4.0.0
 
 
- API scopes? 

- The actual URL posted in your app call. 
 
 
- Are there other accounts affected, or just one, or few? 

All the service accounts we set up.
 
- In case an account works well, email address and user? 
- Any part of your code you deem significant.  
- Request output.

GET: 


POST:

George (Cloud Platform Support)

unread,
Nov 1, 2016, 11:22:12 AM11/1/16
to Google App Engine

Hello Eric!

For your new service accounts, your code imports credentials from a stored JSON file, which is one of the possible alternatives, all of which should work well.

How did you grant domain-wide access to your service account, exactly?

Did you then implement the OAuth2WebServerFlow as described on the “OAuth 2.0” page?

If you delegated domain-wide access to your service account successfully, you need to use the "delegated_credentials = credentials.create_delegated('us...@example.org')" statement to impersonate a user with the service account, as indicated at the “Delegate domain-wide authority” paragraph on the “Using OAuth 2.0 for Server to Server Applications” page.

I hope this helps for now. I’ll look at your code and try to reproduce the bug meanwhile, waiting for your reply.

Eric G

unread,
Nov 3, 2016, 4:05:20 PM11/3/16
to Google App Engine
Thanks. It seems to work now, oddly without even doing credentials.create_delegated (but I may be mistaken, I only tested it briefly in an offline context. In my GAE application, I've switched it to use standard 3-legged OAuth instead of service accounts).

Anyway, if credentials.create_delegated is essential for service accounts with DwD, I would propose making it more obvious in the documentation. I carefully read that page several times and missed it. The way the document hierarchy reads, it looks like it is on the same level as "Google App Engine", "Google Compute Engine", and "Other". So if you are looking for GAE instructions, you may think it doesn't apply to you. I would suggest moving that up one level in the hierarchy so you'd have:

1. Create a Credentials object from the service account's credentials and the scopes your application needs access to.

2. If you have delegated domain-wide access to the service account and you want to impersonate a user account, use thecreate_delegated method of an existing ServiceAccountCredentials object. 

3. Use the authorize method of the Credentials object to apply the necessary credential headers to all requests made by an httplib2.Http instance. 


I would have left this as a comment, but I don't see a way to give documentation feedback on that page.

Thanks again,
Eric

George (Cloud Platform Support)

unread,
Nov 16, 2016, 11:33:40 AM11/16/16
to Google App Engine
Thanks, 

we have submitted a request to bring attention on the weaknesses in the text described above, and to have then the documentation team provide remedy.
Reply all
Reply to author
Forward
0 new messages