@specprotected/spec-proxy-fastly-worker
TypeScript icon, indicating that this package has built-in type declarations

0.2.2 • Public • Published

Spec Proxy Fastly Compute@Edge API Integration

This document describes a method of integrating with Spec Proxy through a Fastly Compute@Edge worker.

We won't cover in detail how to use a Fastly worker and will instead direct you to follow their documentation to get a worker project set up and deployed. Once deployed, all you need do is copy our sample code into your edge worker function and communicate with the Spec team to coordinate the Spec Proxy deployment.

Fastly Compute@Edge Documentation

The Fastly Backend documentation talks about backends and how they work. You will need a backend that points to your origin server and another one that points to your Spec Proxy deployment which this library will use to properly route traffic. We can support complex deployment scenarios as well, we go into this in detail later in this document.

Implementation Example

Using our library is simple. We require only a single function call if we are the only library you are using.

Here are some of Fastly's documents on implementing a JavaScript worker:

Static Backends

Note: You MUST configure Fastly Backends in order for this deployment method to work.


In this example, customers are responsible for configuring the Compute Service with the appropriate backends. These backends are then registered with the Compute function. We translate the incoming hostname to the name of the backend that should be used. This assures proper routing of traffic out of the Compute Service.

In addition to your Backends that serve your application, you will need to create a Backend configuration for your Spec Proxy deployment. Work with your Spec representative to get the hostname of your Spec Proxy deployment which you will use when defining the spec-proxy Backend in your Fastly configuration.

Configuration Options are defined below.

/// <reference types="@fastly/js-compute" />

import {
  specProxyProcess,
  setFastlyBackends,
} from "@specprotected/spec-proxy-fastly-worker";

// This function sets the backends that are used by the fastly service worker
// library to properly route incoming traffic to its ultimate destination.
// You must supply a map of url hostname to Fastly backend, which this library will
// use to automatically direct traffic.
setFastlyBackends({
  // This is your origin destination backend
  "www.example.com": "origin",
  // This is your Spec Proxy deployment backend
  "www.example.com.spec-internal.com": "spec-proxy",
});

addEventListener("fetch", (event) => {
  event.respondWith(
    specProxyProcess(event, {
      /* Configuration Options */
    }),
  );
});

Dynamic Backends

If you have a dynamic number of backends or the number of backends is quite large, you can use the Dynamic Backends configuration.


Note: Dynamic Backends must be enabled on the Compute Service by Fastly, please contact your representative to use this feature or email sales@fastly.com.


This feature is enabled in the worker through the property dynamicBackends in your SpecConfiguration object.

The implementation is quite similar to static backends, but relies on some information provided to the worker of the intended destination. This can occur through a header that contains the destination host, or through hostname replacement, or both. By supplying the configuration option alternateHostHeader, the Spec Proxy library will infer the destination host from this header. Additionally, you can use the hostReplacements property to supply an array of replacements. We use the destination host as the target of replacement, which comes from the Host header or the alternateHostHeader if that is supplied, and then replace part of the hostname with an alternate hostname that points to the destination origin. We will set the Host header of the outgoing request to the destination host value after all replacements are made.

To reiterate, we first acquire the destination host value. This value comes from the Host header unless alternateHostHeader is specified, in which case we will use the header you provide. We then take the destination host and perform any hostReplacements on it to create the final destination host value.

If no match is found, and Static Backends are also set using the technique above, then we will attempt to match a Static Backend configuration with the incoming host.

The dynamic backend mechanism essentially allows a prior service to inform the Edge Worker the location of the origin dynamically. This allows you to add and remove hosts without re-configuring the worker itself. If you change any hosts, you should contact your Spec representative to ensure that the new traffic is properly analyzed.

/// <reference types="@fastly/js-compute" />

import { specProxyProcess } from "@specprotected/spec-proxy-fastly-worker";

import { allowDynamicBackends } from "fastly:experimental";

// configure these values as necessary
allowDynamicBackends({
  connectTimeout: 1000,
  firstByteTimeout: 15000,
  betweenBytesTimeout: 10000,
});

addEventListener("fetch", (event) => {
  event.respondWith(
    specProxyProcess(event, {
      dynamicBackends: true,
      hostReplacements: [
        {
          find: ".customer.com",
          replace: ".origin-customer.com",
        },
        {
          find: "(.*).customer.com",
          replace: "origin-$1.customer.com",
          regex: true,
        },
      ],
    }),
  );
});

In addition to the Configuration Options below, the Spec Proxy Fastly Library provides these additional configuration options to support the Dynamic Backends feature.

Variable Type Default Description
dynamicBackends Boolean false Set this flag to true to enable Dynamic Backends support in the Spec Proxy Library. Dynamic Backends is a feature that allows the Compute@Edge worker to dynamically route traffic to Fastly Backends without having to pre-define them in the UI.
alternateHostHeader String null When provided, the Spec Porxy Library will use the header specified in this value to acquire the destination hostname. This hostname is used when the Dynamic Backend is constructed.
hostReplacements Array null When provided, the Spec Proxy Library will attempt to replace the hostname using the supplied find/replace values. This will use the value of the incoming Host header unless alternateHostHeader (above) is supplied. This feature can be used to algorithmically replace incoming hostnames to form the destination hostname. This is useful if your origin servers share a common pattern, such as prefixing the hostname with origin, as in www.customer.com becomes www.origin.customer.com. This supports a standard string find/replace as well as regex find/replace with support for capture groups.

You can find the definition of the HostReplacement type in our library's typings definition, but we'll also show this here. The replacement occurs from the two properties find and replace. We attempt to find the text using the find pattern and replace it with the replace pattern. When regex is set to true then you may use regular expressions, including capture groups, to perform the find/replace.

export interface HostReplacement {
  /**
   * The pattern to find within the hostname
   */
  find: string;
  /**
   * The text to replace the found pattern within the hostname.
   * This can contain capture group references when regex = true.
   */
  replace: string;
  /**
   * Set to true to enable a regular expression search. Since regex
   * searches are slightly slower, this is not enabled by default.
   */
  regex: boolean;
}

Configuration Options

We provide a few configuration options for how traffic should be handled by the Cloudflare Worker.

Variable Type Default Description
disableSpecProxy Boolean false Toggle between enabling or disabling Spec processing. When disabled (true), all traffic is routed directly to the customer's downstream origin, bypassing Spec completely. This setting causes all of the following settings to be ignored.
inlineMode Boolean false Toggle between two available processing modes. Inline mode (true) works by forwarding traffic through the Spec Trust Cloud for processing. This mode enables inline mitigations. Mirror mode (false) creates a copy of traffic to send to the Spec Trust Cloud for processing while the original message is forwarded directly to the customer's downstream origin. This mode does not allow for inline mitigations. Note: Do not adjust this setting without contacting your Spec representative.
percentageOfIPs Number 100 Number representing the percentage of all IP addresses which should have traffic routed through Spec. The remaining percentage of IPs will be routed directly to the customer's downstream origin. This can be used for progressive onboarding / rollout.
customerKey String none A key provided by Spec to validate that traffic came from a customer-controlled service worker
disableSpecTraffic Boolean none When set to true, disables routing traffic to Spec Proxy only through the /spec_traffic path prefix. Generally, you do not want disable this feature, but it's provided so customers can control routing to this prefix.

The inlineMode configuration option is the only option that changes how Spec Proxy itself behaves. For more details on what inline mode means and what features of Spec Proxy are available to you when running in inline mode, please contact your Spec representative.

The customerKey option provides extra validation that we are only processing traffic that originated from your service workers. In general, this is redundant for inline processing, since we are processing traffic destined for the customer origin and validating it with a customer-provided SSL certificate. For mirror mode configurations, while we only allow traffic into Spec Proxy from your edge platform's IP address ranges and do not return any data in the responses to mirrored traffic, using the customerKey option is recommended. If this option is provided, we will validate this key prior to processing any mirrored traffic. The key is encrypted in transit with the rest of your mirrored traffic.

Runtime Configuration

You can use a Fastly ConfigStore to configure the Compute@Edge worker in realtime without deploying a new version of worker code. Integrating it into the Spec Proxy configuration object is quite simple. ConfigStore values are configured in your Compute service configuration in the Fastly web UI. Below is an example of how the addEventListener call from the above example changes to use the ConfigStore.

import { ConfigStore } from "fastly:config-store";

addEventListener("fetch", (event) => {
  // load up a fastly store for easy runtime configuration
  let store = new ConfigStore("SpecProxy");

  // Note: null is returned if the key isn't present, so the value
  // of inlineMode and disableSpecProxy would default to false
  let inlineMode = store.get("inline_mode") === "true";
  let disableSpecProxy = store.get("disable_spec_proxy") === "true";

  // configure our use of the spec library
  let config = {
    inlineMode,
    disableSpecProxy,
  };

  // only assign percentage of IPs if it's valid
  let percentageIPs = parseInt(store.get("percentage_of_ips"));
  if (!isNaN(percentageIPs)) {
    config.percentageOfIPs = percentageIPs;
  }

  event.respondWith(specProxyProcess(event, config));
});

Configuring Fastly Backends


Note: You do not need to configure backends when using the Dynamic Backends feature.


When you create your Compute service in your Fastly account, you will be presented with the service configuration UI. Within this UI are options to configure your Domain, e.g. www.example.com, and then your Origins. The Hosts menu option under Origins is where you configure your Fastly Backends in the UI for your Compute service. You will create two Hosts here, one for your origin server and the other for your Spec Proxy deployment.

Create the host for your origin server by clicking the Create a host button. Take note of the name you supply to the host configuration as this is the name of the backend that you'll use in the implementation example above when calling setFastlyBackends. Give this host the location of your origin server, for example this could be a load balancer that has an IP whitelist that only allows Fastly IPs to connect to it and is located at load-balancer.example.com. Most of the other options here you can configure as you would like, but the options that are particularly important are:

  • TLS from Fastly to your host
  • Verify certificate
  • Certificate hostname
  • SNI hostname
  • Override host

These options configure secure connections to your origin server. Set TLS from Fastly to your host and Verify certificate to Yes and set the other three options to their appropriate value for your origin. Likely, this will be the value of your Domain configuration, e.g. www.example.com.

Next, you will create the Spec Proxy host. Click Create a host to create a new entry and again take note of the name you provide as this will be the backend you use in the implementation example above when calling setFastlyBackends. You'll set the same options in this configuration as the ones listed above and you can set them them to the same values as the host for your origin server with the exception of Certificate hostname and SNI hostname. These two values will have .spec-internal.com appended to your hostname above, e.g. www.example.com becomes www.example.com.spec-internal.com. This will inform Spec Proxy with the correct location of your origin server for processing.

When you are done, you will have two Hosts, one for your origin server and the other for your Spec Proxy deployment. Fill in the setFastlyBackends function call in the example above with the names of these hosts. When providing the hostname of Spec Proxy, it will be the value of your origin server with .spec-internal.com appeneded to the end. For example, the host www.example.com will become www.example.com.spec-internal.com.

Summary:

Origin

Configuration Name Configuration Value
Name origin
Address www.example.com
Enable TLS Yes
Verify Certificate Yes
Certificate hostname www.example.com
SNI hostname www.example.com (or check "match certificate hostname")
Override host www.example.com

Spec Proxy

Configuration Name Configuration Value
Name spec-proxy
Address www.example.com.spec-internal.com
Enable TLS Yes
Verify Certificate Yes
Certificate hostname www.example.com.spec-internal.com
SNI hostname www.example.com.spec-internal.com (or check "match certificate hostname")
Override host www.example.com

Package Sidebar

Install

npm i @specprotected/spec-proxy-fastly-worker

Weekly Downloads

8

Version

0.2.2

License

MPL 2.0

Unpacked Size

37.7 kB

Total Files

7

Last publish

Collaborators

  • mplanchard
  • mattkharrl
  • rkelmenson-spec
  • spec-jay
  • tcheeseman-spec
  • justin-at-spec
  • grant_spec
  • scottspectrust