This document explains how to configure challenge policies with an existing Google Cloud Fraud Defense integration.
Challenge policies let you selectively trigger CAPTCHA challenges based on custom rules. These rules decide when to show a Fraud Defense challenge based on risk scores, IP addresses, user agents, ASNs, or verified bot (AI agent) identities.
You can use challenge policies with the following recommended features:
- AutoExecute configuration: Simplifies JavaScript integration for client applications.
- Challenges: Triggers user
verification when required by your challenge rules.
Fraud Defense supports the following challenge types:
- Visual challenges: Ask users to select images based on a prompt. By default, a visual challenge gets selected when a rule is configured with the challenge option selected.
- Audio challenges: Ask users to identify spoken audio cues as an accessibility alternative.
- QR code challenges: Ask users to scan a QR code with their mobile device to solve a challenge. Your Universal key must be on an allowlist to use this feature. To add your Universal key to the allowlist, contact the Fraud Defense team at fraud-defense@google.com and provide your Universal key.
Before you begin
- Prepare your environment for Google Cloud Fraud Defense.
- Verify that billing is enabled for your Google Cloud project. You can enable billing by using either a credit card or an existing Google Cloud project billing ID. If you require assistance with billing, contact Cloud Billing support.
Create or identify a Universal key for your project. To create a key, see Create a Universal key. Alternatively, you can copy the ID of an existing Universal key by completing one of the following steps:
To copy the ID of an existing key from the Google Cloud console, do the following:
In the Google Cloud console, go to the Google Cloud Fraud Defense page.
In the reCAPTCHA keys list, find the key that you want to copy and click Copy to clipboard.
To copy the ID of an existing key using the REST API, call the
projects.keys.listmethod.To copy the ID of an existing key using the gcloud CLI, run the
gcloud recaptcha keys listcommand.
Plan your Fraud Defense integration by identifying the user actions that you want to protect (such as
login,signup, orpassword_reset) and which pages on your website trigger these actions. If you use the AutoExecute configuration, ensure that these actions are consistent with the action names specified in theprotected_endpoint_group.Integrate Fraud Defense into your web page. We recommend that you use the Fraud Defense AutoExecute configuration. For general setup instructions, see Install Universal keys on websites.
Fraud Defense policy configuration overview
The Fraud Defense policy configuration lets you customize the behavior of your Fraud Defense protection. You can configure challenge policies using the challenge_rule_groups section.
You can view and update the policy configuration using the Google Cloud console, the gcloud CLI, or the reCAPTCHA Enterprise REST API.
Console
To view or update your policy configuration in the Google Cloud console, do the following:
In the Google Cloud console, go to the Fraud Defense page.
Make sure that your project is selected in the resource selector.
In the reCAPTCHA keys table, click the name of the key for which you want to configure challenge policies.
On the Key details page, go to the Policy tab.
In the Rule groups section, you can view, add, or edit your challenge rules and condition expressions.
Click Save.
gcloud
To update the policy configuration for a key, run the gcloud alpha recaptcha policies update command:
gcloud alpha recaptcha policies update --key=KEY_ID --policy=POLICY.yaml
To view the current policy configuration for a key, run the gcloud alpha recaptcha policies describe command:
gcloud alpha recaptcha policies describe --key=KEY_ID
REST API
To update the policy configuration for a key, call the projects.keys.updatePolicy method:
PATCH https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys/KEY_ID/policy
{
"clientSettings": {
"allowedDomains": [
"example.com"
]
},
"challengeRuleGroups": [
{
"actions": ["login"],
"challengeRules": [
{
"condition": "score < 0.7",
"challenge": {}
}
]
}
]
}
To view the current policy configuration for a key, call the projects.keys.getPolicy method:
GET https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys/KEY_ID/policy
The policy configuration uses YAML format for the Google Cloud CLI and JSON format for the REST API. For the complete schema of the challenge_rule_groups section, see Configure challenge policies.
For examples of different use cases, see Example challenge rule configurations.
Configure challenge policies
You configure challenge policies within the challenge_rule_groups section of
the Fraud Defense policy configuration. If you already have a
policy with client_settings, including the domains information, you can update
the policy to include your challenge policy rules.
The challenge_rule_groups section has the following structure:
challenge_rule_groups:
- actions: [string, ...]
challenge_rules:
- condition: string
challenge:
# difficulty is optional: USABILITY | BALANCE (default) | SECURITY
difficulty: BALANCE
# OR no_challenge: {}
- condition: string
challenge:
difficulty: BALANCE
# OR no_challenge: {}
In every challenge rule, the condition field is optional. If condition is
unspecified or empty, the rule applies unconditionally. Furthermore, the
challenge and no_challenge fields are mutually exclusive, and exactly one
of them must be present in each rule.
Rule evaluation order
Rule groups and their internal rules are evaluated sequentially from top to bottom. The first matching rule is applied. When no group and no rule matches the interaction, evaluation defaults to standard assessment with no challenge shown but a risk score is generated for the request.
Challenge difficulty levels
You can specify the difficulty level when triggering a challenge. For a complete list of valid difficulty values, see the ChallengeSecurityPreference API reference.
Condition syntax
The condition field is an optional string formatted as a Common Expression Language (CEL) expression. If condition is unspecified or empty, the rule applies unconditionally. CEL provides standard C-like operators, including relational (<, <=, >, >=, ==, !=), arithmetic (+, -, /, *, %), logical (!, &&, ||), and container ([], in) operators. CEL supports common primitive data types (bool, int, uint, double, string), basic container types (lists, messages), and constants (such as true, 1, 0.5, "hello", and [1, 2, 3]).
Within the runtime, the following Fraud Defense variables are accessible:
| Variable | Type | Description |
|---|---|---|
score |
double |
The Fraud Defense bot score. |
user_ip_address |
string |
The IP address (IPv4 or IPv6) of the user making the request. |
user_agent |
string |
The user agent of the user making the request. |
user_asn |
int |
The Autonomous System Number (ASN) of the user making the request. Omit the AS prefix (for example, use 12345 instead of AS12345). |
verified_bots |
list(Bot) |
A list of verified automated crawlers or agents (such as search engine indexers, AI search assistants, and partner content scrapers) that Fraud Defense has identified. |
The following additional non-primitive types are defined. For the complete list of values, see Bot.
message Bot {
name [string] - the name of the bot
bot_type [BotType] - the type of automated agent
}
For more information about possible name values, see the Bot API reference. For more information about valid bot_type enum values, see the BotType API reference.
In Fraud Defense challenge policies, you can use any of these variables to produce a boolean expression. For example, score > 0.5, user_ip_address == "192.0.2.1", and user_asn == 12345 are valid condition expressions that evaluate to a boolean. Note that because user_asn is an integer type, you must omit the AS prefix when checking ASNs.
The following functions are available for use in Fraud Defense challenge policy conditions:
| Name | Signature | Description |
|---|---|---|
contains |
string.contains(string) -> bool |
Checks whether the string operand contains the substring. |
startsWith |
string.startsWith(string) -> bool |
Checks whether the string operand starts with the specified prefix. |
endsWith |
string.endsWith(string) -> bool |
Checks whether the string operand ends with the specified suffix. |
size |
size(string) -> intsize(list) -> intstring.size() -> intlist.size() -> int |
Returns the size of a string (number of codepoints) or list (number of elements). |
Comprehension functions are a style of macro built into CEL. The following comprehensions are available:
| Name | Signature | Description | Example |
|---|---|---|---|
has |
has(message.field) -> bool |
Checks whether a field is available. | has(verified_bots[0].name) |
all |
list(A).all(A, predicate(A) -> bool) -> bool |
Checks whether all elements x in a list e match predicate p. |
[1, 2, 3].all(x, x > 0) |
exists |
list(A).exists(A, predicate(A) -> bool) -> bool |
Checks whether any element x in a list e matches predicate p. |
[1, 2, 3].exists(i, i % 2 != 0) |
exists_one |
list(A).exists_one(A, predicate(A)) -> bool |
Checks whether exactly one element x in a list e matches predicate p. |
[1, 2, 2].exists_one(i, i < 2) |
Example challenge rule configurations
This section contains valid challenge rule configuration examples.
Challenge all requests that have a low score
challenge_rule_groups:
- actions: ['*']
challenge_rules:
- condition: 'score < 0.5'
challenge: {}
Select a high-friction challenge for all requests with a low score
challenge_rule_groups:
- actions: ['*']
challenge_rules:
- condition: 'score < 0.5'
challenge:
difficulty: 'SECURITY'
Challenge specific actions that have a low score
challenge_rule_groups:
- actions: ['login', 'signup']
challenge_rules:
- condition: 'score < 0.5'
challenge: {}
Configure different rule thresholds for different actions
challenge_rule_groups:
- actions: ['login']
challenge_rules:
- condition: 'score < 0.5'
challenge: {}
- actions: ['signup']
challenge_rules:
- condition: 'score < 0.7'
challenge: {}
Don't show challenge to IP addresses on allowlist
challenge_rule_groups:
- actions: ['*']
challenge_rules:
- condition: 'user_ip_address in ["123.255.255.001", "123.255.255.002"]'
no_challenge: {}
Note: This rule is distinct from the Fraud Defense IP allowlists feature.
Don't show challenge to subnet of IP addresses
challenge_rule_groups:
- actions: ['*']
challenge_rules:
- condition: 'user_ip_address.startsWith("123.255.255")'
no_challenge: {}
Don't show challenge to requests from specific ASNs
challenge_rule_groups:
- actions: ['*']
challenge_rules:
# Note that ASNs must be specified as integers without the AS prefix (e.g., 12345 instead of AS12345)
- condition: 'user_asn in [12345, 67890]'
no_challenge: {}
Don't show challenge to a Google agent
challenge_rule_groups:
- actions: ['*']
challenge_rules:
- condition: 'verified_bots.exists(e, e.name == "google-agent")'
no_challenge: {}
Show challenge based on complex conditions
challenge_rule_groups:
- actions: ['*']
challenge_rules:
- condition: '(user_agent.contains("Chrome/143") && score < 0.5) || (user_agent.contains("Chrome/149") && score < 0.7)'
challenge: {}
What's next
- To assess the reCAPTCHA response token, see Create assessments for websites.