If you’re just starting out on Google Cloud for the first time, it’s easy to breeze through the concept of service accounts. Some service accounts, like the App Engine or Compute Engine default service accounts, are even created for you as soon as you turn those features on. After that, it’s pretty easy to create a new service account and then throw whatever permissions and roles you think you need to make things work. But before you go and do that, take a sec to understand these 3 things.
Service Accounts Deserve a Purpose
When you’re working out of a development project, it can be tempting to use a generic all-powerful dev service account with unfettered access to everything via the Editor role. Even some of the default service accounts are created with that access. But you’ve heard of the principle of least privilege right? It’s the thing system administrators have been yelling about for decades whenever someone asks for root access. It means that you should only have access to the minimum permissions you need to do your job. This goes for services accounts too.
Before you even assign roles and permissions, think through what you’re going to use that service account for and make it as specific as possible. Then make that purpose clear to you and anyone else who might manage it later on by adding a clear display name and description. This is a great way to quickly and informally document what a service account is meant to do. You’ll know if a display name and description are good enough if they an answer a few questions by just looking at them:
- What roles could this account probably have assigned?
- What services or APIs could this account probably accessing?
- What applications/users/systems could be using this account?
- What would probably break if I disable this account?
When it comes to assigning roles and permissions, if the service account is coming from a dummy dev project, then it’s not such a big deal if you misconfigure some permissions here and there. But what better place to figure it out than in development? Finding the right IAM roles and permissions for your service accounts can be pretty straightforward, but it can be tricky if your needs don’t fit perfectly into any of the predefined roles. You need to identify what your service account needs — and in some cases what it will not need — to assign the appropriate roles. So as easy as it is, resist the temptation to assign Editor to your service accounts. It’s worth the extra effort to narrow things down early on and give your service account a clear purpose.
Something to try:
If you’ve got some mysterious looking service accounts in your project, update the description and the display name in one shot:
gcloud iam service-accounts update SERVICE_ACCOUNT — display-name “A DECENT DISPLAY NAME” — description “A DESCRIPTIVE DESCRIPTION”
The display name should be short, sweet and to the point. The description has a character limit of 256 so feel free to go nuts.
Service Accounts are Resources Too
As it turns out, a service account is more than just an IAM account. They’re resources too. The same way you might want to limit which people have access to a server or a database, you want to make sure you do that for your service accounts, too.
An easy mistake to make when you want to give someone access to any service account is to grant the permissions on the project IAM policy. For example, by granting the Service Account Token Creator role to a user on a project policy, you are giving them the power to impersonate all service accounts on the project, and by extension, access all resources accessed by those service accounts. That’s a bit much.
Luckily, since service accounts are resources, each one has an IAM policy of its own attached to it. There you can grant service account IAM roles that are binded to users for that specific account instead of project wide. For example, if you add firstname.lastname@example.org as the Service Account Token Creator on email@example.com, then Joe will have that role’s privileges over that service account only. This way, Joe won’t be able to accidentally mess with any of the other important stuff that you don’t want Joe to access. Sorry Joe.
Something to try:
Check the IAM policy for a service account with this gcloud command:
gcloud iam service-accounts get-iam-policy SERVICE_ACCOUNT
By default these are blank. Add a user to the policy like this:
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT --member MEMBER — role=ROLE
The MEMBER will be the user account’s email address and the ROLE will be IAM role you want to grant that user (in the roles/ format). Here’s a list of the service account roles that currently exist.
You don’t always need private keys
When you’re accessing Google Cloud from your local machine, how do you access the service accounts you need? If your answer involves generating a json key every time you need one then you deserve to know that there’s an easier and more secure way.
Instead of using keys, with the right permissions, you can use short-lived credentials. It’s a way of doing basically the same thing with a little less hassle. The Service Account Token Creator role allows a user to generate short-lived credentials on a service account. If you’re accessing Cloud via REST API then you can generate access tokens for that service account. If you’re mostly just running gcloud commands, then you can stick the
--impersonate-service-account flag instead of using a key file.
Something to try:
First, you’ll need to grant the Service Account Token Creator role to the user for the service account they want to use. You can do that with the command I mentioned above:
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT --member MEMBER --role=roles/iam.serviceAccountTokenCreator
With that in place, the user can run gcloud commands as a service account by tacking on the — impersonate-service-account flag along with the service account email address. The same functionality is extended to gsutil if you’re working with GCS buckets, except they’ll use the
-i flag instead, followed by the service account. Easy.
If you want to access the Google Cloud REST API as a service account using an access token, first get an access token for your own account and stick it in an environment variable:
export MYTOKEN=$(gcloud auth print-access-token)
Next, you’ll have to include a request in the form of a json object. Throw that into a file that looks like this:
For this example, I named that file
request.json. This is a pretty barebones version of a request. The “delegates” here are used if you’ve got a conga line (delegation chain) of service accounts that are used to access one another. If that’s not the case, don’t worry about it, you can leave this blank.
As for the scope, this refers to the Oauth 2.0 scope that you’ll need to access certain API’s. What you include here will depend on what you want to do with the service account you’re requesting a token for. A full list of APIs and their corresponding scopes is documented here.
And finally, the lifetime is simply how long you want the token to be good for, in seconds.
Once you’ve got all that, you can request a token with this curl command that will send a POST request to the Google Cloud API:
curl -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com:generateAccessToken -H “Authorization: Bearer $MYTOKEN” -H “Content-Type: application/json; charset=utf-8” -d @request.json
The output here will be the access token for the service account that you can subsequently use to hit up the API as that service account. Tah dah.
More Things About Service Accounts
That’s just 3 things about service accounts but there’s a lot more information on best practices when it comes to making them, managing them, and using them. Here’s a link to the official documentation if you’re into that sort of thing. If you want to learn more about short-lived service account credentials, you can find that right here. If you’re tired of reading, check out a video series on the Google Cloud Tech Youtube channel here.