Providing Credentials to Google Cloud Storage API

It seems it's not so easy to create credentials from a PKCS #12 file with new Google Cloud Client Library as it used to be with the old Cloud Storage JSON API.

The easiest way would be to use JSON format instead as described here, and then use GoogleCredentials#fromStream method to load it:

Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("credentials.json"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

If you still want to use PKCS #12, I believe this would work:

PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(
    SecurityUtils.getPkcs12KeyStore(), new FileInputStream("credentials.p12"), "notasecret", "privatekey", "notasecret");
Credentials credentials = new ServiceAccountCredentials(null, "accountId", privateKey, null, null);
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

The Google Cloud client library for Java allows you to use several auth schemes, but by far the easiest is to take advantage of "Application Default Credentials." These are the credential associated with the service account that your app engine app runs as. If you use the google-cloud Java client library on App Engine or Compute Engine, the following should just work:

import static java.nio.charset.StandardCharsets.UTF_8;


Storage storage = StorageOptions.getDefaultInstance().getService();
BlobId blobId = BlobId.of("bucket", "blob_name");
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();
Blob blob = storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8));

This is probably the simplest way to use auth. If you're running the program locally and not deployed to a Google environment, you can also install the gcloud command line utility and then run gcloud auth application-default login, at which point application default credentials should enable the code above to authenticate as you without any explicit authentication logic.

If you want to programmatically specify a specific service account and have the JSON key file associated with it, you can do so explicitly like so:

Storage storage = StorageOptions.newBuilder()
         new FileInputStream("/path/to/my/key.json")))

You can also specify the path to the service account private key by using the environment variable GOOGLE_APPLICATION_CREDENTIALS. So something like:

$> GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json java MyApp