golang / oauth2

Go OAuth2
https://golang.org/x/oauth2
BSD 3-Clause "New" or "Revised" License
5.4k stars 992 forks source link

google: Support querying the scopes supported by the GCE metadata server #102

Open jacobsa opened 9 years ago

jacobsa commented 9 years ago

google.ComputeTokenSource supports fetching tokens from the GCE metadata server, which is great. But there is a user experience issue here: the caller needs a token for a particular source, and if the VM instance was not configured with that source the error will not be discovered until later when a 403 response from the server is received. Worse, the 403 response is probably not clear about what the issue is. It would be much better if we could fail early if the scope we need is not around.

As far as I can tell, the metadata server documentation doesn't say that it's possible to query a list of the supported scopes. But the gsutil source code implies that this is possible.

jacobsa commented 9 years ago

Using the tokeninfo service once a token is obtained would also work, but of course involves remote calls.

rakyll commented 9 years ago

Metadata server provides the scopes, see http://godoc.org/google.golang.org/cloud/compute/metadata#Scopes.

In order to improve the user experience, we have two burdens. ComputeTokenSource is unaware of the scope requirements. Therefore, we can't double check if the instance is configured to have enough permissions for the resources the user will access during the ComputeTokenSource initialization. The other drawback is that we liked the idea of having token sources failing lazily. It allows you to build http.Client instances with inline TokenSource initializations.

client := &http.Client{
    Transport: &oauth2.Transport{
        Source: google.ComputeTokenSource(""),
    },
}

To address the first problem, we may have a more conservative ComputeTokenSource implementation that accepts a list of scopes and fails if the VM instance has not enough rights. I am not a fan of this solution though. The promise of the metadata is to let the user not to deal with the actual scope strings.

Second problem is trivial to solve if we can find a solution to the first. We can return an error from the ComputeTokenSource accessor.

jacobsa commented 9 years ago

Oh, thanks for pointing out Scopes; I didn't realize that the (undocumented) metadata server API I mentioned was already wrapped.