How It Works

Fastly VCL

Fastly uses Varnish Configuration Language (VCL) to configure and manage edge logic. The HUMAN Enforcer leverages the ability to add custom VCL logic (as well as a variety of other Fastly features) to implement all the behaviors and features necessary for the HUMAN Enforcer to function.

📘

Understanding Fastly VCL

Familiarity with the Fastly VCL request lifecycle is crucial to understanding how the HUMAN Fastly VCL Enforcer operates. You can learn more about the Fastly VCL request lifecycle here.

The HUMAN Enforcement Flow

The diagram below provides a simplified illustration of the HUMAN Fastly VCL Enforcer flow. Detailed explanations of each numbered step are included underneath the diagram.

Note: This diagram focuses on the enforcement flow only. The request flow for first party requests, preflight requests, filtered requests, error handling, etc. is not included.

fastly-vcl-enforcer-flow.png

🚧

Notice

The flow appears to transition between HUMAN subroutines (e.g., px_recv directly to px_pass), but this is not exactly accurate. In reality, the px_recv subroutine executes a return(pass) statement to trigger a Fastly state transition. This invokes the vcl_pass hook subroutine, which then calls the px_pass subroutine within it. For this reason, it is crucial that the HUMAN subroutines are called at the beginning of every VCL hook subroutine.

1. Initialization

  • The Enforcer configuration is initialized.
  • The incoming request is parsed and request data is extracted.
  • The HUMAN Risk Cookie, if present, is decoded and validated.
    • If the HUMAN Risk Cookie is enough to make a pass/block determination, Steps 2-4 are skipped and the flow proceeds directly to Step 5 (also in px_recv).
    • If the HUMAN Risk Cookie is not enough to make a pass/block determination, the return(pass) statement is used to push the flow to vcl_pass and proceed with Step 2 .

2. Risk API Request (Conditionally)

  • The Risk API backend request (bereq) is prepared and PX_API is set as the backend.

3. Risk API Response (Conditionally)

  • The return(deliver) statement is used to push the flow to vcl_deliver. The Risk API backend response (beresp) is copied to the client response (resp) as a result.

4. Restart (Conditionally)

  • The Risk API response data is transferred from the client response (resp) to the client request (req) so it will be available after the restart.
  • The restart statement is used to return the flow to vcl_recv.

5. Verification

  • The binary score (from the HUMAN Risk Cookie or Risk API response) is verified.
  • If the request should be blocked, an error statement is used to proceed to Step 6.
  • If the request should be passed, the px_recv subroutine ends and the flow proceeds to Step 7.

6. Blocking

  • A synthetic block response is created.
  • The return(deliver) statement is used to push the flow to vcl_deliver and directly to Step 8.

7. Passing

  • The px_recv subroutine ends without a return statement, allowing for the continuation of vcl_recv and the rest of the VCL flow.
  • The customer-defined VCL flow as written in the MAIN VCL file is executed.

📘

Note

After HUMAN has determined to pass the request, all subsequent invocations to HUMAN subroutines will NOT execute the enforcement flow. Instead, they will perform minor logic to ensure the rest of the customer-defined VCL flow remains smooth and unaffected by HUMAN (e.g., removing HUMAN metadata headers from backend requests to your origin).

8. Async Activity Reporting

  • Once the response has been retrieved from the origin or cache and is ready to be returned to the client, asynchronous activities (page_requested, block, and additional_s2s) will be sent to HUMAN.
  • Any necessary modifications to the client response (e.g., setting the PXHD cookie) are made.

Reserved Error Codes

The HUMAN Enforcer logic reserves a few error codes for specific cases to help navigate between different Fastly workflow states. These error codes should remain unused by other VCL logic in the Fastly services, as using any of the following codes may lead to unexpected behavior.

Error CodeMeaning
990custom_preflight_handler
991first_party_disabled
992first_party_xhr_disabled
995exceeded_rate_limit, s2s_high_score, cookie_high_score
996cookie_high_score

Fastly Limitations

📘

For information about Fastly VCL constraints and limitations, see here.

Headers

One significant limitation of Fastly VCL is that it does not allow for global variables or parameters passed to subroutines. As a result, all data stored between subroutines and throughout the request lifecycle must be stored on request headers.

The HUMAN Fastly VCL Enforcer stores data on headers starting with px-* or x-px-* (e.g., px-ctx, x-px-filter-by). In total, the HUMAN Fastly VCL Enforcer uses between 5-15 request headers; the specific number depends on the configuration settings, enabled features, and incoming request data.

Restarts

The HUMAN Fastly VCL Enforcer utilzes 1 restart at most for the enforcement flow. This restart is used to perform the synchronous Risk API request in cases where the HUMAN Risk Cookie is insufficient to provide a score. In cases where the HUMAN Risk Cookie is sufficient, a restart will NOT be performed.

For more information about Fastly VCL restarts, see here.