Detecting Service Account Impersonation on Google Cloud

Posted on Oct 24, 2021
tl;dr: Create Google Logging query looking for protoPayload.methodName="GenerateAccessToken" use protoPayload.authenticationInfo.principalEmail="[SERVICE_ACCOUNT_EMAIL]" to include or exclude service accounts

Introduction

As a follow-up to https://blog.chy.la/posts/using-service-account-impersonation-with-terraform/, I want to share a way to detect the impersonation with Google Cloud Platform native tools.

Ensure sufficient logging is enabled, navigate to the “Audit Logs” configuration https://console.cloud.google.com/iam-admin/audit and enable “Admin Read” and “Data Read” for IAM logs.

Identity and Access Management (IAM) API

iam-logs

The above will allow the token generation events to be logged to Google Cloud logs.

iam-gentoken-event

Detection

Query logs

To find the events we are interested in, you can run the following query; this will find all occurrences, so you will most likely see more than you expect. Use this to have a look if there is anything out of the ordinary.

operation.producer="iamcredentials.googleapis.com"
protoPayload.methodName="GenerateAccessToken"

iam-gentoken-query

Focus on a single account

To focus on a single account event, add this to the query.

protoPayload.authenticationInfo.principalEmail="[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com"

Detecting anomalies

If you can establish a list of service accounts that you know will use the impersonation, you can look for events triggered by service accounts not on your list.

To exclude a single account, you add the following to the query, note the “-” at the start.

-protoPayload.authenticationInfo.principalEmail="[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com"

Helpful script

You can use this script gentoken-generate-list.sh to generate the entries for the service accounts you want to exclude based on a list of service accounts (one per line, no quotes)

gentoken-generate-list.sh

#!/bin/bash
if [ -z "$1" ]
then
  echo "Missing service account list file"
  exit
fi

SA_NAME_LIST=$(cat $1)

for name in $SA_NAME_LIST; do
  echo "-protoPayload.authenticationInfo.principalEmail=\"$name\"";
done

Final query

Below you can see an example of how your query should look with multiple exclusions. Save the query for future use; in the future, we will set up monitoring and alerting using our created query. So stick around for the next part.

iam-gentoken-query-excl