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.
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 diagram below provides a simplified illustration of the HUMAN Fastly VCL Enforcer flow. Detailed explanations of each numbered step are included underneath the diagram.
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.

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
px_recv).return(pass) statement is used to push the flow to vcl_pass and proceed with Step 2 .2. Risk API Request (Conditionally)
bereq) is prepared and PX_API is set as the backend.3. Risk API Response (Conditionally)
beresp) to the client request (req) so it will be available after the restart.restart statement is used to return the flow to vcl_recv.4. Verification
error statement is used to proceed to Step 5.px_recv subroutine ends and the flow proceeds to Step 6.5. Blocking
return(deliver) statement is used to push the flow to vcl_deliver and directly to Step 7.6. Passing
px_recv subroutine ends without a return statement, allowing for the continuation of vcl_recv and the rest of the VCL flow.MAIN VCL file is executed.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).
7. Response Modification
8. Async Activity Reporting
page_requested, block, and additional_s2s) are sent to HUMAN.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.
For information about Fastly VCL constraints and limitations, see here.
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.
The HUMAN Fastly VCL Enforcer utilizes 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.