Skip to content

Commit 0920706

Browse files
sethvargobitsabhi
andauthored
Update troubleshooting docs for Python (#488)
Closes #487 --------- Co-authored-by: Abhi Srivastava <bits.abhi@gmail.com>
1 parent ba79af0 commit 0920706

File tree

3 files changed

+110
-1
lines changed

3 files changed

+110
-1
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,6 @@ regardless of the authentication mechanism.
322322
"token_format" is "id_token".
323323
324324
325-
326325
<a id="setup"></a>
327326
## Setup
328327

docs/EXAMPLES.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,69 @@ jobs:
187187
run: |-
188188
curl https://myapp-uvehjacqzq.a.run.app \
189189
--header "Authorization: Bearer ${{ steps.auth.outputs.id_token }}"
190+
191+
# Example of using ID token in Python code
192+
- id: 'python-example'
193+
run: |-
194+
python -c "
195+
import os
196+
import requests
197+
198+
# ID token is available as environment variable
199+
id_token = os.environ.get('GOOGLE_ID_TOKEN', '${{ steps.auth.outputs.id_token }}')
200+
201+
# Use the token to invoke a Cloud Run service
202+
response = requests.get(
203+
'https://myapp-uvehjacqzq.a.run.app',
204+
headers={'Authorization': f'Bearer {id_token}'}
205+
)
206+
print(response.text)
207+
"
208+
```
209+
210+
### Using Default Credentials with Scopes in Python
211+
212+
When using Workload Identity Federation with Python libraries, you may need to
213+
add scopes before refreshing credentials:
214+
215+
```yaml
216+
jobs:
217+
job_id:
218+
permissions:
219+
contents: 'read'
220+
id-token: 'write'
221+
222+
steps:
223+
- uses: 'actions/checkout@v4'
224+
225+
- id: 'auth'
226+
uses: 'google-github-actions/auth@v2'
227+
with:
228+
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
229+
service_account: 'my-service-account@my-project.iam.gserviceaccount.com'
230+
231+
- id: 'python-auth'
232+
run: |-
233+
python -c "
234+
from google.auth import default
235+
from google.auth.transport.requests import Request
236+
237+
# Get default credentials
238+
credentials, project = default()
239+
240+
# Add scopes before refreshing for impersonation
241+
credentials = credentials.with_scopes(
242+
['https://www.googleapis.com/auth/cloud-platform']
243+
)
244+
245+
# Refresh to get the token
246+
credentials.refresh(request=Request())
247+
248+
# Now you can use the credentials
249+
print(f'Access token: {credentials.token}')
250+
if hasattr(credentials, 'id_token'):
251+
print(f'ID token: {credentials.id_token}')
252+
"
190253
```
191254

192255
[github-markdown-toc]: https://github.blog/changelog/2021-04-13-table-of-contents-support-in-markdown-files/

docs/TROUBLESHOOTING.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,53 @@ tool like `jq`:
230230
cat credentials.json | jq -r tostring
231231
```
232232

233+
<a name="cannot-refresh"></a>
234+
235+
## Cannot refresh credentials to retrieve an ID token
236+
237+
If you get an error like:
238+
239+
```text
240+
google.auth.exceptions.RefreshError: ('Unable to acquire impersonated credentials', '{"error": {"code": 400, "message": "Request contains an invalid argument.", "status": "INVALID_ARGUMENT"}}')
241+
```
242+
243+
when trying to refresh credentials in Python code to get an ID token, this is
244+
usually because the credentials are missing required scopes. The Google Auth
245+
library requires scopes to be set when refreshing credentials for impersonation.
246+
247+
To fix this issue, add the required scopes before refreshing:
248+
249+
```python
250+
from google.auth import default
251+
from google.auth.transport.requests import Request
252+
253+
credentials, project = default()
254+
255+
# Add scopes before refreshing
256+
credentials = credentials.with_scopes(
257+
["https://www.googleapis.com/auth/cloud-platform"]
258+
)
259+
credentials.refresh(request=Request())
260+
261+
# Now you can access the ID token
262+
print(credentials.id_token)
263+
```
264+
265+
Alternatively, you can use the `token_format` parameter of this action to
266+
generate an ID token directly:
267+
268+
```yaml
269+
- uses: 'google-github-actions/auth@v2'
270+
with:
271+
workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
272+
service_account: ${{ secrets.WIF_SERVICE_ACCOUNT }}
273+
token_format: 'id_token'
274+
id_token_audience: 'https://example.com'
275+
```
276+
277+
This will export the ID token as an environment variable that you can use in
278+
your Python code.
279+
233280
## Organizational Policy Constraints
234281

235282
> **ℹ️ NOTE!** Your Google Cloud organization administrator controls these

0 commit comments

Comments
 (0)