@ssheleg/sheleg-dev 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +172 -0
- package/LICENSE +21 -0
- package/README.md +132 -0
- package/SECURITY.md +63 -0
- package/bin/sheleg-dev.js +99 -0
- package/package.json +45 -0
- package/plugins/sheleg-dev/.claude-plugin/plugin.json +28 -0
- package/plugins/sheleg-dev/skills/ad-tracking/SKILL.md +442 -0
- package/plugins/sheleg-dev/skills/ad-tracking/references/consent-mode.md +257 -0
- package/plugins/sheleg-dev/skills/ad-tracking/references/event-tracking.md +201 -0
- package/plugins/sheleg-dev/skills/ad-tracking/references/gtag-api.md +389 -0
- package/plugins/sheleg-dev/skills/ad-tracking/references/meta-linkedin.md +103 -0
- package/plugins/sheleg-dev/skills/ad-tracking/references/performance-security.md +288 -0
- package/plugins/sheleg-dev/skills/crypto-payments/SKILL.md +384 -0
- package/plugins/sheleg-dev/skills/crypto-payments/references/heleket-provider.md +1357 -0
- package/plugins/sheleg-dev/skills/frontend-performance/SKILL.md +147 -0
- package/plugins/sheleg-dev/skills/frontend-performance/references/accessibility-perf.md +172 -0
- package/plugins/sheleg-dev/skills/frontend-performance/references/css-performance.md +180 -0
- package/plugins/sheleg-dev/skills/frontend-performance/references/nextjs.md +271 -0
- package/plugins/sheleg-dev/skills/google-auth/SKILL.md +275 -0
- package/plugins/sheleg-dev/skills/google-auth/references/adc-and-service-accounts.md +464 -0
- package/plugins/sheleg-dev/skills/google-auth/references/oauth2-web-server.md +615 -0
- package/plugins/sheleg-dev/skills/google-auth/references/sign-in-with-google.md +593 -0
- package/plugins/sheleg-dev/skills/google-auth/references/workload-identity.md +376 -0
- package/plugins/sheleg-dev/skills/google-signin/SKILL.md +121 -0
- package/plugins/sheleg-dev/skills/google-signin/references/full-guide.md +421 -0
- package/plugins/sheleg-dev/skills/stripe-billing/SKILL.md +458 -0
- package/plugins/sheleg-dev/skills/stripe-billing/references/price-integrity.md +201 -0
- package/plugins/sheleg-dev/skills/stripe-billing/references/stripe-agent-toolchain.md +173 -0
- package/plugins/sheleg-dev/skills/stripe-billing/references/subscription-lifecycle.md +294 -0
- package/plugins/sheleg-dev/skills/stripe-billing/references/testing-and-local-dev.md +214 -0
- package/plugins/sheleg-dev/skills/stripe-billing/references/webhook-events.md +211 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
# Application Default Credentials & Service Accounts (Node.js & Python)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Contents
|
|
5
|
+
|
|
6
|
+
- [Table of Contents](#table-of-contents)
|
|
7
|
+
- [ADC Overview](#adc-overview)
|
|
8
|
+
- [ADC Search Order](#adc-search-order)
|
|
9
|
+
- [Setting Up ADC](#setting-up-adc)
|
|
10
|
+
- [Using ADC in Code](#using-adc-in-code)
|
|
11
|
+
- [Service Account Keys (JWT)](#service-account-keys-jwt)
|
|
12
|
+
- [Compute Credentials](#compute-credentials)
|
|
13
|
+
- [Impersonated Credentials](#impersonated-credentials)
|
|
14
|
+
- [Downscoped Client](#downscoped-client)
|
|
15
|
+
- [ID Tokens](#id-tokens)
|
|
16
|
+
- [Environment Variables](#environment-variables)
|
|
17
|
+
|
|
18
|
+
## Table of Contents
|
|
19
|
+
- [ADC Overview](#adc-overview)
|
|
20
|
+
- [ADC Search Order](#adc-search-order)
|
|
21
|
+
- [Setting Up ADC](#setting-up-adc)
|
|
22
|
+
- [Using ADC in Code](#using-adc-in-code)
|
|
23
|
+
- [Service Account Keys (JWT)](#service-account-keys-jwt)
|
|
24
|
+
- [Compute Credentials](#compute-credentials)
|
|
25
|
+
- [Impersonated Credentials](#impersonated-credentials)
|
|
26
|
+
- [Downscoped Client](#downscoped-client)
|
|
27
|
+
- [ID Tokens](#id-tokens)
|
|
28
|
+
- [Environment Variables](#environment-variables)
|
|
29
|
+
|
|
30
|
+
## ADC Overview
|
|
31
|
+
|
|
32
|
+
Application Default Credentials (ADC) automatically finds credentials based on the environment. Best for server-to-server and same-identity-for-all-users scenarios.
|
|
33
|
+
|
|
34
|
+
## ADC Search Order
|
|
35
|
+
|
|
36
|
+
1. **Attached service account** — via GCP metadata server (Compute Engine, Cloud Run, GKE, etc.)
|
|
37
|
+
2. **`gcloud auth application-default login`** — local credential file
|
|
38
|
+
3. **`GOOGLE_APPLICATION_CREDENTIALS`** — env var pointing to a credential JSON file
|
|
39
|
+
|
|
40
|
+
Credential file locations from `gcloud auth application-default login`:
|
|
41
|
+
- **macOS/Linux**: `$HOME/.config/gcloud/application_default_credentials.json`
|
|
42
|
+
- **Windows**: `%APPDATA%\gcloud\application_default_credentials.json`
|
|
43
|
+
|
|
44
|
+
## Setting Up ADC
|
|
45
|
+
|
|
46
|
+
### Local Development
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Login with user credentials (generates local ADC file)
|
|
50
|
+
gcloud auth application-default login
|
|
51
|
+
|
|
52
|
+
# With specific scopes
|
|
53
|
+
gcloud auth application-default login \
|
|
54
|
+
--scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/drive
|
|
55
|
+
|
|
56
|
+
# With service account impersonation
|
|
57
|
+
gcloud auth application-default login \
|
|
58
|
+
--impersonate-service-account=SA_EMAIL@PROJECT.iam.gserviceaccount.com
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Production (GCP)
|
|
62
|
+
|
|
63
|
+
Attach a service account to the resource (Compute Engine VM, Cloud Run service, GKE pod, etc.). No code changes needed — ADC uses the metadata server automatically.
|
|
64
|
+
|
|
65
|
+
### External Environments
|
|
66
|
+
|
|
67
|
+
Set `GOOGLE_APPLICATION_CREDENTIALS` to point to a credential JSON file:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
|
|
71
|
+
# Or a workload identity federation config:
|
|
72
|
+
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/workload-config.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Using ADC in Code
|
|
76
|
+
|
|
77
|
+
### Node.js
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
const {GoogleAuth} = require('google-auth-library');
|
|
81
|
+
|
|
82
|
+
const auth = new GoogleAuth({
|
|
83
|
+
scopes: 'https://www.googleapis.com/auth/cloud-platform'
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const client = await auth.getClient();
|
|
87
|
+
const projectId = await auth.getProjectId();
|
|
88
|
+
const url = `https://dns.googleapis.com/dns/v1/projects/${projectId}`;
|
|
89
|
+
const res = await client.fetch(url);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### With googleapis
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
const {google} = require('googleapis');
|
|
96
|
+
|
|
97
|
+
const auth = new google.auth.GoogleAuth({
|
|
98
|
+
scopes: ['https://www.googleapis.com/auth/cloud-platform']
|
|
99
|
+
});
|
|
100
|
+
const authClient = await auth.getClient();
|
|
101
|
+
google.options({auth: authClient});
|
|
102
|
+
|
|
103
|
+
const storage = google.storage('v1');
|
|
104
|
+
const buckets = await storage.buckets.list({project: projectId});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Python
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
import google.auth
|
|
111
|
+
|
|
112
|
+
credentials, project = google.auth.default()
|
|
113
|
+
|
|
114
|
+
# With specific scopes:
|
|
115
|
+
credentials, project = google.auth.default(
|
|
116
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### With google-api-python-client
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from googleapiclient.discovery import build
|
|
124
|
+
import google.auth
|
|
125
|
+
|
|
126
|
+
credentials, project = google.auth.default(
|
|
127
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
128
|
+
)
|
|
129
|
+
storage = build('storage', 'v1', credentials=credentials)
|
|
130
|
+
buckets = storage.buckets().list(project=project).execute()
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### With authorized requests
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
import google.auth
|
|
137
|
+
import google.auth.transport.requests
|
|
138
|
+
|
|
139
|
+
credentials, project = google.auth.default(
|
|
140
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
141
|
+
)
|
|
142
|
+
request = google.auth.transport.requests.Request()
|
|
143
|
+
credentials.refresh(request)
|
|
144
|
+
|
|
145
|
+
# Use with requests library
|
|
146
|
+
authed_session = google.auth.transport.requests.AuthorizedSession(credentials)
|
|
147
|
+
response = authed_session.get('https://storage.googleapis.com/...')
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Load from file explicitly
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
import google.auth
|
|
154
|
+
|
|
155
|
+
credentials, project = google.auth.load_credentials_from_file(
|
|
156
|
+
'/path/to/credentials.json',
|
|
157
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
158
|
+
)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Service Account Keys (JWT)
|
|
162
|
+
|
|
163
|
+
### Node.js — From JSON Key File
|
|
164
|
+
|
|
165
|
+
```js
|
|
166
|
+
const {JWT} = require('google-auth-library');
|
|
167
|
+
const keys = require('./service-account-key.json');
|
|
168
|
+
|
|
169
|
+
const client = new JWT({
|
|
170
|
+
email: keys.client_email,
|
|
171
|
+
key: keys.private_key,
|
|
172
|
+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
173
|
+
});
|
|
174
|
+
const res = await client.fetch(url);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Node.js — From Environment Variable
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
const {JWT} = require('google-auth-library');
|
|
181
|
+
|
|
182
|
+
const keysEnvVar = process.env['GOOGLE_CREDENTIALS'];
|
|
183
|
+
if (!keysEnvVar) throw new Error('GOOGLE_CREDENTIALS not set');
|
|
184
|
+
const keys = JSON.parse(keysEnvVar);
|
|
185
|
+
|
|
186
|
+
const client = new JWT({
|
|
187
|
+
email: keys.client_email,
|
|
188
|
+
key: keys.private_key,
|
|
189
|
+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Python — From JSON Key File
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from google.oauth2 import service_account
|
|
197
|
+
|
|
198
|
+
credentials = service_account.Credentials.from_service_account_file(
|
|
199
|
+
'service-account-key.json',
|
|
200
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
201
|
+
)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Python — From Dictionary
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
import json
|
|
208
|
+
from google.oauth2 import service_account
|
|
209
|
+
|
|
210
|
+
info = json.loads(os.environ['GOOGLE_CREDENTIALS'])
|
|
211
|
+
credentials = service_account.Credentials.from_service_account_info(
|
|
212
|
+
info,
|
|
213
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
214
|
+
)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Python — With Subject (Domain-Wide Delegation)
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
from google.oauth2 import service_account
|
|
221
|
+
|
|
222
|
+
credentials = service_account.Credentials.from_service_account_file(
|
|
223
|
+
'service-account-key.json',
|
|
224
|
+
scopes=['https://www.googleapis.com/auth/gmail.readonly'],
|
|
225
|
+
subject='user@yourdomain.com'
|
|
226
|
+
)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Service Account Key JSON Structure
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"type": "service_account",
|
|
234
|
+
"project_id": "your-project-id",
|
|
235
|
+
"private_key_id": "key-id",
|
|
236
|
+
"private_key": "-----BEGIN RSA PRIVATE KEY-----\n...",
|
|
237
|
+
"client_email": "sa-name@project-id.iam.gserviceaccount.com",
|
|
238
|
+
"client_id": "123456789",
|
|
239
|
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
240
|
+
"token_uri": "https://oauth2.googleapis.com/token",
|
|
241
|
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
|
242
|
+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Security**: Service account keys are a security risk. Prefer Workload Identity Federation or attached service accounts. If using keys, rotate regularly and restrict access.
|
|
247
|
+
|
|
248
|
+
## Compute Credentials
|
|
249
|
+
|
|
250
|
+
For code running on GCP with an attached service account.
|
|
251
|
+
|
|
252
|
+
### Node.js
|
|
253
|
+
|
|
254
|
+
```js
|
|
255
|
+
const {auth, Compute} = require('google-auth-library');
|
|
256
|
+
|
|
257
|
+
const client = new Compute({
|
|
258
|
+
serviceAccountEmail: 'my-sa@project.iam.gserviceaccount.com' // optional
|
|
259
|
+
});
|
|
260
|
+
const projectId = await auth.getProjectId();
|
|
261
|
+
const res = await client.fetch(url);
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
In most cases, prefer `GoogleAuth` (ADC) over direct `Compute` usage.
|
|
265
|
+
|
|
266
|
+
### Python
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from google.auth import compute_engine
|
|
270
|
+
|
|
271
|
+
credentials = compute_engine.Credentials(
|
|
272
|
+
service_account_email='my-sa@project.iam.gserviceaccount.com' # optional
|
|
273
|
+
)
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
In most cases, prefer `google.auth.default()` (ADC) over direct `compute_engine.Credentials`.
|
|
277
|
+
|
|
278
|
+
## Impersonated Credentials
|
|
279
|
+
|
|
280
|
+
Use IAM Credentials API to impersonate a target service account.
|
|
281
|
+
|
|
282
|
+
### Node.js
|
|
283
|
+
|
|
284
|
+
```js
|
|
285
|
+
const {GoogleAuth, Impersonated} = require('google-auth-library');
|
|
286
|
+
|
|
287
|
+
const auth = new GoogleAuth();
|
|
288
|
+
const sourceClient = await auth.getClient();
|
|
289
|
+
|
|
290
|
+
const targetClient = new Impersonated({
|
|
291
|
+
sourceClient: sourceClient,
|
|
292
|
+
targetPrincipal: 'target-sa@project.iam.gserviceaccount.com',
|
|
293
|
+
lifetime: 30, // seconds
|
|
294
|
+
delegates: [], // optional chain
|
|
295
|
+
targetScopes: ['https://www.googleapis.com/auth/cloud-platform']
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
const res = await targetClient.fetch(url);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Python
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
from google.auth import impersonated_credentials
|
|
305
|
+
import google.auth
|
|
306
|
+
|
|
307
|
+
source_credentials, _ = google.auth.default()
|
|
308
|
+
|
|
309
|
+
target_credentials = impersonated_credentials.Credentials(
|
|
310
|
+
source_credentials=source_credentials,
|
|
311
|
+
target_principal='target-sa@project.iam.gserviceaccount.com',
|
|
312
|
+
target_scopes=['https://www.googleapis.com/auth/cloud-platform'],
|
|
313
|
+
lifetime=300 # seconds (default: 3600)
|
|
314
|
+
)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
The source credential needs the **Service Account Token Creator** role (`roles/iam.serviceAccountTokenCreator`).
|
|
318
|
+
|
|
319
|
+
## Downscoped Client
|
|
320
|
+
|
|
321
|
+
Restrict permissions of a short-lived credential (Cloud Storage only).
|
|
322
|
+
|
|
323
|
+
### Node.js
|
|
324
|
+
|
|
325
|
+
```js
|
|
326
|
+
const {GoogleAuth, DownscopedClient} = require('google-auth-library');
|
|
327
|
+
|
|
328
|
+
const auth = new GoogleAuth({scopes: 'https://www.googleapis.com/auth/cloud-platform'});
|
|
329
|
+
const client = await auth.getClient();
|
|
330
|
+
|
|
331
|
+
const cab = {
|
|
332
|
+
accessBoundary: {
|
|
333
|
+
accessBoundaryRules: [{
|
|
334
|
+
availablePermissions: ['inRole:roles/storage.objectViewer'],
|
|
335
|
+
availableResource: '//storage.googleapis.com/projects/_/buckets/my-bucket',
|
|
336
|
+
availabilityCondition: {
|
|
337
|
+
expression: "resource.name.startsWith('projects/_/buckets/my-bucket/objects/prefix')"
|
|
338
|
+
}
|
|
339
|
+
}]
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
const downscopedClient = new DownscopedClient(client, cab);
|
|
344
|
+
const refreshedAccessToken = await downscopedClient.getAccessToken();
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Python
|
|
348
|
+
|
|
349
|
+
```python
|
|
350
|
+
from google.auth import _default
|
|
351
|
+
from google.auth import credentials as ga_credentials
|
|
352
|
+
import google.auth
|
|
353
|
+
|
|
354
|
+
credentials, _ = google.auth.default(
|
|
355
|
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
# Downscoping is done via the STS API; the Python library exposes it through
|
|
359
|
+
# google.auth.downscoped.DownscopedCredentials (available in google-auth >= 2.0):
|
|
360
|
+
from google.auth import downscoped
|
|
361
|
+
|
|
362
|
+
credential_access_boundary = downscoped.CredentialAccessBoundary(rules=[
|
|
363
|
+
downscoped.AccessBoundaryRule(
|
|
364
|
+
available_resource='//storage.googleapis.com/projects/_/buckets/my-bucket',
|
|
365
|
+
available_permissions=['inRole:roles/storage.objectViewer'],
|
|
366
|
+
)
|
|
367
|
+
])
|
|
368
|
+
|
|
369
|
+
downscoped_credentials = downscoped.DownscopedCredentials(
|
|
370
|
+
source_credentials=credentials,
|
|
371
|
+
credential_access_boundary=credential_access_boundary
|
|
372
|
+
)
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## ID Tokens
|
|
376
|
+
|
|
377
|
+
### Fetching ID Tokens (for Cloud Run / Cloud Functions / IAP)
|
|
378
|
+
|
|
379
|
+
#### Node.js
|
|
380
|
+
|
|
381
|
+
```js
|
|
382
|
+
const {GoogleAuth} = require('google-auth-library');
|
|
383
|
+
|
|
384
|
+
const targetUrl = 'https://cloud-run-1234-uc.a.run.app';
|
|
385
|
+
const auth = new GoogleAuth();
|
|
386
|
+
const client = await auth.getIdTokenClient(targetUrl);
|
|
387
|
+
const res = await client.fetch(targetUrl);
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### Python
|
|
391
|
+
|
|
392
|
+
```python
|
|
393
|
+
import google.oauth2.id_token
|
|
394
|
+
import google.auth.transport.requests
|
|
395
|
+
|
|
396
|
+
request = google.auth.transport.requests.Request()
|
|
397
|
+
target_audience = 'https://cloud-run-1234-uc.a.run.app'
|
|
398
|
+
|
|
399
|
+
# Fetch a raw ID token string
|
|
400
|
+
token = google.oauth2.id_token.fetch_id_token(request, target_audience)
|
|
401
|
+
|
|
402
|
+
# Or get refreshable ID token credentials
|
|
403
|
+
credentials = google.oauth2.id_token.fetch_id_token_credentials(
|
|
404
|
+
target_audience, request=request
|
|
405
|
+
)
|
|
406
|
+
credentials.refresh(request)
|
|
407
|
+
# credentials.token is the ID token
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### Python — Service Account ID Token
|
|
411
|
+
|
|
412
|
+
```python
|
|
413
|
+
from google.oauth2 import service_account
|
|
414
|
+
|
|
415
|
+
credentials = service_account.IDTokenCredentials.from_service_account_file(
|
|
416
|
+
'service-account-key.json',
|
|
417
|
+
target_audience='https://cloud-run-1234-uc.a.run.app'
|
|
418
|
+
)
|
|
419
|
+
request = google.auth.transport.requests.Request()
|
|
420
|
+
credentials.refresh(request)
|
|
421
|
+
# credentials.token is the ID token
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Verifying IAP Headers
|
|
425
|
+
|
|
426
|
+
#### Node.js
|
|
427
|
+
|
|
428
|
+
```js
|
|
429
|
+
const {OAuth2Client} = require('google-auth-library');
|
|
430
|
+
|
|
431
|
+
const client = new OAuth2Client();
|
|
432
|
+
const response = await client.getIapCerts();
|
|
433
|
+
const ticket = await client.verifySignedJwtWithCertsAsync(
|
|
434
|
+
idToken,
|
|
435
|
+
response.pubkeys,
|
|
436
|
+
`/projects/PROJECT_NUMBER/apps/PROJECT_ID`,
|
|
437
|
+
['https://cloud.google.com/iap']
|
|
438
|
+
);
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### Python
|
|
442
|
+
|
|
443
|
+
```python
|
|
444
|
+
from google.oauth2 import id_token
|
|
445
|
+
from google.auth.transport import requests
|
|
446
|
+
|
|
447
|
+
request = requests.Request()
|
|
448
|
+
|
|
449
|
+
decoded = id_token.verify_token(
|
|
450
|
+
iap_jwt,
|
|
451
|
+
request,
|
|
452
|
+
audience=f'/projects/{PROJECT_NUMBER}/apps/{PROJECT_ID}',
|
|
453
|
+
certs_url='https://www.gstatic.com/iap/verify/public_key'
|
|
454
|
+
)
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Environment Variables
|
|
458
|
+
|
|
459
|
+
| Variable | Purpose |
|
|
460
|
+
|----------|---------|
|
|
461
|
+
| `GOOGLE_APPLICATION_CREDENTIALS` | Path to credential JSON file |
|
|
462
|
+
| `GOOGLE_CLOUD_PROJECT` | Default project ID |
|
|
463
|
+
| `GCLOUD_PROJECT` | Alias for project ID |
|
|
464
|
+
| `HTTPS_PROXY` / `https_proxy` | Proxy for HTTPS requests |
|