Ga4 auth setup
Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/ga4-pack/skills/ga4-auth-setup
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill ga4-auth-setupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Configure auth for the GA4 Data API — OAuth user credentials for interactive use, or a service account for automation / CI. Pick the right path, set the right scopes, grant the right property-level access. Trigger with "set up GA4 auth", "GA4 service account", "GA4 OAuth", "connect to Google Analytics".
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.7 KB, as published. Nobody here has run it
GA4 Auth Setup
GA4 has two production-grade auth paths. Pick before you start; mixing them mid-flight is the most common failure mode.
| Path | When | Credential file |
|---|---|---|
| Service account | Automation, CI, server-side scripts. Token is long-lived, scoped, revocable. | ~/.config/gcloud/sa-ga4.json (or any path you choose) |
| OAuth user creds | Interactive use, multiple GA4 properties, ad-hoc analyst work. Token refreshes from a ~/.config/gcloud/application_default_credentials.json file. | ADC |
Recommendation: service account for any pipeline / report-runner / agent use. OAuth for a human poking around. Don't share OAuth user creds across machines — that's an audit-trail mess.
Path A — Service account (recommended for automation)
1. Create the SA in GCP
PROJECT=your-gcp-project # the project that will own the SA
SA_NAME=ga4-reader
SA_EMAIL="${SA_NAME}@${PROJECT}.iam.gserviceaccount.com"
gcloud iam service-accounts create "$SA_NAME" \
--display-name="GA4 read-only API access" \
--project="$PROJECT"
# Generate a key (file lands locally)
gcloud iam service-accounts keys create ~/.config/gcloud/sa-ga4.json \
--iam-account="$SA_EMAIL"
2. Grant the SA access to your GA4 property
This is the step everyone forgets. GA4 has property-level access control that lives in the Google Analytics web UI, NOT in GCP IAM. The service account email needs to be added there.
- Open https://analytics.google.com/
- Admin (bottom-left gear) → Property column → Property Access Management
- Add user: paste
$SA_EMAIL(e.g.[email protected]) - Role: Viewer (read-only — anything more is over-privilege)
- Save
3. Enable the Data API in the SA's project
gcloud services enable analyticsdata.googleapis.com --project="$PROJECT"
4. Test the auth round-trip
GOOGLE_APPLICATION_CREDENTIALS=~/.config/gcloud/sa-ga4.json \
PROPERTY_ID=123456789 \
python3 -c "
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import RunReportRequest, DateRange, Metric, Dimension
import os
client = BetaAnalyticsDataClient()
req = RunReportRequest(
property=f'properties/{os.environ[\"PROPERTY_ID\"]}',
date_ranges=[DateRange(start_date='7daysAgo', end_date='today')],
metrics=[Metric(name='activeUsers')],
dimensions=[Dimension(name='date')],
)
resp = client.run_report(req)
for row in resp.rows:
print(row.dimension_values[0].value, row.metric_values[0].value)
"
If you get rows back, auth works. If you get PermissionDenied: 403, the SA isn't added to the property (step 2). If you get Disabled: 403, the API isn't enabled (step 3).
Path B — OAuth user credentials (interactive)
gcloud auth application-default login \
--scopes='https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform'
This opens a browser, you sign in with the Google account that has access to the GA4 property, and a refresh token lands at ~/.config/gcloud/application_default_credentials.json. The Data API client picks it up automatically when GOOGLE_APPLICATION_CREDENTIALS is not set.
Same test as Path A step 4 — just omit the GOOGLE_APPLICATION_CREDENTIALS= prefix.
Finding your PROPERTY_ID
GA4 property IDs are 9-digit numbers (not the G-XXXXX measurement ID, which is for the front-end tracker).
- Open https://analytics.google.com/
- Admin → Property column → Property Details
- Top of the page: Property ID — copy the digits, e.g.
123456789
Secret hygiene
-
Never commit the SA JSON key. Add to
.gitignore:*-sa-*.json sa-ga4.json -
Use SOPS+age for the SA key in any repo it lives in. Per the IS standard:
cd <repo> && sops-init, thenmv ~/.config/gcloud/sa-ga4.json .sops/ga4-sa.json.sopsand decrypt in-process when needed. -
Rotate the SA key annually at minimum:
gcloud iam service-accounts keys list --iam-account=$SA_EMAILshows the active keys; create a new one + delete the old one. -
Grant Viewer-only at the GA4 property level. Editor or Administrator gives the SA the power to delete the property — you don't want a CI pipeline with that blast radius.
Common errors
| Error | Likely cause | Fix |
|---|---|---|
403 PermissionDenied: User does not have sufficient permissions for this property. | SA email not added to GA4 property | Path A, step 2 |
403 SERVICE_DISABLED | Data API not enabled in SA's GCP project | Path A, step 3 |
401 UNAUTHENTICATED | GOOGLE_APPLICATION_CREDENTIALS points to a missing/unreadable file | ls -la $GOOGLE_APPLICATION_CREDENTIALS |
Invalid property ID: G-XXXX | Using measurement ID instead of property ID | See "Finding your PROPERTY_ID" above |
Quota exceeded | Default Data API quota is 200K tokens/day per property | Check Quotas in Cloud Console; raise quota or batch queries with broader date ranges |
Related skills
ga4-data-api-query— once auth works, build the actualrunReportcallga4-bigquery-export— for unsampled event-level data via BigQuery instead of the Data API