or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

account-security-analysis.mdassessment-operations.mdfirewall-policies.mdindex.mdip-override-management.mdkey-management.mdmetrics-analytics.md

key-management.mddocs/

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