---
title: Backblaze B2 Cloud Storage
summary: null
url: >-
  https://www.fastly.com/documentation/guides/integrations/non-fastly-services/backblaze-b2-cloud-storage
---


[Backblaze B2 Cloud Storage](https://www.backblaze.com/b2/cloud-storage.html) (B2) public and private buckets can be used as [origins](/guides/getting-started/hosts/working-with-hosts) with Fastly.

> **HINT:** Backblaze offers an [integration discount](/guides/integrations/non-fastly-services/data-transfer-with-backblaze-b2) that eliminates  egress costs to Fastly when using Backblaze B2 Cloud Storage as an origin. In addition, Backblaze also offers a [migration program](https://www.backblaze.com/b2/solutions/datatransfer/cloud-to-cloud.html) designed to offset many of the data transfer costs associated with switching from another cloud provider to Backblaze. To ensure your migration has minimal downtime, [contact support](https://support.fastly.com).

## Before you begin

Before you begin the setup and configuration steps required to use B2 as an origin, keep in mind the following:

* __You must have a valid Backblaze account.__ Before you can create a new bucket and upload files to it for Fastly to use, you must first [create a Backblaze account](https://www.backblaze.com/b2/docs/quick_account.html) at the Backblaze website.
* __Backblaze provides two ways to set up and configure B2.__ B2 can be set up and configured using either the [Backblaze web interface](https://www.backblaze.com/blog/b2-for-beginners-inside-the-b2-web-interface/) or the B2 command line tool. Either creation method works for *public* buckets. To use *private* buckets, however, you must use the B2 command line tool. For additional details, including instructions on how to install the command line tool, read [Backblaze's B2 documentation](https://www.backblaze.com/b2/docs/quick_command_line.html).
* __Backblaze provides two APIs for integrating with Backblaze B2 Cloud Storage.__ You can use the [B2 Cloud Storage API](https://www.backblaze.com/b2/docs/) or the [S3 Compatible API](https://www.backblaze.com/b2/docs/s3_compatible_api.html) to make your B2 data buckets available through Fastly. The S3 Compatible API allows existing S3 integrations and SDKs to integrate with B2. Buckets and their specific application keys created prior to May 4th, 2020, however, cannot be used with the S3 Compatible API. For more information, read Backblaze's article on [Getting Started with the S3 Compatible API](https://www.backblaze.com/docs/cloud-storage-s3-compatible-api).

## Using Backblaze B2 as an origin

To use B2 as an origin, follow the steps below.

### Creating a new bucket

Data in B2 is stored in buckets. Follow these steps to create a new bucket via the B2 web interface.

> **HINT:** The Backblaze [CLI docs](https://www.backblaze.com/b2/docs/quick_bucket.html) provide details on how to create a bucket using the command line tool.

1. [Log in to your Backblaze account](https://secure.backblaze.com/user_signin.htm). Your Backblaze account settings page appears.
1. Click **Buckets**.
1. Click **Create a Bucket**.

   ![Backblaze B2 New Bucket window](/img/backblaze-b2-new-bucket.png)

1. In the **Bucket Unique Name** field, enter a unique bucket name. Each bucket name must be at least 6 alphanumeric characters and can only use hyphens (`-`) as separators, not spaces.
1. Click **Create a Bucket**. The new bucket  appears in the list of buckets on the B2 Cloud Storage Buckets page.
1. [Upload a file](#uploading-files-to-a-new-bucket) to the new bucket you just created.

> **IMPORTANT:** Buckets created prior to May 4th, 2020 cannot be used with the S3 Compatible API. If you do not have any S3 Compatible buckets, Backblaze recommends creating a new bucket.

### Uploading files to a new bucket

Once you've created a new bucket in which to store your data, follow these steps to upload files to it via the B2 web interface.

> **HINT:** The Backblaze [CLI docs](https://www.backblaze.com/b2/docs/quick_upload.html) provide details on how to upload files using the command line tool.

1. Click **Buckets** in the B2 web interface. The B2 Cloud Storage Buckets page appears.
1. Find the bucket details for the bucket you just created.
1. Click **Upload/Download**.
1. Click **Upload**.
1. Either drag and drop any file into the window or click to use the file selection tools to find a file to be uploaded. The name and type of file at this stage doesn't matter. Any file will work. Once uploaded, the name of the file appears in the list of files for the bucket.
1. [Find your bucket's assigned hostname](#finding-your-buckets-assigned-hostname) so you can set up a Fastly service that interacts with B2.

### Finding your bucket's assigned hostname

To set up a Fastly service that interacts with your B2, you will need to know the hostname Backblaze assigned to the [bucket you created](#creating-a-new-bucket) and [uploaded files](#uploading-files-to-a-new-bucket) to.

Find your hostname in one of the following ways:

* __Via the B2 web interface when you're using the standard B2 Cloud Storage API.__ Click the name of the file you just uploaded and examine the **Friendly URL** and **Native URL** fields in the Details window that appears. The hostname is the text after the `https://` designator in each line that matches exactly.

  ![Backblaze B2 Download Host](/img/backblaze-b2-download-host.png)

* __Via the command line and the B2 Cloud Storage API.__ Run the `b2 get-account-info` command on the command line and use the hostname from the `downloadUrl` attribute.

* __Via the B2 web interface when you're using the S3 Compatible API.__ Click **Buckets** and find the bucket details for the bucket you just created. The hostname is the text in the Endpoint field.

  ![Backblaze B2 S3 Endpoint](/img/backblaze-b2-s3-endpoint.png)

### Creating a Backblaze application key for private buckets

Your Backblaze master application key controls access to all buckets and files on your Backblaze account. If you plan to use a Backblaze B2 *private* bucket with Fastly, you should create an application key specific to the bucket.

> **HINT:** The Backblaze documentation provides more information [about application keys](https://www.backblaze.com/b2/docs/application_keys.html). When creating application keys for your private bucket, we recommend using the least amount of privileges possible. You can optionally set the key to expire after a certain number of seconds (up to a maximum of 1000 days or 86,400,000 seconds). If you choose an expiration, however, you'll need to periodically create a new application key and then update your Fastly configuration accordingly each time.

#### Via the web interface

To create an application key via the B2 web interface:

1. Click **App Keys**.
1. Click **Add a New Application Key**.

   ![Backblaze B2 New Application Key](/img/backblaze-b2-new-application-key.png)

1. Fill out the fields of the **Add Application Key** controls as follows:
   * In the **Name of Key** field, enter the name of your private bucket key. Key names are alphanumeric and can only use hyphens (`-`) as separators, not spaces.
   * From the **Allow access to Bucket(s)** menu, select the name of your private bucket.
   * From the **Type of Access** controls, select **Read Only**.
   * Leave the remaining optional controls and fields blank.
1. Click **Create New Key**.

   ![Backblaze B2 Created Application Key](/img/backblaze-b2-created-application-key.png)

1. Immediately note the **keyID** and the **applicationKey** from the success message. You'll use this information when you implement header-based authentication with private objects.

#### Via the command line

To create an application key from the command line, run the `create-key` command as follows:

```term copy
$ b2 create-key --bucket <bucketName> <keyName> shareFiles,listBuckets
```

where `<bucketName> <keyName>` represents the name of the bucket and key you created. For example:

```term copy
$ b2 create-key --bucket this-is-an-example-bucket Fastly-Private-Bucket-Key shareFiles,listBuckets
```

The **keyID** and the **applicationKey** are the two values returned.

> **IMPORTANT:** Application keys created prior to May 4th, 2020 cannot be used with the S3 Compatible API.

### Creating a new service

To create a new Fastly service, you must first create a new domain and then create a new host and edit it to accept traffic for B2. Instructions to do this appear in our guide to [creating a new service](/guides/getting-started/services/about-services). While completing these instructions, keep the following in mind:

1. When you [create the new host](/guides/getting-started/hosts/working-with-hosts#adding-a-host), enter the  [B2 bucket's hostname](#finding-your-buckets-assigned-hostname) in the **Hosts** field on the **Origins** page.
1. When you [edit the host](/guides/getting-started/hosts/working-with-hosts#editing-a-host) details on the **Edit this host page**, confirm the Transport Layer Security (TLS) area information for your host. Specifically, make sure you:
   * secure the connection between Fastly and your origin.
   * enter your [bucket's hostname](#finding-your-buckets-assigned-hostname) in the **Certificate hostname** field.
   * select the checkbox to match the SNI hostname to the Certificate hostname (it appears under the SNI hostname field).
1. *(Optional)* Also when you edit the host, enable shielding by choosing the appropriate [shielding location](/guides/concepts/shielding/#choosing-a-shield-location) from the **Shielding** menu. When using B2 Cloud Storage, this means you must choose a shielding location closest to the most appropriate Backblaze data center. For the data centers closest to:
   * Sacramento, California (in the US West region), choose **San Jose (SJC)** from the **Shielding** menu.
   * Phoenix, Arizona (in the US West region), choose **Palo Alto (PAO)** from the **Shielding** menu.
   * Amsterdam, Netherlands (in the EU central region), choose **Amsterdam (AMS)** from the **Shielding** menu.
1. Decide whether or not you should specify an override host:
   * If you're using the S3 Compatible API, skip this step and don't specify an override host.
   * If you're not using the S3 Compatible API, in the **Override host** field, enter an appropriate address for your host (e.g., `s3-uswest-000.backblazeb2.com` or `f000.backblazeb2.com`).

## Using the S3 Compatible API

The S3 Compatible API can be used with both public and private objects.

### Using the S3 Compatible API with public objects

To use the S3 Compatible API with public objects, you will need to make sure the `Host` header contains the name of your B2 Bucket. There are two ways to do this, both of which require you to get your region name which will be the 2nd part of your S3 Endpoint. So if your S3 Endpoint is `s3.us-west-000.backblazeb2.com`, this means your region will be `us-west-000`.

1. In the **Origin** you created set the **Override host** field to `<bucket>.s3.<region>.backblazeb2.com` (e.g., `testing.s3.uswest-000.backblazeb2.com`).
1. Create a [VCL Snippet](/guides/full-site-delivery/fastly-vcl/vcl-snippets/using-vcl-snippets). When you create the snippet, select **within subroutine** to specify its placement and choose **miss** as the subroutine type. Then, populate the **VCL** field with the following code. Be sure to change specific values as noted to ones relevant to your own B2 bucket - in this case `var.b2Bucket` would be `"testing"` and `var.b2Region` would be `"uswest-000"`.

    ```vcl
    declare local var.b2Bucket STRING;
    declare local var.b2Region STRING;
    set var.b2Bucket = "YOUR_B2_BUCKET_NAME";   # Change this value to your own data
    set var.b2Region = "YOUR_B2_BUCKET_REGION"; # Change this value to your own data

    if (req.method == "GET" && !req.backend.is_shield) {
      set bereq.http.host = var.b2Bucket ".s3." var.b2Region ".backblazeb2.com";
    }
    ```

### Using the S3 Compatible API with private objects

To use a Backblaze B2 private bucket with Fastly, you must implement version 4 of [Amazon’s header-based authentication](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html). You can do this using [custom VCL](/guides/full-site-delivery/fastly-vcl/about-fastly-vcl).

Start by obtaining the following information from Backblaze (see [Creating a Backblaze application key for private buckets](#creating-a-backblaze-application-key-for-private-buckets)):

Item     | Description
--------------|-------------------------------------------------------------------------------------------------------------------------------------------------
Bucket name   | The name of your Backblaze B2 bucket. When you download items from your bucket, this is the string listed in the URL path or hostname of each object.
Region        | The Backblaze region code of the location where your bucket resides (e.g., `uswest-000`).
Access key    | The Backblaze keyID for the App Key that has at least read permission on the bucket.
Secret key    | The Backblaze applicationKey paired with the access key above.

Once you have this information, you can configure your Fastly service to authenticate against your B2 bucket using header authentication by calculating the appropriate header value in VCL.

Start by creating a [VCL snippet](/guides/full-site-delivery/fastly-vcl/vcl-snippets/using-vcl-snippets). Give it a meaningful name, such as `AWS protected origin`. When you create the snippet, select **within subroutine** to specify its placement and choose **miss** as the subroutine type. Then, populate the **VCL** field with the following code (be sure to change specific values as noted to ones relevant to your own AWS bucket):

```vcl
declare local var.b2AccessKey STRING;
declare local var.b2SecretKey STRING;
declare local var.b2Bucket STRING;
declare local var.b2Region STRING;
declare local var.canonicalHeaders STRING;
declare local var.signedHeaders STRING;
declare local var.canonicalRequest STRING;
declare local var.canonicalQuery STRING;
declare local var.stringToSign STRING;
declare local var.dateStamp STRING;
declare local var.signature STRING;
declare local var.scope STRING;

set var.b2AccessKey = "YOUR_B2_ACCESS_KEY";   # Change this value to your own data
set var.b2SecretKey = "YOUR_B2_SECRET_KEY";   # Change this value to your own data
set var.b2Bucket = "YOUR_B2_BUCKET_NAME";     # Change this value to your own data
set var.b2Region = "YOUR_B2_BUCKET_REGION";   # Change this value to your own data

if (req.method == "GET" && !req.backend.is_shield) {

  set bereq.http.x-amz-content-sha256 = digest.hash_sha256("");
  set bereq.http.x-amz-date = strftime({"%Y%m%dT%H%M%SZ"}, now);
  set bereq.http.host = var.b2Bucket ".s3." var.b2Region ".backblazeb2.com";
  set bereq.url = querystring.remove(bereq.url);
  set bereq.url = regsuball(urlencode(urldecode(bereq.url.path)), {"%2F"}, "/");
  set var.dateStamp = strftime({"%Y%m%d"}, now);
  set var.canonicalHeaders = ""
    "host:" bereq.http.host LF
    "x-amz-content-sha256:" bereq.http.x-amz-content-sha256 LF
    "x-amz-date:" bereq.http.x-amz-date LF
  ;
  set var.canonicalQuery = "";
  set var.signedHeaders = "host;x-amz-content-sha256;x-amz-date";
  set var.canonicalRequest = ""
    "GET" LF
    bereq.url.path LF
    var.canonicalQuery LF
    var.canonicalHeaders LF
    var.signedHeaders LF
    digest.hash_sha256("")
  ;

  set var.scope = var.dateStamp "/" var.b2Region "/s3/aws4_request";

  set var.stringToSign = ""
    "AWS4-HMAC-SHA256" LF
    bereq.http.x-amz-date LF
    var.scope LF
    regsub(digest.hash_sha256(var.canonicalRequest),"^0x", "")
  ;

  set var.signature = digest.awsv4_hmac(
    var.b2SecretKey,
    var.dateStamp,
    var.b2Region,
    "s3",
    var.stringToSign
  );

  set bereq.http.Authorization = "AWS4-HMAC-SHA256 "
    "Credential=" var.b2AccessKey "/" var.scope ", "
    "SignedHeaders=" var.signedHeaders ", "
    "Signature=" + regsub(var.signature,"^0x", "")
  ;
  unset bereq.http.Accept;
  unset bereq.http.Accept-Language;
  unset bereq.http.User-Agent;
  unset bereq.http.Fastly-Client-IP;
}
```

## Using the B2 API

The B2 API can be used with both public and private objects.

### Public objects

You'll need to make sure the URL contains your bucket name. You can do this using a **Header** object as follows:

1. Click **Create header** again to create another new header.

   ![creating an authorization header via the header page](/img/backblaze-b2-create-authorization-header.png)

1. Fill out the **Create a header** fields as follows:
   * In the **Name** field, enter `Rewrite B2 URL`.
   * From the **Type** menu, select **Request**, and from the **Action** menu, select **Set**.
   * In the **Destination** field, enter `url`.
   * From the **Ignore if set** menu, select **No**.
   * In the **Priority** field, enter `20`.
1. In the **Source** field, enter `"/file/<Bucket Name>" req.url`.
1. Click **Create**. A new Authorization header appears on the Content page.
1. <Partial name='step-activate-deploy' inline />

Alternatively create a [VCL Snippet](/guides/full-site-delivery/fastly-vcl/vcl-snippets/using-vcl-snippets). When you create the snippet, select **within subroutine** to specify its placement and choose **miss** as the subroutine type. Then, populate the **VCL** field with the following code. Be sure to change the variable to the name of your own B2 bucket.

```vcl
declare local var.b2Bucket STRING;
set var.b2Bucket = "YOUR_B2_BUCKET_NAME";   # Change this value to your own data

if (req.method == "GET" && !req.backend.is_shield) {
  set bereq.url = "/file/" var.b2Bucket bereq.url;
}
```

### Private objects

1. To use a Backblaze B2 private bucket with Fastly, you must obtain an `Authorization Token`. This must be obtained via the command line.
1. You'll now need to authorize the command line tool with [the application key you obtained](#creating-a-backblaze-application-key-for-private-buckets).

   ```term copy
   $ b2 authorize-account <keyID> <applicationKey>
   ```

1. You will now need to get an authorization token for the private bucket.

   ```term copy
   $ b2 get-download-auth <bucket>
   ```

   e.g.,

   ```term copy
   $ b2 get-download-auth testing
   ```

   This will create a token that is valid for 86400 seconds (i.e 1 day), the default. You can optionally change the expiration time from anywhere between 1s and 604,800 seconds (i.e 1 week).

   ```term copy
   $ b2 get-download-auth --duration 604800 testing
   ```

   Take note of the generated token.

> **HINT:** You will need to regenerate an authorization token and update your Fastly configuration before the end of the expiration time. A good way to do this would be through Fastly's [versionless dictionaries](/guides/full-site-delivery/dictionaries/about-dictionaries).

### Passing a generated token to Backblaze

There are two ways you can pass the generated token to Backblaze. The first is using an `Authorization` header. This is the recommended method.

1. Click **Create header** again to create another new header.

   ![creating an authorization header via the header page](/img/backblaze-b2-create-authorization-header.png)

1. Fill out the **Create a header** fields as follows:
   * In the **Name** field, enter `Authorization`.
   * From the **Type** menu, select **Request**, and from the **Action** menu, select **Set**.
   * In the **Destination** field, enter `http.Authorization`.
   * From the **Ignore if set** menu, select **No**.
   * In the **Priority** field, enter `20`.
1. In the **Source** field, enter the **Authorization Token** generated in the command line tool, surrounded by quotes. For example, if the token generated was `DEC0DEC0C0A`, then the **Source** field would be `"DEC0DEC0C0A"`
1. Click **Create**. A new Authorization header appears on the Content page.
1. <Partial name='step-activate-deploy' inline />

Alternatively, the second way is to pass an `Authorization` query parameter.

1. Click **Create header** again to create another new header.

   ![creating an authorization header via the header page](/img/backblaze-b2-create-authorization-param.png)

1. Fill out the **Create a header** fields as follows:
   * In the **Name** field, enter `Authorization`.
   * From the **Type** menu, select **Request**, and from the **Action** menu, select **Set**.
   * In the **Destination** field, enter `url`.
   * From the **Ignore if set** menu, select **No**.
   * In the **Priority** field, enter `20`.
1. In the **Source** field, enter the header authorization information using the following format:

    ```plain
    querystring.set(req.url, "Authorization", "<Authorization Token>")
    ```

    Using the previous example, that would be:

    ```plain
    querystring.set(req.url, "Authorization", "DEC0DEC0C0A")
    ```

1. Click **Create**. A new Authorization header appears on the Content page.
1. <Partial name='step-activate-deploy' inline />

> **NOTE:** <Partial name='third-party-integrations' inline />

## Related content

* [Working with hosts](/guides/getting-started/hosts/working-with-hosts)
* [Data transfer with Backblaze B2](/guides/integrations/non-fastly-services/data-transfer-with-backblaze-b2)
* [VCL reference](/reference/vcl/)
