Search code examples
tokengoogle-cloud-storagebucket

Google Cloud Storage - Limit Access Token to Single Bucket


I have a server application that stores user files in Google Cloud Storage. Clients request files from the server, and it returns a URL that points to the file in the Google Cloud Storage. The server also returns an Access Token so that the client can download the file.

I have found that the Access Token that my server is generating can be used to download any file that I have stored in Google Cloud Storage. I would prefer to generate an Access Token that is only valid for a single Bucket. Is that possible? Is this the correct approach for limiting client access to Storage?

Here's how I'm generating the access token:

private Credential authorize (Set<String> scopes)
{
    GoogleCredential credential = null;

    try
    {
        if (m_HttpTransport == null)
        {
            m_HttpTransport = GoogleNetHttpTransport.newTrustedTransport ();
        }

        File p12File = new File ("key.p12");

        credential = new GoogleCredential.Builder ()
                           .setTransport (m_HttpTransport)
                           .setJsonFactory (JacksonFactory.getDefaultInstance ())
                           .setServiceAccountId ("foo@developer.gserviceaccount.com")
                           .setServiceAccountScopes (scopes)
                           .setServiceAccountPrivateKeyFromP12File (p12File).build ();
    }
    catch (Exception ex)
    {
        m_Logger.log (Level.SEVERE, null, ex);
    }

    return credential;
}

private String retrieveReadOnlyAccessToken ()
        throws IOException
{
    Set<String> scopes = new HashSet<> ();

    scopes.add (StorageScopes.DEVSTORAGE_READ_ONLY);

    Credential credential = authorize (scopes);

    credential.refreshToken ();

    return credential.getAccessToken ();
}

Solution

  • For your use case (a limited access to a resource) I would suggest using Signed URLs. See documentation here.

    The typical way to address this use case is to provide a signed URL to a user, which allows the user access to that resource for a limited time. Anyone who knows the URL can access the resource for a limited time.

    In case of Signed URLs, your users do not even have to own an Google account to read/write/delete GCS resources and access control is completely managed by your application.