GCP Service Account Key Analyzer

Read a Google Cloud service account key: which account and project it belongs to, the key id you need to revoke it, and why it is the one credential in GCP that never expires. Nothing is uploaded and the private key is never echoed back.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Analyze the key. Nothing leaves this tab.

Wanted a different tool?

  • GCP IAM Policy Analyzer because the key itself says nothing about what the account can do, and the roles bound to it are where that lives.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A key for the App Engine default account

The default service accounts hold roles/editor on the project, so this file is a permanent editor credential for everything in it, including the ability to mint more keys.

{
  "type": "service_account",
  "project_id": "my-project",
  "private_key_id": "0123456789abcdef0123456789abcdef01234567",
  "private_key": "-----BEGIN PRIVATE KEY-----\nREDACTED\n-----END PRIVATE KEY-----\n",
  "client_email": "my-project@appspot.gserviceaccount.com",
  "client_id": "123456789012345678901",
  "token_uri": "https://oauth2.googleapis.com/token"
}

Workload identity federation, which is the replacement

An external account config carries no private key at all. Credentials are exchanged at runtime for short-lived tokens, so there is nothing in the file that works on its own.

{
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/1/locations/global/workloadIdentityPools/gh/providers/gh",
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
  "token_url": "https://sts.googleapis.com/v1/token",
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/svc@my-project.iam.gserviceaccount.com:generateAccessToken"
}

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Creating a downloadable key at all

    It is the only credential in Google Cloud with no expiry and no rotation. Copying it is undetectable, and every copy keeps working until somebody explicitly deletes it.

    Instead:Workload identity federation for anything outside Google Cloud, and an attached service account for anything inside it. Both hand out hour-long tokens instead.

  2. Creating a key for a default service account

    The App Engine and Compute Engine defaults hold `roles/editor` on the project, so that key is a permanent editor credential for everything in it, including the ability to mint more keys.

    Instead:Create a dedicated service account with only the roles it needs, and remove `roles/editor` from the defaults.

  3. Rotating everything after a suspected leak

    `private_key_id` identifies exactly which key was used in the audit logs, so the blast radius is usually one key rather than all of them.

    Instead:Read the key id from the logs and delete that one with `gcloud iam service-accounts keys delete`.

  4. Passing the key through an environment variable as raw PEM

    The newlines are escaped inside the JSON as issued. A round trip through an environment variable unescapes them, and the result is an invalid key error that points at nothing useful.

    Instead:Keep the file byte-for-byte, or base64 it if it has to be a single-line value.

  5. Assuming a key that has been shared can be made safe again

    There is no revocation short of deleting the key, and no way to know how many copies exist.

    Instead:Delete it and issue a new one, or better, remove the need for one.

The only Google Cloud credential with no expiry

Everything else in GCP hands you a token that lasts an hour. A downloaded service account key works until somebody explicitly deletes it, and the usual way anyone discovers one leaked is a bill or a breach notification.

There is no rotation and no lifetime

A key file is a private key in a JSON document. Nothing expires it, nothing rotates it, and copying it is undetectable. It ends up in a repository, a CI variable, a laptop, a Slack message and a support ticket, and every one of those copies keeps working. Google's own recommendation is not to create them.

What to use instead, by where the workload runs

Inside Google Cloud, attach a service account to the VM, the GKE workload or the Cloud Run service and the metadata server issues short-lived tokens with nothing to leak. Outside it, workload identity federation exchanges an existing identity, from GitHub Actions, AWS or any OIDC provider, for a short-lived Google token. Both remove the file entirely rather than protecting it better.

type: service_account    a permanent private key
type: external_account   federation, no secret in the file

A key for a default service account is a project-wide credential

The App Engine and Compute Engine default service accounts are granted roles/editor when a project is created. A key for one of those is therefore a permanent editor credential for the whole project, including the ability to create more service accounts and more keys. Remove roles/editor from the defaults and never create keys for them.

private_key_id is what you revoke

It is the value that appears in audit logs and in the console's key list, so it is how you tell which key was used and which one to delete. Knowing it turns an incident from rotating everything into deleting one key.

gcloud iam service-accounts keys delete KEY_ID \
  --iam-account=SA_EMAIL

Escaped newlines matter

As Google issues the file the PEM newlines are escaped inside the JSON string. Real newlines mean the value has been through something that unescaped it, usually an environment variable round trip, and that is where most invalid key errors come from. If it has to go through an environment variable, base64 it rather than pasting the PEM.

What this cannot see, and what it does with what you paste

Everything happens in this tab. The file is parsed in your browser, nothing is uploaded, nothing is stored, and the private key material is never printed back into the output, which is deliberate so a screenshot of the result is not itself a leak. It cannot tell you what the service account can DO, because that lives in IAM policies rather than in the key, and it cannot tell you whether the key is still active. Treat any key that has been pasted somewhere less careful than this as compromised, and delete it.