Skip to main content
← Back to list
01Issue
BugShippedExtensionsTeam
Assigneesstack72

Relationships

#1231 @swamp/gcp/calendar: service-account & ADC auth mint cloud-platform-scoped tokens → 403 on Calendar API

Opened by kneel · 7/17/2026· Shipped 7/18/2026

Summary

@swamp/gcp/calendar's service-account (credentialsJson) and ADC auth paths mint OAuth2 access tokens with no scopes requested, so gcloud returns a default cloud-platform-scoped token. The Google Calendar API (calendar/v3) requires a Calendar scope (https://[HOST-1]/auth/calendar or .../calendar.readonly), which cloud-platform does not grant. Every calendar model method therefore fails with 403 Request had insufficient authentication scopes when authenticated via a service account or ADC.

The only auth path that works is supplying a pre-minted, externally-scoped token via the accessToken global arg / GCP_ACCESS_TOKEN env — i.e. the user must obtain the correctly-scoped token outside the extension.

Affected code

models/_lib/gcp.ts:

  • activateServiceAccountFromJson()gcloud auth print-access-token <client_email> is invoked with no --scopes (~line 235).
  • getApplicationDefaultCredentials()gcloud auth application-default print-access-token with no --scopes (~line 266).
  • There is no scopes global argument and no scope env override anywhere in the extension.

This _lib is shared across the whole @swamp/gcp/* family, where cloud-platform scope is correct for genuine infrastructure APIs — but the Calendar Data API is a Workspace/consumer API that needs its own OAuth scope, so this family is the case the generic assumption breaks.

Reproduction

# vault holds a valid service-account JSON with Calendar API access
swamp model create @swamp/gcp/calendar/events gcal-events \
  --global-arg 'credentialsJson=${{ vault.get(gcal, credentialsJson) }}' \
  --global-arg project=<project> \
  --global-arg calendarId=<calendar-id>
swamp model method run gcal-events list --input maxResults=5 --input singleEvents=true
# -> list failed (403): "Request had insufficient authentication scopes"

Confirmed the same service account + calendar succeed when called with a Calendar-scoped token: minting via gcloud auth print-access-token --impersonate-service-account=<sa> --scopes=https://[HOST-1]/auth/calendar.readonly and hitting calendar/v3/calendars/<id>/events directly returns events (HTTP 200). Only the scope differs.

Expected vs actual

  • Expected: with service-account JSON (README auth options 2 & 3, advertised as the vault-friendly path), calendar model methods authenticate and succeed.
  • Actual: they always 403 — the documented SA and ADC auth paths are non-functional for the Calendar API.

Suggested fix

Add an optional scopes global argument (default, for the calendar family, to https://[HOST-1]/auth/calendar) and pass --scopes to both gcloud auth print-access-token and gcloud auth application-default print-access-token. More generally, the codegen could derive default OAuth scopes per API family rather than relying on the implicit cloud-platform default.

Workaround

Mint a Calendar-scoped access token externally (e.g. a service-account JWT bearer-token exchange with scope=.../auth/calendar.readonly, or gcloud ... --scopes=...) and pass it via the accessToken global arg / GCP_ACCESS_TOKEN.

Environment

  • Extension: @swamp/gcp/calendar @ 2026.07.17.1
  • swamp CLI: 20260716.194319.0-sha.df9fc306
  • gcloud: Google Cloud SDK 555.0.0
  • Calendar accessed: a personal calendar shared to the service account with "See all event details"

Upstream repository: https://github.com/swamp-club/swamp-extensions

Environment

  • Extension: @swamp/gcp/calendar@2026.07.17.1
  • swamp: 20260716.194319.0-sha.df9fc306
  • OS: linux (x86_64)
  • Deno: 2.8.3
  • Shell: /bin/zsh
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 4 MOREPR_MERGED+ 1 MORECONTRIBUTOR_NOTIFIED

Shipped

7/18/2026, 11:17:47 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack727/18/2026, 9:29:59 PM
Editable. Press Enter to edit.

stack72 commented 7/18/2026, 11:18:48 PM

Thanks @kneel for reporting this! The fix has been merged and a release is on its way. We appreciate your contribution to swamp.

Sign in to post a ripple.