Ian De La Cruz Blog

Working with Google Service Accounts in Ruby

In this post, I’ll be talking about how to work with a Google Service Account, using Ruby, without the Ruby Client library.

The inspiration for this post is my personal struggle with using Google Service Account without the client library. I wasn’t using the official client library because of the fact that it was in ALPHA. Being a project that I’ll only be starting, I can’t risk having the library suddenly change.

I’ll be talking about 2 main points: the creation of the JWT itself and errors I encountered. I won’t be talking about what JWTs are in this post. I recommend you go to Auth0 for this.

Creating the JWT

The documentation for Service Accounts had a pretty good explanation of what was going on how to create the token using HTTP. But, for someone who only has a rudimentary understanding of what a JSON Web Token is, the documentation can become confusing.

This first part was talking about forming the JWT header. Don’t worry about this. We’ll let the Ruby-JWT library do this for us when we are already encoding.

The second part talks about creating a claim set. This is a basic JSON Object. There is a description for each key of the object in the documentation. This is what I did in Ruby:

The third part talks about signing the JWT. This is where it gets pretty messy. To do this, I created a method that generates the token for me. It basically adds the headers, claim body, and signature for you.

As you can see, I was passing a PEM file to OpenSSL:PKey::RSA.new. This can be found in the documentation. This JWT is now a proper JWT to be passed to Google servers. This is what I did to do this:

To explain the snippet above, what I first do is create a connection to the auth server. Then, I generate the JWT. Since the url has to be URL-encoded, I passed the grant type to CGI::escape. I, then, append the jwt to the grant-type. Essentially, the body is of this form: grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<jwt here>

Google’s response would now contain the Token which you will use to talk to its servers.

This looks easy and all, but I would like to share some of the errors I encountered to figure out everything I have described above.

Errors

When working with the OpenSSL::PKey::RSA, you must pass it a PEM file. This is to avoid a OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key:: nested asn1 error. What I did was pass the file location of the PEM file, relative to root directory.

Now, a PEM file is not provided for by Google. Instead, the developers’ console gives you either a P12 file or JSON file. I usually go for the JSON file. What I learned, though, was that I can use the P12 file to create a PEM file. I found the solution here.

If you don’t want to open any other page, the command: openssl pkcs12 -in path.p12 -out newfile.key.pem -nocerts -nodes.

Conclusion

Hopefully, you’ve learned a thing or two about how to use Service Accounts for your own applications. The methods I’ve outlined should be transferrable to other languages. I would, however, recommend that you use Google’s provided client libraries when you can.

If you have any questions, you can ping me on Twitter @RIanDeLaCruz10. Have a Great Day and Merry Christmas!