0
# Key Management
1
2
Comprehensive management of reCAPTCHA keys for different platforms including web applications, Android apps, and iOS apps. Key management operations handle the full lifecycle from creation and configuration through updates, deletion, and migration from legacy reCAPTCHA versions.
3
4
## Capabilities
5
6
### Create Key
7
8
Creates a new reCAPTCHA key with platform-specific settings. Keys can be configured for web, Android, or iOS platforms with appropriate security settings and domain/package restrictions.
9
10
```python { .api }
11
def create_key(
12
request: CreateKeyRequest = None,
13
*,
14
parent: str = None,
15
key: Key = None,
16
retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
17
timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
18
metadata: Sequence[Tuple[str, str]] = ()
19
) -> Key:
20
"""
21
Creates a new reCAPTCHA Enterprise key.
22
23
Args:
24
request: The request object for creating a key
25
parent: Required. The name of the project in format 'projects/{project}'
26
key: Required. Key configuration and settings
27
retry: Retry configuration for the request
28
timeout: Timeout for the request in seconds
29
metadata: Additional metadata for the request
30
31
Returns:
32
Key: The created key with generated name and settings
33
34
Raises:
35
google.api_core.exceptions.InvalidArgument: If key configuration is invalid
36
google.api_core.exceptions.AlreadyExists: If key with same display name exists
37
google.api_core.exceptions.PermissionDenied: If insufficient permissions
38
"""
39
```
40
41
#### Usage Example
42
43
```python
44
from google.cloud import recaptchaenterprise
45
from google.cloud.recaptchaenterprise_v1.types import Key, WebKeySettings
46
47
client = recaptchaenterprise.RecaptchaEnterpriseServiceClient()
48
49
# Create a web key
50
web_settings = WebKeySettings(
51
allowed_domains=["example.com", "app.example.com"],
52
allow_amp_traffic=True,
53
integration_type=WebKeySettings.IntegrationType.SCORE,
54
challenge_security_preference=WebKeySettings.ChallengeSecurityPreference.USABILITY
55
)
56
57
key = Key(
58
display_name="My Website Key",
59
web_settings=web_settings,
60
labels={"environment": "production", "team": "security"}
61
)
62
63
request = recaptchaenterprise.CreateKeyRequest(
64
parent="projects/your-project-id",
65
key=key
66
)
67
68
created_key = client.create_key(request=request)
69
print(f"Created key: {created_key.name}")
70
```
71
72
### List Keys
73
74
Retrieves all reCAPTCHA keys for a project with support for pagination and filtering.
75
76
```python { .api }
77
def list_keys(
78
request: ListKeysRequest = None,
79
*,
80
parent: str = None,
81
retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
82
timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
83
metadata: Sequence[Tuple[str, str]] = ()
84
) -> ListKeysResponse:
85
"""
86
Get a list of keys in a project.
87
88
Args:
89
request: The request object for listing keys
90
parent: Required. The name of the project in format 'projects/{project}'
91
retry: Retry configuration for the request
92
timeout: Timeout for the request in seconds
93
metadata: Additional metadata for the request
94
95
Returns:
96
ListKeysResponse: List of keys with pagination information
97
98
Raises:
99
google.api_core.exceptions.PermissionDenied: If insufficient permissions
100
google.api_core.exceptions.InvalidArgument: If parent format is invalid
101
"""
102
```
103
104
### Get Key
105
106
Retrieves detailed information about a specific reCAPTCHA key.
107
108
```python { .api }
109
def get_key(
110
request: GetKeyRequest = None,
111
*,
112
name: str = None,
113
retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
114
timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
115
metadata: Sequence[Tuple[str, str]] = ()
116
) -> Key:
117
"""
118
Returns the specified key.
119
120
Args:
121
request: The request object for getting a key
122
name: Required. The name of the key in format 'projects/{project}/keys/{key}'
123
retry: Retry configuration for the request
124
timeout: Timeout for the request in seconds
125
metadata: Additional metadata for the request
126
127
Returns:
128
Key: The key configuration and settings
129
130
Raises:
131
google.api_core.exceptions.NotFound: If the key doesn't exist
132
google.api_core.exceptions.PermissionDenied: If insufficient permissions
133
"""
134
```
135
136
### Update Key
137
138
Updates the configuration of an existing reCAPTCHA key.
139
140
```python { .api }
141
def update_key(
142
request: UpdateKeyRequest = None,
143
*,
144
key: Key = None,
145
update_mask: FieldMask = None,
146
retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
147
timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
148
metadata: Sequence[Tuple[str, str]] = ()
149
) -> Key:
150
"""
151
Updates the specified key.
152
153
Args:
154
request: The request object for updating a key
155
key: Required. The key to update with new settings
156
update_mask: Optional. Field mask specifying which fields to update
157
retry: Retry configuration for the request
158
timeout: Timeout for the request in seconds
159
metadata: Additional metadata for the request
160
161
Returns:
162
Key: The updated key configuration
163
164
Raises:
165
google.api_core.exceptions.NotFound: If the key doesn't exist
166
google.api_core.exceptions.InvalidArgument: If update parameters are invalid
167
google.api_core.exceptions.PermissionDenied: If insufficient permissions
168
"""
169
```
170
171
### Delete Key
172
173
Permanently deletes a reCAPTCHA key.
174
175
```python { .api }
176
def delete_key(
177
request: DeleteKeyRequest = None,
178
*,
179
name: str = None,
180
retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
181
timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
182
metadata: Sequence[Tuple[str, str]] = ()
183
) -> None:
184
"""
185
Deletes the specified key.
186
187
Args:
188
request: The request object for deleting a key
189
name: Required. The name of the key in format 'projects/{project}/keys/{key}'
190
retry: Retry configuration for the request
191
timeout: Timeout for the request in seconds
192
metadata: Additional metadata for the request
193
194
Raises:
195
google.api_core.exceptions.NotFound: If the key doesn't exist
196
google.api_core.exceptions.PermissionDenied: If insufficient permissions
197
google.api_core.exceptions.FailedPrecondition: If key is still in use
198
"""
199
```
200
201
### Migrate Key
202
203
Migrates a key from reCAPTCHA v2 or v3 to reCAPTCHA Enterprise.
204
205
```python { .api }
206
def migrate_key(
207
request: MigrateKeyRequest = None,
208
*,
209
name: str = None,
210
skip_billing_check: bool = None,
211
retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
212
timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
213
metadata: Sequence[Tuple[str, str]] = ()
214
) -> Key:
215
"""
216
Migrates an existing key from reCAPTCHA to reCAPTCHA Enterprise.
217
218
Args:
219
request: The request object for migrating a key
220
name: Required. The name of the key in format 'projects/{project}/keys/{key}'
221
skip_billing_check: Optional. Skip billing account check
222
retry: Retry configuration for the request
223
timeout: Timeout for the request in seconds
224
metadata: Additional metadata for the request
225
226
Returns:
227
Key: The migrated key configuration
228
229
Raises:
230
google.api_core.exceptions.NotFound: If the key doesn't exist
231
google.api_core.exceptions.FailedPrecondition: If migration requirements not met
232
google.api_core.exceptions.PermissionDenied: If insufficient permissions
233
"""
234
```
235
236
### Retrieve Legacy Secret Key
237
238
Retrieves the secret key for a legacy reCAPTCHA key during migration.
239
240
```python { .api }
241
def retrieve_legacy_secret_key(
242
request: RetrieveLegacySecretKeyRequest = None,
243
*,
244
key: str = None,
245
retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
246
timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
247
metadata: Sequence[Tuple[str, str]] = ()
248
) -> RetrieveLegacySecretKeyResponse:
249
"""
250
Get the secret key string for a legacy key.
251
252
Args:
253
request: The request object for retrieving secret key
254
key: Required. The public key name in format 'projects/{project}/keys/{key}'
255
retry: Retry configuration for the request
256
timeout: Timeout for the request in seconds
257
metadata: Additional metadata for the request
258
259
Returns:
260
RetrieveLegacySecretKeyResponse: Contains the legacy secret key
261
262
Raises:
263
google.api_core.exceptions.NotFound: If the key doesn't exist
264
google.api_core.exceptions.PermissionDenied: If insufficient permissions
265
google.api_core.exceptions.FailedPrecondition: If key is not legacy
266
"""
267
```
268
269
## Request and Response Types
270
271
### CreateKeyRequest
272
273
```python { .api }
274
class CreateKeyRequest:
275
"""Request message for creating a key."""
276
parent: str # Required. Project name in format 'projects/{project}'
277
key: Key # Required. Key configuration
278
```
279
280
### Key
281
282
```python { .api }
283
class Key:
284
"""reCAPTCHA key configuration."""
285
name: str # Output only. Resource name
286
display_name: str # Human-readable display name
287
web_settings: WebKeySettings # Web platform settings
288
android_settings: AndroidKeySettings # Android platform settings
289
ios_settings: IOSKeySettings # iOS platform settings
290
labels: Dict[str, str] # Key-value labels
291
create_time: Timestamp # Output only. Creation time
292
testing_options: TestingOptions # Testing configuration
293
waf_settings: WafSettings # WAF integration settings
294
```
295
296
### Platform-Specific Settings
297
298
```python { .api }
299
class WebKeySettings:
300
"""Settings for web-based keys."""
301
allow_all_domains: bool # Allow all domains
302
allowed_domains: List[str] # Specific allowed domains
303
allow_amp_traffic: bool # Allow AMP traffic
304
integration_type: IntegrationType # Score vs checkbox integration
305
challenge_security_preference: ChallengeSecurityPreference # Security vs usability
306
307
class IntegrationType(Enum):
308
"""Web integration types."""
309
INTEGRATION_TYPE_UNSPECIFIED = 0
310
SCORE = 1 # Invisible reCAPTCHA with score
311
CHECKBOX = 2 # Traditional checkbox reCAPTCHA
312
INVISIBLE = 3 # Invisible reCAPTCHA
313
314
class ChallengeSecurityPreference(Enum):
315
"""Challenge security preferences."""
316
CHALLENGE_SECURITY_PREFERENCE_UNSPECIFIED = 0
317
USABILITY = 1 # Prefer user experience
318
BALANCE = 2 # Balance security and usability
319
SECURITY = 3 # Prefer security
320
321
class AndroidKeySettings:
322
"""Settings for Android app keys."""
323
allow_all_package_names: bool # Allow all package names
324
allowed_package_names: List[str] # Specific allowed package names
325
support_non_google_app_store_distribution: bool # Support non-Play Store apps
326
327
class IOSKeySettings:
328
"""Settings for iOS app keys."""
329
allow_all_bundle_ids: bool # Allow all bundle IDs
330
allowed_bundle_ids: List[str] # Specific allowed bundle IDs
331
apple_developer_id: AppleDeveloperId # Apple developer verification
332
333
class ExpressKeySettings:
334
"""Settings for reCAPTCHA Express keys."""
335
# Express settings for streamlined reCAPTCHA implementation
336
337
class AppleDeveloperId:
338
"""Apple developer ID for iOS key verification."""
339
private_key: str # Apple private key
340
key_id: str # Apple key ID
341
team_id: str # Apple team ID
342
```
343
344
### Additional Configuration Types
345
346
```python { .api }
347
class TestingOptions:
348
"""Testing configuration for development."""
349
testing_score: float # Fixed score for testing (0.0-1.0)
350
testing_challenge: TestingChallenge # Testing challenge behavior
351
352
class TestingChallenge(Enum):
353
"""Testing challenge options."""
354
TESTING_CHALLENGE_UNSPECIFIED = 0
355
NOCAPTCHA = 1 # No challenge
356
UNSOLVABLE_CHALLENGE = 2 # Unsolvable challenge
357
358
class WafSettings:
359
"""Web Application Firewall settings."""
360
waf_service: WafService # WAF service integration
361
waf_feature_set: WafFeatureSet # WAF feature set
362
363
class WafService(Enum):
364
"""WAF service providers."""
365
WAF_SERVICE_UNSPECIFIED = 0
366
CA = 1 # CA App Synthetic Monitor
367
FASTLY = 3 # Fastly
368
369
class WafFeatureSet(Enum):
370
"""WAF feature sets."""
371
WAF_FEATURE_SET_UNSPECIFIED = 0
372
CHALLENGE_PAGE = 1 # Challenge page
373
SESSION_TOKEN = 2 # Session token
374
ACTION_TOKEN = 3 # Action token
375
EXPRESS = 4 # Express mode
376
```
377
378
### List and Response Types
379
380
```python { .api }
381
class ListKeysRequest:
382
"""Request message for listing keys."""
383
parent: str # Required. Project name
384
page_size: int # Optional. Maximum results per page
385
page_token: str # Optional. Pagination token
386
387
class ListKeysResponse:
388
"""Response message for listing keys."""
389
keys: List[Key] # The list of keys
390
next_page_token: str # Token for next page of results
391
392
class GetKeyRequest:
393
"""Request message for getting a key."""
394
name: str # Required. Key name
395
396
class UpdateKeyRequest:
397
"""Request message for updating a key."""
398
key: Key # Required. Key with updated values
399
update_mask: FieldMask # Optional. Fields to update
400
401
class DeleteKeyRequest:
402
"""Request message for deleting a key."""
403
name: str # Required. Key name
404
405
class MigrateKeyRequest:
406
"""Request message for migrating a key."""
407
name: str # Required. Key name
408
skip_billing_check: bool # Optional. Skip billing verification
409
410
class RetrieveLegacySecretKeyRequest:
411
"""Request message for retrieving legacy secret key."""
412
key: str # Required. Public key name
413
414
class RetrieveLegacySecretKeyResponse:
415
"""Response message containing legacy secret key."""
416
legacy_secret_key: str # The legacy secret key string
417
```
418
419
## Usage Examples
420
421
### Creating Platform-Specific Keys
422
423
#### Web Key with Domain Restrictions
424
425
```python
426
web_settings = WebKeySettings(
427
allowed_domains=["example.com", "*.example.com"],
428
allow_amp_traffic=True,
429
integration_type=WebKeySettings.IntegrationType.SCORE,
430
challenge_security_preference=WebKeySettings.ChallengeSecurityPreference.BALANCE
431
)
432
433
key = Key(
434
display_name="Production Web Key",
435
web_settings=web_settings,
436
labels={"environment": "prod", "domain": "example.com"}
437
)
438
```
439
440
#### Android Key with Package Name Restrictions
441
442
```python
443
android_settings = AndroidKeySettings(
444
allowed_package_names=["com.example.myapp"],
445
support_non_google_app_store_distribution=False
446
)
447
448
key = Key(
449
display_name="Android App Key",
450
android_settings=android_settings,
451
labels={"platform": "android", "version": "1.0"}
452
)
453
```
454
455
#### iOS Key with Bundle ID Restrictions
456
457
```python
458
apple_dev_id = AppleDeveloperId(
459
private_key="-----BEGIN PRIVATE KEY-----\n...",
460
key_id="ABC123DEF4",
461
team_id="DEF123ABC4"
462
)
463
464
ios_settings = IOSKeySettings(
465
allowed_bundle_ids=["com.example.myapp"],
466
apple_developer_id=apple_dev_id
467
)
468
469
key = Key(
470
display_name="iOS App Key",
471
ios_settings=ios_settings,
472
labels={"platform": "ios"}
473
)
474
```
475
476
### Testing Configuration
477
478
```python
479
testing_options = TestingOptions(
480
testing_score=0.8, # Fixed score for testing
481
testing_challenge=TestingOptions.TestingChallenge.NOCAPTCHA
482
)
483
484
key = Key(
485
display_name="Development Key",
486
web_settings=web_settings,
487
testing_options=testing_options,
488
labels={"environment": "development"}
489
)
490
```
491
492
### Key Migration Example
493
494
```python
495
# First, retrieve the legacy secret key
496
legacy_request = recaptchaenterprise.RetrieveLegacySecretKeyRequest(
497
key="projects/your-project/keys/your-legacy-key"
498
)
499
legacy_response = client.retrieve_legacy_secret_key(request=legacy_request)
500
print(f"Legacy secret key: {legacy_response.legacy_secret_key}")
501
502
# Then migrate the key
503
migrate_request = recaptchaenterprise.MigrateKeyRequest(
504
name="projects/your-project/keys/your-legacy-key",
505
skip_billing_check=False
506
)
507
migrated_key = client.migrate_key(request=migrate_request)
508
print(f"Migrated key: {migrated_key.name}")
509
```
510
511
## Error Handling
512
513
```python
514
from google.api_core import exceptions
515
516
try:
517
key = client.create_key(request=request)
518
except exceptions.AlreadyExists as e:
519
print(f"Key with this display name already exists: {e}")
520
except exceptions.InvalidArgument as e:
521
print(f"Invalid key configuration: {e}")
522
except exceptions.FailedPrecondition as e:
523
print(f"Prerequisites not met (billing, API enablement): {e}")
524
525
try:
526
client.delete_key(name=key_name)
527
except exceptions.NotFound as e:
528
print(f"Key not found: {e}")
529
except exceptions.FailedPrecondition as e:
530
print(f"Key still in use, cannot delete: {e}")
531
```
532
533
## Best Practices
534
535
### Key Creation
536
- Use descriptive display names that indicate purpose and environment
537
- Set appropriate domain/package restrictions for security
538
- Use labels to organize keys by team, environment, or application
539
- Configure testing options for development and staging keys
540
541
### Key Security
542
- Regularly rotate keys in production environments
543
- Use specific domain/package allowlists rather than allowing all
544
- Monitor key usage through metrics and logs
545
- Implement proper key lifecycle management
546
547
### Migration Planning
548
- Test migration in development environment first
549
- Retrieve and securely store legacy secret keys before migration
550
- Plan for gradual rollout to minimize service disruption
551
- Update client applications to use new Enterprise features post-migration