Skip to content

Authentication Reference

WebbinRoot edited this page May 9, 2026 · 1 revision

Authentication Reference

If you are new to GCPwn, read Getting Started first.

This page is the canonical authentication reference for GCPwn. It covers each auth mode, setup patterns, startup syntax, and in-workspace credential operations.

Table of Contents

Auth Modes at a Glance

Auth Type Supported in GCPwn Typical Credential Source Rotation Model Common Use
ADC (adc) Yes Local Google auth defaults / ADC JSON Refresh-token backed OAuth flow Standard operator workflow with gcloud. Can result in OAuth2 tokens for next row being created, but has refresh mechanism backing.
OAuth2 token (oauth2) Yes Direct bearer token input Short-lived bearer token Testing standalone delegated/harvested access tokens identified (ex ya29.a0AfH6SM...)
Service account key (service-acc-key / service) Yes Service account JSON key file Long-lived key unless rotated Service-account identity operations

GCPwn Startup Commands

At startup, add credentials with one of the following patterns:

  • adc
adc <credential_name> [--filepath-to-adc <adc_json_path>] [--tokeninfo]
  • oauth2
oauth2 <credential_name> --token <access_token> [--tokeninfo]
  • service-acc-key
service-acc-key <credential_name> --service-file <service_account_json_path>

Quick startup examples:

adc corp-adc --filepath-to-adc ~/.config/gcloud/application_default_credentials.json
oauth2 redteam-token --token ya29.a0AfH6SM...
service-acc-key app-sa --service-file /tmp/app-sa.json

You can also select an existing credential by name/index, or press Enter to continue without loading credentials.

After Startup

  • creds list
  • creds swap [<credname>]
  • creds info [<credname>] [--csv]
  • creds tokeninfo [<credname>]
  • creds update [<credname>] --type <adc|oauth2|service> [credential flags...] [--assume]

Add new credentials at startup (adc, oauth2, service-acc-key), then use creds update to refresh stored credentials.

For full workspace command coverage, see Workspace Instructions.

Tokeninfo Quick Note

BOTH user and service account access tokens can exist, but the token string by itself does not clearly identify the principal behind it (you can't base64 decode it like a JWT; its "opaque").

The --tokeninfo flag and creds tokeninfo command call Google’s /tokeninfo endpoint to return token metadata (for example, email and scopes) given an access token. This helps enrich your session data, details who the token belongs to if you don't have that context, and maps the current credential to the correct IAM identity during enumeration.

Tokeninfo Endpoint

https://oauth2.googleapis.com/tokeninfo?access_token=<ACCESS_TOKEN>

GCPwn examples

# When adding creds
oauth2 redteam-token --token ya29.a0AfH6SM... --tokeninfo
# While in workspace
creds tokeninfo redteam-token

References

Application Default Credentials (ADC)

ADC Overview

Application Default Credentials (ADC) is not a single credential. It is Google’s credential discovery mechanism used by SDK-backed tooling to automatically locate usable auth material.

In GCPwn, this maps to google.auth.default() behavior. The library resolves the active credential source for you (local user ADC, service account material, workload identity config, or metadata-attached identity).

Common ADC lookup order in operator workflows as follows, so unset GOOGLE_APPLICATION_CREDENTIALS if that is potentially causing you issues as we focus on 2 for now:

  1. GOOGLE_APPLICATION_CREDENTIALS environment variable
  2. Local ADC file from gcloud auth application-default login

If you are operating interactively, "ADC" usually maps to user-backed OAuth credentials (aka. username/password login) which is what we will consider here.

ADC TLDR Setup

# Browser-based user auth + local ADC file
gcloud auth application-default login

# Recommended to avoid project-context confusion
gcloud config set project <project_ID>

# After starting gcpwn choose ADC as your option with your crednmae. Default ADC file location is usually ~/.config/gcloud/application_default_credentials.json but you can specify path to another file if needed
gcpwn> adc <credname> [--filepath-to-adc ~/.config/gcloud/application_default_credentials.json]

ADC Field Mapping

Field Required Source
credential_name Yes Operator-defined alias
--filepath-to-adc No ADC JSON file path
--tokeninfo No Query Google tokeninfo metadata endpoint

ADC Deep Dive/Setup

1. Know which gcloud login matters

  • gcloud auth login: authenticates the gcloud CLI user context. i.e. you can make further gcloud commands at command line as that user.
  • gcloud auth application-default login: creates ADC material for SDK/client-library usage. i.e. you can make further SDK calls as the user you authenticated as

For GCPwn, application-default login is the key requirement because GCPwn relies on SDK-backed authentication resolution.

2. Start ADC browser authentication

> gcloud auth application-default login
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=76408[REDACTED]

Sign in through the browser flow:

Sign-In-1 Sign-In-2 Sign-In-3 Sign-In-4

3. Confirm ADC file creation

After redirecting back to localhost, Google writes your ADC credential file under .config/gcloud:

Credentials saved to file: [/home/kali/.config/gcloud/application_default_credentials.json]

These credentials will be used by any library that requests Application Default Credentials (ADC).

Inspect the file. Note there is a client_id, client_secret, and refresh_token. These can be ingested as we will see by a python SDK/code for GCP to auto gen a token and make subsequent API calls.

# cat /home/kali/.config/gcloud/application_default_credentials.json                                                     
{
  "account": "",
  "client_id": "764086[REDACTED].apps.googleusercontent.com",
  "client_secret": "d-FL[REDACTED]",
  "refresh_token": "1//01i[REDACTED]",
  "type": "authorized_user",
  "universe_domain": "googleapis.com"
} 

4. Set project context explicitly

The ADC file itself does not set your intended project target. Set project context explicitly to avoid issues with gcpwn:

# Set the project to avoid issues down the road
gcloud config set project <PROJECT_ID>

5. Understand refresh token vs access token behavior

In the ADC file we saw a client_id, client_secret, refresh_token but no access token to send directly to a GCP API. You will typically see a refresh token, not a long-lived pre-generated access token.

At runtime, GCPwn loads the ADC material, uses the material to request and store an access token, uses that access token for subsequent calls, and reuses stored refresh material (ex. refresh_token) for future auto-refresh attempts when the token is invalid.

6. Load ADC into GCPwn and validate with tokeninfo

After startup, load ADC. Note this was successful and gcpwn in the background requested and stored an access token as we will see in the next step.

What you will notice is the final access token (ya29...) is opaque, or you can't decode it locally. Same with gpwn. If you want to decode the opaque access token to better enrich your data then run creds tokeninfo to inspect token metadata (email/scopes) from Google’s tokeninfo endpoint:

Welcome to your workspace! Type 'help' or '?' to see available commands.

[-] No creds found
Submit the name or index of an existing credential from above, or add NEW credentials via:
  [1] adc      <credential_name> [--filepath-to-adc <adc_json_path>] [--tokeninfo]
  [2] oauth2   <credential_name> --token <access_token> [--tokeninfo]
  [3] service-acc-key <credential_name> --service-file <service_account_json_path>

Tip: `--tokeninfo` queries Google's tokeninfo endpoint to capture scope/email for OAuth-style creds.

Input: adc starting_user_token
[*] Project ID of credentials is: <PROJECT_ID>
[*] Credentials successfully added
[*] Loading in ADC credentials...
[*] Attempting to refresh the credentials using the stored refresh token. Note this is normal for brand new OAuth2 credentials added/updated.
[*] Credentials successfully refreshed...
[*] Credentials successfully stored/updated...
[*] Proceeding with up-to-date ADC credentials for starting_user_token...
[*] Loaded credentials starting_user_token
(<PROJECT_ID>:starting_user_token)> creds tokeninfo
[*] Checking credentials against https://oauth2.googleapis.com/tokeninfo endpoint...
[*] Succeeded in querying tokeninfo. The response is shown below:
{
  "azp": "764086[TRUNCATED]",
  "aud": "764086[TRUNCATED]",
  "sub": "1057[TRUNCATED]",
  "scope": "email https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.login https://www.googleapis.com/auth/userinfo.email openid",
  "exp": "1778303317",
  "expires_in": "3512",
  "email": "[REDACTED_EMAIL]",
  "email_verified": "true",
  "access_type": "offline"
}

7. Verify session storage behavior

If you want to see the actual access token generated, you can inspect databases/sessions.db to confirm that GCPwn stored session credential material, including refreshed access-token state:

# sqlite3 databases/sessions.db 
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .tables
session          session_actions
sqlite> SELECT workspace_id, credname, credtype, email, default_project FROM session;
1|starting_user_token|adc|[REDACTED_EMAIL]|<PROJECT_ID>

Session credential payload (formatted):

{
  "token": "ya29.a0AQvPyI[REDACTED]",
  "refresh_token": "1//01in[REDACTED]",
  "token_uri": "https://oauth2.googleapis.com/token",
  "client_id": "76408[TRUNCATED]",
  "client_secret": "d-FL[REDACTED]",
  "universe_domain": "googleapis.com",
  "account": "",
  "expiry": "2026-05-09T05:08:36.410200Z"
}

8. Optional manual workflow for access token generation (without GCPwn)

If needed, you can manually:

  1. exchange refresh token material for an access token
  2. send that access token to /tokeninfo
  3. Use that access token as a token input credential in gcpwn covered in the next section

Generate Access Token

# curl request
CLIENT_ID="<CLIENT_ID>"
CLIENT_SECRET="<CLIENT_SECRET>"
REFRESH_TOKEN="<REFRESH_TOKEN>"

curl -sS -X POST "https://oauth2.googleapis.com/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=${CLIENT_ID}" \
  --data-urlencode "client_secret=${CLIENT_SECRET}" \
  --data-urlencode "refresh_token=${REFRESH_TOKEN}" \
  --data-urlencode "grant_type=refresh_token"

# curl example
CLIENT_ID="764[TRUNCATED]"
CLIENT_SECRET="d-FL[REDACTED]"
REFRESH_TOKEN="1//01i[REDACTED]"

curl -sS -X POST "https://oauth2.googleapis.com/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=${CLIENT_ID}" \
  --data-urlencode "client_secret=${CLIENT_SECRET}" \
  --data-urlencode "refresh_token=${REFRESH_TOKEN}" \
  --data-urlencode "grant_type=refresh_token"
{
  "access_token": "ya29.a0AQvPyIOFt[REDACTED]",
  "expires_in": 3599,
  "scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/sqlservice.login openid https://www.googleapis.com/auth/cloud-platform",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUz[REDACTE]"
}  

Send Token to /tokeninfo

# curl request
>curl "https://oauth2.googleapis.com/tokeninfo?access_token=<token>"

#example 
> curl "https://oauth2.googleapis.com/tokeninfo?access_token=ya29.a0AQvPy[REDACTED]"
{
  "azp": "7640[TRUNCATED].com",
  "aud": "7640[TRUNCATED].com",
  "sub": "1057[TRUNCATED]",
  "scope": "email https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.login https://www.googleapis.com/auth/userinfo.email openid",
  "exp": "1778303317",
  "expires_in": "3188",
  "email": "[REDACTED_EMAIL]",
  "email_verified": "true",
  "access_type": "offline"
}

9. Refresh Creds

Like I showed before, gcpwn ALSO stores the refresh material from ADC. So if your access token expires and the tool doesn't auto-refresh it, or you want to refresh your token sooner, you can do that as shown below assuming your adc creds have not changed

(<PROJECT_ID>:starting_user_token)> creds update starting_user_token --type adc --assume
[*] Project ID of credentials is: <PROJECT_ID>
[*] Credentials successfully added
[*] Loading in ADC credentials...
[*] Attempting to refresh the credentials using the stored refresh token. Note this is normal for brand new OAuth2 credentials added/updated.
[*] Credentials successfully refreshed...
[*] Credentials successfully stored/updated...
[*] Proceeding with up-to-date ADC credentials for starting_user_token...
[*] Loaded credentials starting_user_token

OAuth2 Token

OAuth2 Overview

OAuth2 tokens can come from multiple sources in GCP for both users and service accounts. They typically look like ya29.... These might be from a local user:<email> on the system or a serviceAccount:<email> attached to something like a compute instance for example (classic SSRF).

If you recover a standalone OAuth2 token, you can load it directly into GCPwn and begin making API calls immediately.

Important caveat: a standalone access token is short-lived and cannot be auto-refreshed by itself unless you also have refresh material. Review the instructions to refresh the <credname> at the end of this section

OAuth2 TLDR Setup

# Obtain a valid OAuth2 access token (ex. `ya29...`)

# Pass the token into GCPwn
oauth2 redteam-token --token ya29.a0AfH6SM...

OAuth2 Field Mapping

Field Required Source
credential_name Yes Operator-defined alias
--token Yes OAuth2 bearer token
--tokeninfo No Query Google tokeninfo metadata endpoint

OAuth2 Deep Dive/Setup

1. Decide which OAuth2 token source you have

There are a lot of paths that can lead to an OAuth token being recovered. Two common operator paths are:

  1. user token via gcloud auth login (or recovered local gcloud token cache)
  2. service-account token via instance metadata (IMDS)

2a. User path (gcloud auth login)

Run login and complete browser auth:

# gcloud auth login
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=3255[REDACTED]

You are now logged in as [REDACTED_EMAIL].
Your current project is [<PROJECT_ID>].  You can change this setting by running:
  $ gcloud config set project PROJECT_ID
2b Inspect local gcloud token stores

gcloud auth login commonly creates/updates token stores under ~/.config/gcloud, including:

  • access_tokens.db (short-lived access tokens)
  • credentials.db (credential profile material that may include refresh-backed fields)
$ ls -lart /home/kali/.config/gcloud/
total 72
[TRUNCATED]
-rw-------  1 kali kali     5 May  9 01:03 gce
-rw-r--r--  1 kali kali 12288 May  9 01:03 default_configs.db
-rw-------  1 kali kali 12288 May  9 01:03 access_tokens.db
-rw-------  1 kali kali 12288 May  9 01:03 credentials.db
drwxrwxr-x  3 kali kali  4096 May  9 01:03 legacy_credentials
$ sqlite3 /home/kali/.config/gcloud/access_tokens.db
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> PRAGMA table_info(access_tokens);
0|account_id|TEXT|0||1
1|access_token|TEXT|0||0
2|token_expiry|TIMESTAMP|0||0
3|rapt_token|TEXT|0||0
4|id_token|TEXT|0||0
sqlite> SELECT * FROM access_tokens;
[REDACTED_EMAIL]|ya29.a0[TRUNCATED]|2026-05-09 06:03:55.997030||eyJhbG[TRUNCATED]

credentials.db can also contain refresh/token profile material:

$ sqlite3 /home/kali/.config/gcloud/credentials.db
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .tables
credentials
sqlite> SELECT * FROM credentials;
[REDACTED_EMAIL]|{
  "client_id": "32555940559.apps.googleusercontent.com",
  "client_secret": "Zms[REDACTED]",
  "refresh_token": "1//01p9Q[REDACTED]",
  "revoke_uri": "https://oauth2.googleapis.com/revoke",
  "scopes": [
    "openid",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/cloud-platform",
    "https://www.googleapis.com/auth/appengine.admin",
    "https://www.googleapis.com/auth/sqlservice.login",
    "https://www.googleapis.com/auth/compute",
    "https://www.googleapis.com/auth/accounts.reauth"
  ],
  "token_uri": "https://oauth2.googleapis.com/token",
  "type": "authorized_user",
  "universe_domain": "googleapis.com"
}

3a. Service-account path (IMDS on compute)

On a compute instance with an attached service account, IMDS can return a service-account OAuth2 token:

hacking3465@instance-20260509-053642:~$ curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/660172346949-compute@developer.gserviceaccount.com/token
{"access_token":"ya29.c.c0AZ[REDACTED]","expires_in":3599,"token_type":"Bearer"}

4. Load OAuth token into GCPwn

Whichever route you followed plug the OAuth2 credential into GCPwn and set project the project after loading the token:

Input: oauth2 my_compute_oauth_token --token "ya29.c.c0AZ4bNpad[REDACTED]"
[*] Project ID of credentials is: Unknown
[*] Credentials successfully added
Loading in OAuth2 token. Note it might be expired based on how long its existed...
[*] Loaded credentials my_compute_oauth_token
(Unknown:my_compute_oauth_token)> modules run enum_cloudstorage
(Unknown:my_compute_oauth_token)> projects set <PROJECT_ID>
(<PROJECT_ID>:my_compute_oauth_token)> modules run enum_cloudstorage
[*] Target project 1/1: <PROJECT_ID>
[**] Reviewing test_[TRUNCATED]
[*] GCPwn found 1 Buckets in project <PROJECT_ID>
[*] TEXT OUTPUT (<PROJECT_ID>)
Resource Type: Buckets
Columns: name | location | blobs
Rows: showing 1 of 1
[TRUNCATED]

5. Understand refresh behavior

A standalone OAuth2 token cannot be refreshed unless you also have refresh material.
When a token expires, obtain a new token for the same principal and update the existing credential name:

creds update redteam-token --type oauth2 --token ya29.NEWTOKEN... --assume

Service Account Key

Service Account Key Overview

Service accounts are included in IAM bindings throughout GCP environments. Users can generate long-lasting static JSON API keys for service accounts which can then be used in various tools/SDKs to make API calls as the service account.

Service Account Key TLDR Setup

# Obtain a service account JSON key file
# (usually via IAM -> Service Accounts -> Keys)

# Load the key into GCPwn at startup
service-acc-key app-sa --service-file /tmp/app-sa.json

Service Account Key Field Mapping

Field Required Source
credential_name Yes Operator-defined alias
--service-file Yes Service account JSON key file path

Service Account Key Deep Dive/Setup

1. Create or recover a service account key file

Service account auth requires a JSON key file. Operators usually obtain this from IAM key-management workflows (or recover it from an accessible host/workspace path).

Typical file shape:

{
  "type": "service_account",
  "project_id": "example-project",
  "private_key_id": "[REDACTED]",
  "private_key": "-----BEGIN PRIVATE KEY-----\n[REDACTED]\n-----END PRIVATE KEY-----\n",
  "client_email": "sa-name@example-project.iam.gserviceaccount.com",
  "client_id": "[REDACTED]",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token"
}

2. Secure the key file on disk

Treat this file like a password-equivalent secret.

chmod 600 /tmp/app-sa.json

3. Load the key into GCPwn

At startup:

service-acc-key app-sa --service-file /tmp/app-sa.json

4. Set project context and run a quick validation call

The tool should auto-detect the project based off the project_id field in the key. However, depending on the key/project context, explicitly setting the active project might be required:

(Unknown:app-sa)> projects set <PROJECT_ID>
(<PROJECT_ID>:app-sa)> modules run enum_cloudstorage

5. Refresh

Service account keys don't auto-refresh like the ADC example. If you recover another keyf or the same principle you can update a credname with

creds update app-sa --type service --service-file /tmp/app-sa.json --assume

Auth Operational Notes

  • creds info prints current credential summary and discovered permission view.
  • creds info --csv exports flattened permission rows for review/filtering.
  • creds tokeninfo works for OAuth-style creds and is metadata enrichment only.
  • creds set updates stored email/project metadata for a credential context.

Common Auth Errors

Error Pattern Meaning Remediation
Must supply token via --token OAuth2 mode called without token Re-run with --token <access_token>
File ... does not exist ADC/service file path invalid Verify path and re-run
ADC not setup No default ADC available Run gcloud auth application-default login and gcloud config project set <PROJECT_ID> before starting gcpwn
Can't perform tokeninfo operations with a service account token tokeninfo used with service-account creds Use tokeninfo for OAuth-style creds only
Credential refresh errors Expired/invalid refresh state Your crednetials/token are expired. Re-authenticate and run creds update if you have a new token to replace your current expired session with

Source References

Clone this wiki locally