Skip to content
OpenSmartRoute
Skillv1.0.0

ga4-auth-setup

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 ac

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (skills/.curated/ga4-auth-setup/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill ga4-auth-setup. Copyright stays with the author (MIT).

GA4 Auth Setup

Overview

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.

Prerequisites

  • A Google Cloud project where you can create a service account and enable APIs, or a Google account with access to the target GA4 property.
  • The GA4 property ID (digits only, not the G-... measurement ID).
  • gcloud authenticated to the GCP project; the Python verification also needs the Google Analytics Data API client library installed.

Instructions

Examples

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.

  1. Open https://analytics.google.com/
  2. Admin (bottom-left gear) → Property column → Property Access Management
  3. Add user: paste $SA_EMAIL (e.g. ga4-reader@your-project.iam.gserviceaccount.com)
  4. Role: Viewer (read-only — anything more is over-privilege)
  5. 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).

  1. Open https://analytics.google.com/
  2. Admin → Property column → Property Details
  3. 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, then mv ~/.config/gcloud/sa-ga4.json .sops/ga4-sa.json.sops and decrypt in-process when needed.

  • Rotate the SA key annually at minimum: gcloud iam service-accounts keys list --iam-account=$SA_EMAIL shows 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.

Output

You will have either a service-account key usable by automated clients or local OAuth application-default credentials for interactive use. The verification request prints date and active-user rows when the selected credential can read the specified property.

Error Handling

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

Resources

  • ga4-data-api-query — once auth works, build the actual runReport call
  • ga4-bigquery-export — for unsampled event-level data via BigQuery instead of the Data API

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-ga4-auth-setup/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-ga4-auth-setup.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-ga4-auth-setup",
  "kind": "skill",
  "name": "ga4-auth-setup",
  "description": "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\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "saas",
      "analytics",
      "google-analytics",
      "ga4",
      "auth",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "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\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "skills/.curated/ga4-auth-setup/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/skills/.curated/ga4-auth-setup/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/skills/.curated/ga4-auth-setup/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Bash(gcloud:*),",
      "Bash(curl:*),",
      "Bash(jq:*),",
      "Bash(python3:*),",
      "Bash(ls:*)"
    ],
    "license": "MIT"
  },
  "instructions": "# GA4 Auth Setup\n\n## Overview\n\nGA4 has two production-grade auth paths. Pick before you start; mixing them mid-flight is the most common failure mode.\n\n| Path | When | Credential file |\n|---|---|---|\n| **Service account** | Automation, CI, server-side scripts. Token is long-lived, scoped, revocable. | `~/.config/gcloud/sa-ga4.json` (or any path you choose) |\n| **OAuth user creds** | Interactive use, multiple GA4 properties, ad-hoc analyst work. Token refreshes from a `~/.config/gcloud/application_default_credentials.json` file. | ADC |\n\n**Recommendation:** service account for any pipeline / re",
  "cost": {
    "context_tokens": 1473
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-ga4-auth-setup/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.