Skip to content

Commit 6074285

Browse files
authored
Merge pull request #1553 from davegri/master
Update oauth2.rst with instructions for auth within GCP
2 parents f118a0f + b899e20 commit 6074285

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

.github/workflows/main.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ jobs:
2929
- run: tox -e lint
3030
- run: tox -e py
3131
- run: shopt -s globstar && pyupgrade --py3-only **/*.py # --py36-plus
32-
- run: pip-audit --ignore-vuln PYSEC-2023-228 --ignore-vuln PYSEC-2022-43012 # pip:PYSEC-2023-228 setuptools:PYSEC-2022-43012
32+
- run: pip-audit --ignore-vuln PYSEC-2023-228 --ignore-vuln PYSEC-2022-43012 --ignore-vuln GHSA-5rjg-fvgr-3xxf # pip:PYSEC-2023-228 setuptools:PYSEC-2022-43012 setuptools:GHSA-5rjg-fvgr-3xxf
3333
- run: tox -e build
3434
- run: tox -e doc

docs/oauth2.rst

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
148205
For End Users: Using OAuth Client ID
149206
------------------------------------
150207

0 commit comments

Comments
 (0)