Integrate reCAPTCHA for WAF with Fastly

This document shows you how to integrate reCAPTCHA for WAF with Fastly.

To complete the integration, you must implement one or more features of reCAPTCHA for WAF, create reCAPTCHA firewall policies, and integrate with Fastly compute service.

Before you begin

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

    Record your Google Cloud project ID for later use.

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the reCAPTCHA Enterprise API.

    Enable the API

  4. Create an API key for authentication:

    1. In the Google Cloud console, go to the Credentials page.

      Go to Credentials

    2. Click Create credentials, and then select API key.

    3. Record the API key for later use.

  5. Plan how you want to implement the features of reCAPTCHA for WAF to protect your website.

    1. Choose one or more WAF features that best match your use case.
    2. Identify the pages that you want to protect and the type of WAF feature that you want to implement on those pages.
    3. Identify the conditions to allow or block access.
    4. Understand the reCAPTCHA firewall policy components and their attributes that help you to create reCAPTCHA firewall policies. For examples, see Examples of reCAPTCHA firewall policies.
  6. Download the reCAPTCHA package for Fastly recaptcha_fastly_client_0.1.0.tar.gz.

  7. Create a Fastly account with Compute@Edge capabilities.

Implement features of reCAPTCHA for WAF

Depending on your requirements, you can use one or more features of reCAPTCHA for WAF in a single application.

If you want to use more than one feature, then you must create a reCAPTCHA key for each of those features and use them in your application. For example, if you want to use reCAPTCHA action-tokens and reCAPTCHA challenge page, then you must create an action-token key and a challenge-page key, and use them in your application.

action-token

You must have reCAPTCHA running on your web pages to generate action-tokens. After reCAPTCHA generates an action-token, you attach the action-token to a predefined request header wherever you need to protect any user action, such as checkout. By default, action-tokens are valid for 30 minutes, but can vary depending on the traffic. You must attach the action-token to a predefined request header before the token expires, so that the Fastly can evaluate the token attributes.

To implement a reCAPTCHA action-token, do the following:

  1. Create an action-token key for your website.

    gcloud

    To create reCAPTCHA keys, use the gcloud recaptcha keys create command.

    Before using any of the command data below, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • INTEGRATION_TYPE: Type of integration. Specify score or checkbox.
    • DOMAIN_NAME: Domains or subdomains of websites allowed to use the key.

      Specify multiple domains as a comma-separated list. Optional: Specify --allow-all-domains to disable domain verification.

      Disabling domain verification is a security risk because there are no restrictions on the site, so your reCAPTCHA key can be accessed and used by anyone.

    • WAF_FEATURE: Name of the WAF feature. Specify action-token.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    Execute the gcloud recaptcha keys create command:

    Linux, macOS, or Cloud Shell

    gcloud recaptcha keys create \
    --web \
    --display-name=DISPLAY_NAME  \
    --integration-type=INTEGRATION_TYPE \
    --domains=DOMAIN_NAME \
    --waf-feature=WAF_FEATURE \
    --waf-service=WAF_SERVICE

    Windows (PowerShell)

    gcloud recaptcha keys create `
    --web `
    --display-name=DISPLAY_NAME  `
    --integration-type=INTEGRATION_TYPE `
    --domains=DOMAIN_NAME `
    --waf-feature=WAF_FEATURE `
    --waf-service=WAF_SERVICE

    Windows (cmd.exe)

    gcloud recaptcha keys create ^
    --web ^
    --display-name=DISPLAY_NAME  ^
    --integration-type=INTEGRATION_TYPE ^
    --domains=DOMAIN_NAME ^
    --waf-feature=WAF_FEATURE ^
    --waf-service=WAF_SERVICE

    The response contains the newly created reCAPTCHA key.

    REST

    For API reference information about key types and integration types, see Key and Integration type.

    Before using any of the request data, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • INTEGRATION_TYPE: Type of integration. Specify score or checkbox.
    • DOMAIN_NAME: Domains or subdomains of websites allowed to use the key.

      Specify multiple domains as a comma-separated list. Optional: Specify --allow-all-domains to disable domain verification.

      Disabling domain verification is a security risk because there are no restrictions on the site, so your reCAPTCHA key can be accessed and used by anyone.

    • WAF_FEATURE: Name of the WAF feature. Specify action-token.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    HTTP method and URL:

    POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys

    Request JSON body:

    
    {
      "displayName": "DISPLAY_NAME",
       'wafSettings': "  {
           "wafService": "WAF_SERVICE",
      
    "wafFeature": "WAF_FEATURE"
      }
      "webSettings": {
        "allowedDomains": "DOMAINS",
        "integrationType": "TYPE_OF_INTEGRATION"
       }
       
    }
    

    To send your request, choose one of these options:

    curl

    Save the request body in a file named request.json, and execute the following command:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys"

    PowerShell

    Save the request body in a file named request.json, and execute the following command:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys" | Select-Object -Expand Content

    You should receive a JSON response similar to the following:

    
    {
      "name": "projects/project-id/keys/7Ldqgs0UBBBBBIn4k7YxEB-LwEh5S9-Gv6QQIWB8m",
    "displayName": "DISPLAY_NAME,
    
    "webSettings": {
      "allowAllDomains": true,
      "allowedDomains": [
        "localhost"
      ],
    
     "integrationType": "SCORE",
    
    
    },
    "wafSettings": {
      "wafService": "fastly",
    
      "wafFeature": "ACTION_TOKEN"
      
    
    }
    }
    
    

    Record your action-token key for later use.

  2. Integrate reCAPTCHA JavaScript on your web pages with the action-token key that you created. For instructions, refer to the document that corresponds with the integration type of your action-token key.
  3. After you receive the token from reCAPTCHA, attach the token to a predefined request header in the following format:
     X-Recaptcha-Token: value-of-your-action-token
    

    You can use languages such as XHR, Ajax, or Fetch API to attach the token to a predefined request header.

    The following sample script shows how to protect the execute action and attach the token to a predefined request header using JavaScript + XHR:

      
      <script>
        src="https://www.google.com/recaptcha/enterprise.js?render=ACTION_TOKEN_KEY"></script>
    
        <script>
        function onSuccess(action_token) {
             const xhr = new XMLHttpRequest();
             xhr.open('GET','YOUR_URL', false);
             // Attach the action-token to the predefined request header
             xhr.setRequestHeader("X-Recaptcha-Token", action_token);
             xhr.send(null);
           }
           function onError(reason) {
             alert('Response promise rejected: ' + reason);
           grecaptcha.enterprise.ready(function () {
             document.getElementById("execute-button").onclick = () => {
               grecaptcha.enterprise.execute('ACTION_TOKEN_KEY', {
               }).then(onSuccess, onError);
             };
           });
          }
        </script>
      
      

session-token

The reCAPTCHA JavaScript sets a reCAPTCHA session-token as a cookie on the end user's browser after the assessment. The end user's browser attaches the cookie and refreshes the cookie as long as the reCAPTCHA JavaScript remains active.

To provide a session-token as a cookie, install a session-token key on at least one of your web pages that the end user browses before the page that needs to be protected. For example, if you want to protect the checkout page, install a session-token key on the home page or product page.

To learn about how to install session-token keys on your web pages, see Integrate score-based keys with the frontend.

You can use this cookie to protect the end user's subsequent requests and page loads on a specific domain. Session-tokens are valid for 30 minutes by default. However, if the end user stays on the page where you implemented the session-token, reCAPTCHA refreshes the session-token periodically to prevent it from expiring.

Install session-tokens on each page that needs to be protected by reCAPTCHA. We recommend that you protect every page with reCAPTCHA and use Google Cloud Armor rules to enforce access on all the pages, except the first page that end users browse.

The following is a sample reCAPTCHA session-token:
   recaptcha-ca-t=value-of-your-session-token;domain=domain;expires=expiration_time

To implement a reCAPTCHA session-token, do the following:

  1. Create a session-token key for your website.

    gcloud

    To create reCAPTCHA keys, use the gcloud recaptcha keys create command.

    Before using any of the command data below, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • INTEGRATION_TYPE: Type of integration. Specify score.
    • DOMAIN_NAME: Domains or subdomains of websites allowed to use the key.

      Specify multiple domains as a comma-separated list. Optional: Specify --allow-all-domains to disable domain verification.

      Disabling domain verification is a security risk because there are no restrictions on the site, so your reCAPTCHA key can be accessed and used by anyone.

    • WAF_FEATURE: Name of the WAF feature. Specify session-token.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    Execute the gcloud recaptcha keys create command:

    Linux, macOS, or Cloud Shell

    gcloud recaptcha keys create \
    --web \
    --display-name=DISPLAY_NAME  \
    --integration-type=INTEGRATION_TYPE \
    --domains=DOMAIN_NAME \
    --waf-feature=WAF_FEATURE \
    --waf-service=WAF_SERVICE

    Windows (PowerShell)

    gcloud recaptcha keys create `
    --web `
    --display-name=DISPLAY_NAME  `
    --integration-type=INTEGRATION_TYPE `
    --domains=DOMAIN_NAME `
    --waf-feature=WAF_FEATURE `
    --waf-service=WAF_SERVICE

    Windows (cmd.exe)

    gcloud recaptcha keys create ^
    --web ^
    --display-name=DISPLAY_NAME  ^
    --integration-type=INTEGRATION_TYPE ^
    --domains=DOMAIN_NAME ^
    --waf-feature=WAF_FEATURE ^
    --waf-service=WAF_SERVICE

    The response contains the newly created reCAPTCHA key.

    REST

    For API reference information about key types and integration types, see Key and Integration type.

    Before using any of the request data, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • INTEGRATION_TYPE: Type of integration. Specify score.
    • DOMAIN_NAME: Domains or subdomains of websites allowed to use the key.

      Specify multiple domains as a comma-separated list. Optional: Specify --allow-all-domains to disable domain verification.

      Disabling domain verification is a security risk because there are no restrictions on the site, so your reCAPTCHA key can be accessed and used by anyone.

    • WAF_FEATURE: Name of the WAF feature. Specify session-token.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    HTTP method and URL:

    POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys

    Request JSON body:

    
    {
      "displayName": "DISPLAY_NAME",
       'wafSettings': "  {
           "wafService": "WAF_SERVICE",
      
    "wafFeature": "WAF_FEATURE"
      }
      "webSettings": {
        "allowedDomains": "DOMAINS",
        "integrationType": "TYPE_OF_INTEGRATION"
       }
       
    }
    

    To send your request, choose one of these options:

    curl

    Save the request body in a file named request.json, and execute the following command:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys"

    PowerShell

    Save the request body in a file named request.json, and execute the following command:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys" | Select-Object -Expand Content

    You should receive a JSON response similar to the following:

    
    {
      "name": "projects/project-id/keys/7Ldqgs0UBBBBBIn4k7YxEB-LwEh5S9-Gv6QQIWB8m",
    "displayName": "DISPLAY_NAME,
    
    "webSettings": {
      "allowAllDomains": true,
      "allowedDomains": [
        "localhost"
      ],
    
     "integrationType": "SCORE",
    
    
    },
    "wafSettings": {
      "wafService": "fastly",
    
      "wafFeature": "SESSION_TOKEN"
    
    
    }
    }
    
    

    Record your session-token key for later use.

  2. Add the session-token key and waf=session to the reCAPTCHA JavaScript.

    The following sample script shows how to implement a session-token on a web page:

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>reCAPTCHA WAF Session Token</title>
     <script src="https://www.google.com/recaptcha/enterprise.js?render=SESSION_TOKEN_KEY&waf=session" async defer></script>
     <body></body>
    </head>
    </html>

challenge-page

When you implement a reCAPTCHA challenge page, reCAPTCHA redirects to an interstitial page where it determines if it's necessary to show a CAPTCHA challenge to a user. Therefore, CAPTCHA challenges might not be visible to all users.

To implement a reCAPTCHA challenge page, do the following:

  1. Create a challenge-page key for your website.

    gcloud

    To create reCAPTCHA keys, use the gcloud recaptcha keys create command.

    Before using any of the command data below, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • INTEGRATION_TYPE: Type of integration. Specify invisible.
    • DOMAIN_NAME: Domains or subdomains of websites allowed to use the key. Specify --allow-all-domains.
    • WAF_FEATURE: Name of the WAF feature. Specify challenge-page.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    Execute the gcloud recaptcha keys create command:

    Linux, macOS, or Cloud Shell

    gcloud recaptcha keys create \
    --web \
    --display-name=DISPLAY_NAME  \
    --integration-type=INTEGRATION_TYPE \
    --domains=DOMAIN_NAME \
    --waf-feature=WAF_FEATURE \
    --waf-service=WAF_SERVICE

    Windows (PowerShell)

    gcloud recaptcha keys create `
    --web `
    --display-name=DISPLAY_NAME  `
    --integration-type=INTEGRATION_TYPE `
    --domains=DOMAIN_NAME `
    --waf-feature=WAF_FEATURE `
    --waf-service=WAF_SERVICE

    Windows (cmd.exe)

    gcloud recaptcha keys create ^
    --web ^
    --display-name=DISPLAY_NAME  ^
    --integration-type=INTEGRATION_TYPE ^
    --domains=DOMAIN_NAME ^
    --waf-feature=WAF_FEATURE ^
    --waf-service=WAF_SERVICE

    The response contains the newly created reCAPTCHA key.

    REST

    For API reference information about key types and integration types, see Key and Integration type.

    Before using any of the request data, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • INTEGRATION_TYPE: Type of integration. Specify invisible.
    • DOMAIN_NAME: Domains or subdomains of websites allowed to use the key. Specify --allow-all-domains.
    • WAF_FEATURE: Name of the WAF feature. Specify challenge-page.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    HTTP method and URL:

    POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys

    Request JSON body:

    
    {
      "displayName": "DISPLAY_NAME",
       'wafSettings': "  {
           "wafService": "WAF_SERVICE",
      
    "wafFeature": "WAF_FEATURE"
      }
      "webSettings": {
        "allowedDomains": "DOMAINS",
        "integrationType": "TYPE_OF_INTEGRATION"
       }
       
    }
    

    To send your request, choose one of these options:

    curl

    Save the request body in a file named request.json, and execute the following command:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys"

    PowerShell

    Save the request body in a file named request.json, and execute the following command:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys" | Select-Object -Expand Content

    You should receive a JSON response similar to the following:

    
    {
      "name": "projects/project-id/keys/7Ldqgs0UBBBBBIn4k7YxEB-LwEh5S9-Gv6QQIWB8m",
    "displayName": "DISPLAY_NAME,
    
    "webSettings": {
      "allowAllDomains": true,
      "allowedDomains": [
        "localhost"
      ],
    
      "integrationType": "INVISIBLE",
     
    
    },
    "wafSettings": {
      "wafService": "fastly",
    
      "wafFeature": "CHALLENGE_PAGE"
      
    
    }
    }
    
    

    Record your challenge-page key for later use.

  2. To redirect users to the reCAPTCHA challenge page and receive a reCAPTCHA token, create a firewall policy with the redirect action on protected pages.

express

To implement reCAPTCHA express, create an express key.

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. gcloud

    To create reCAPTCHA keys, use the gcloud recaptcha keys create command.

    Before using any of the command data below, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    Execute the gcloud recaptcha keys create command:

    Linux, macOS, or Cloud Shell

    gcloud recaptcha keys create \
    --express \
    --display-name=DISPLAY_NAME  \
    --waf-service=WAF_SERVICE

    Windows (PowerShell)

    gcloud recaptcha keys create `
    --express `
    --display-name=DISPLAY_NAME  `
    --waf-service=WAF_SERVICE

    Windows (cmd.exe)

    gcloud recaptcha keys create ^
    --express ^
    --display-name=DISPLAY_NAME  ^
    --waf-service=WAF_SERVICE

    The response contains the newly created reCAPTCHA key.

    REST

    For API reference information about key types and integration types, see Key and Integration type.

    Before using any of the request data, make the following replacements:

    • DISPLAY_NAME: Name for the key. Typically a site name.
    • WAF_SERVICE: Name of the WAF service provider. Specify fastly for Fastly.

    HTTP method and URL:

    POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys

    Request JSON body:

    
    {
      "displayName": "DISPLAY_NAME",
       'wafSettings': "  {
           "wafService": "WAF_SERVICE",
      
    }
    

    To send your request, choose one of these options:

    curl

    Save the request body in a file named request.json, and execute the following command:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys"

    PowerShell

    Save the request body in a file named request.json, and execute the following command:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/keys" | Select-Object -Expand Content

    You should receive a JSON response similar to the following:

    
    {
      "name": "projects/project-id/keys/7Ldqgs0UBBBBBIn4k7YxEB-LwEh5S9-Gv6QQIWB8m",
    "displayName": "DISPLAY_NAME,
    
    },
    "wafSettings": {
      "wafService": "fastly",
    
      
    
    }
    }
    
    

    Record your express key for later use.

Integrate with Fastly compute service

To use the reCAPTCHA firewall policies, you must set up a Fastly compute service to intercept and process requests.

You can either create and configure a new compute service or integrate reCAPTCHA firewall policies with an existing Fastly service, by chaining. If you want to use chaining, the reCAPTCHA service must be the furthest upstream Fastly service or other proxy for correct IP detection.

To create a compute service, you must have the following information:

  • Your domain name
  • reCAPTCHA package for FASTLY in zip format
  • Origin name for your backend server
  • Origin name for the reCAPTCHA backend server: Recaptcha Enterprise
  • Origin name for Google backend server: Google
  • Your API key that you created for the authentication
  • Your Google Cloud project ID
  • Your reCAPTCHA keys that you created for your WAF features

To set up a Fastly service with reCAPTCHA firewall policies, do the following:

  1. Log in to Fastly.
  2. To create a compute service, follow the instructions in Creating a new compute service.

    When creating a compute service, do the following:

    • To create an origin for the reCAPTCHA backend server, specify the following values:

      • Name of your origin = Recaptcha Enterprise
      • IP address (or hostname) of your origin server = public-preview-recaptchaenterprise.googleapis.com
    • To create an origin for Google backend server, specify the following values:

      • Name of your origin = Google
      • IP address (or hostname) of your origin server = www.google.com:443
    • To create an origin for your backend server, specify the following values:

      • Name of your origin = Any meaningful name for your backend server.
      • IP address (or hostname) of your origin server = Hostname for your backend server.
    • Upload the reCAPTCHA package for Fastly recaptcha_fastly_client_0.1.0.tar.gz.

    • Create a new ConfigStore named recaptcha and add the following key-value pairs:

      Key Value
      api_key The API key that you created for authentication.
      project_number Your Google Cloud project ID.
      action_site_key reCAPTCHA WAF action-token key. This key is required if you're using action-tokens for protecting your pages.
      session_site_key reCAPTCHA WAF session-token key. This key is required if you're using session-tokens for protecting your pages.
      challengepage_site_key reCAPTCHA WAF challenge-page key. This key is required if you're using the reCAPTCHA challenge page for protecting your pages.
      express_site_key reCAPTCHA express key. This key is required if you're using the reCAPTCHA express for protecting your pages.
      recaptcha_js_install_path URLs of the pages where you want the reCAPTCHA WAF plugin to install the reCAPTCHA JavaScript using the session-token key. Specify the paths as a [glob pattern](https://man7.org/linux/man-pages/man7/glob.7.html) and use `;` as the delimiter. This option is available only for reCAPTCHA session-token.

What's next