@@ -145,6 +145,63 @@ There is also the option to pass credentials as a dictionary:
145145
146146.. _oauth-client-id :
147147
148+ For Bots Running inside GCP (Cloud Run, Cloud Functions, Cloud Build): Using Application-Default Credentials
149+ ------------------------------------------------------------------------------------------------------------
150+
151+ When your code runs *inside * Google Cloud, every container, function, or build already
152+ has an **identity **—the service account the runtime is configured to use.
153+ Google injects a short-lived OAuth 2.0 access token for that service account, so you
154+ don’t need to ship or mount a JSON key file. All you have to do is:
155+
156+ 1. :ref: `enable-api-access ` if you haven’t done it yet (Sheets API **and ** Drive API).
157+
158+ 2. Attach a service account to the Cloud Run service / Cloud Function / Cloud Build step.
159+ Share the target spreadsheet with the service account’s **email address **
160+ (e.g. `my-run-sa@project.iam.gserviceaccount.com `) just as you would with a colleague.
161+
162+ 3. Use `google.auth.default() ` to pick up the in-runtime credentials and hand them to gspread:
163+
164+ ::
165+
166+ import google.auth
167+ import gspread
168+
169+ SCOPES = [
170+ "https://www.googleapis.com/auth/spreadsheets",
171+ "https://www.googleapis.com/auth/drive",
172+ ]
173+
174+ creds, _ = google.auth.default(scopes=SCOPES)
175+ gc = gspread.authorize(creds)
176+
177+ sh = gc.open_by_key("1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms")
178+ print(sh.sheet1.get("A1"))
179+
180+ * No `GOOGLE_APPLICATION_CREDENTIALS ` environment variable.
181+ * No JSON key copied into the container.
182+ * Tokens are rotated automatically by the platform.
183+
184+ 4. **Local testing: ** run
185+
186+ ::
187+
188+ gcloud auth application-default login \
189+ --scopes=https://www.googleapis.com/auth/drive,\
190+ https://www.googleapis.com/auth/spreadsheets
191+
192+ to emulate the same Application-Default Credentials flow on your laptop.
193+
194+ .. note ::
195+ If you forget to pass the Sheets **and ** Drive scopes when calling
196+ ``google.auth.default(scopes=...) `` you will get a *403: insufficient
197+ permissions * error even though the code is running on GCP. Always include
198+ both scopes.
199+
200+ .. warning ::
201+ ADC proves *who * your code is, but Sheets access is still controlled by the
202+ spreadsheet’s share list. Make sure the service account is listed there,
203+ otherwise you’ll see ``gspread.exceptions.SpreadsheetNotFound ``.
204+
148205For End Users: Using OAuth Client ID
149206------------------------------------
150207
0 commit comments