Cross-Origin Resource Sharing Rules
    • Dark
      Light

    Cross-Origin Resource Sharing Rules

    • Dark
      Light

    Article Summary

    Web browsers generally limit a web page's access to content from other sites. Backblaze B2 Cloud Storage supports Cross-Origin Resource Sharing (CORS) to allow users to lift those restrictions.

    Web browsers group pages by their origin, which is the combination of their protocol (for example, HTTP or HTTPS), their hostname (for example, f001.backblazeb2.com), and their port number (usually 80 or 443 for HTTP and HTTPS). While images can be embedded from any origin, by default, JavaScript will typically use only XMLHttpRequests to get content from the same origin as the HTML page that included the script. Similarly, by default, WebGL will only load textures from the same origin.

    Backblaze B2 supports the standard CORS mechanism to allow Backblaze B2 customers to share the content of their buckets with web pages hosted outside of Backblaze B2. With CORS, before making a non-simple, cross-origin request, a browser makes a preflight request to ask the server if it can make the cross-origin request. By default, the Backblaze B2 servers will deny preflight requests. Adding CORS rules to your bucket tells Backblaze B2 which preflight requests to approve. CORS does not replace normal Backblaze B2 authorization mechanisms. For more information, see CORS on Non-Public Buckets.

    When a CORS preflight or cross-origin download is requested, B2 evaluates the CORS rules on the file's bucket. Rules can be set when you create the bucket with b2_create_bucket, or updated on an existing bucket using b2_update_bucket.

    CORS rules only affect Backblaze B2 operations in their allowedOperations list. Every rule must specify at least one in their allowedOperations. You may add up to 100 CORS rules to each of your buckets. Each rule must be less than 1,000 bytes long. A rule's size in bytes is computed by adding up the byte lengths of the UTF-8 representation of each string in corsRuleName, allowedOrigins, allowedOperations, allowedHeaders, and exposeHeaders.

    Backblaze B2 uses the first rule that matches the request. A CORS preflight (OPTIONS) request matches a rule if the origin header matches one of the rule's allowedOrigins, if the operation is in the rule's allowedOperations, (case-sensitive) and if every value in the Access-Control-Request-Headers is in the rule's allowedHeaders. A non-preflight request (GET or POST) matches a rule if the origin header matches one of the rule's allowedOrigins and if the operation is in the rule's allowedOperations.

    CORS for Uploads

    You can set up CORS rules to allow b2_upload_file and b2_upload_part calls to be performed from web browsers. For more information about uploading, see Upload Files with the CLI.

    CORS is not supported for mostBackblaze B2 APIs, so you must perform them in your server, not in a web page. For uploading, this includes calls such as:

    • b2_authorize_account
    • b2_get_upload_url
    • b2_start_large_file
    • b2_get_upload_part_url
    • b2_finish_large_file

    Your code is responsible for retrying when uploads don't work immediately. The upload URLs and upload authTokens that are returned by b2_get_upload_url and b2_get_upload_part_url can be used to upload to any path in the bucket, so be sure you trust the users that you give them to and the application.

    To allow b2_upload_file, you will need to add some headers to allowedHeaders in your CORS rule, including:

    • authorization
    • X-Bz-File-Name
    • X-Bz-Content-Sha1

    To allow b2_upload_part, you will need to add some headers to allowedHeaders in your CORS rule, including:

    • authorization
    • X-Bz-Part-Number
    • X-Bz-Content-Sha1

    You may choose to allow other headers, such as ones that start with X-Bz-Info-.

    CORS Rule Structure

    Each CORS rule can have the following parameters:

    corsRuleName
    required

    A name for humans to recognize the rule in a user interface. Names must be unique within a bucket. Names can consist of upper-case and lower-case English letters, numbers, and a hyphen (-). No other characters are allowed. A name must be at least 6 characters long and can be up to 63 characters long. Names that start with b2- are reserved for Backblaze use.

    Examples of a valid name:

    • myPhotosSite
    • allowAnyHttps
    • backblaze-images

    allowedOrigins
    required

    A non-empty list specifying which origins the rule covers. Each value may have one of many formats:

    • The origin can be fully specified, such as http://www.example.com:8180 or https://www.example.com:4433.
    • The origin can omit a default port, such as https://www.example.com.
    • The origin may have a single asterisk (*) as part of the domain name, such as https://*.example.com, https://*:8443, or https://*.
    • The origin may be https to match any origin that uses HTTPS. (This is broader than https://* because it matches any port.)
    • Finally, the origin can be a single asterisk (*) to match any origin.

    If any entry is *, it must be the only entry. There can be at most one https entry and no entry after it may start with https:.

    allowedOperations
    required

    A list specifying which operations the rule allows. At least one value must be specified. All values must be from the following list.

    Backblaze B2 Native API Operations

    • b2_download_file_by_name
    • b2_download_file_by_id
    • b2_upload_file
    • b2_upload_part

    Backblaze B2 S3-Compatible API Operations
    (There is one for each supported HTTP method, mapping to the AllowedMethod element in S3’s CORSRule object.)

    • s3_delete
    • s3_get
    • s3_head
    • s3_post
    • s3_put

    allowedHeaders
    optional

    If present, this is a list of headers that are allowed in the Access-Control-Request-Headers header value of the request for a preflight OPTION. Each value may have one of many formats:

    • It may be a complete header name, such as x-bz-content-sha1.
    • It may end with an asterisk, such as x-bz-info-*.
    • Finally, it may be a single asterisk (*) to match any header.

    If any entry is *, it must be the only entry in the list. If this list is missing, it is treated as a list with no entries.

    exposeHeaders
    optional

    If present, this is a list of headers that may be exposed to an application inside the client (for example, exposed to JavaScript in a browser). Each entry in the list must be a complete header name (for example, x-bz-content-sha1). If this list is missing or empty, no headers will be exposed.

    maxAgeSeconds
    required

    This specifies the maximum number of seconds that a browser may cache the response to a preflight request. The value must not be negative and it must not be more than 86,400 seconds (one day).

    As an example, the following rule allows downloads, including range requests, from any HTTPS origin and will tell browsers that it can expose the x-bz-content-sha1 header to the web page.

    [
        {
          "corsRuleName": "downloadFromAnyOrigin",
          "allowedOrigins": [
            "https"
          ],
          "allowedHeaders": ["range"],
          "allowedOperations": [
            "b2_download_file_by_id",
            "b2_download_file_by_name"
          ],
          "exposeHeaders": ["x-bz-content-sha1"],
          "maxAgeSeconds": 3600
        }
    ]

    CORS on Private Buckets

    Requests still need to present normal Backblaze B2 authorization tokens to download content from non-public buckets. Additionally, Backblaze B2 denies CORS preflight requests that use the account authorization token that is returned by b2_authorize_account. Only more restricted authorization tokens are allowed, such as those that are returned by b2_get_download_authorization. This restriction exists because you should not send your real account credentials or authorization to web browsers. The authorization token that is returned by b2_get_download_authorization is valid only for b2_download_file_by_name. Together, these restrictions mean that you cannot use b2_download_file_by_id on a private bucket, even with a CORS rule allowing it.

    Because browsers are specifically mandated to strip user-headers from CORS requests, it is not possible to use the AUTHORIZATION header in download requests from private buckets when those requests come from a browser. Browsers do not include most headers when doing a CORS preflight. Therefore, when using CORS for downloads on a private bucket, you need to use a download authorization token and include it in the download URL as a query parameter, not as a header. Be sure to capitalize only the first letter of "Authorize," as in the following example:

    https://f000.backblazeb2.com/file/buck/my.js?Authorization=3_20181026...dnld

    The following example uses the alternative authentication method of appending the authentication string to the download URL to download the file helloworld.html from a public bucket publichello:

    https://f000.backblaze2.com/files/publichello/helloworld.html

    The following example shows how to download a similar file from a bucket privatehello:

    https://f000.backblaze2.com/files/privatehello/helloworld.html?Authorization=3_20181021181348_1654aeb9046d1bcdd60dff3c_06314b74a8fc99f72def5a18c1b3c87ab35f329c_000_20181030221348_0000_ dnld
    Note
    Although web standards are to ignore case in the headers, URLS are case sensitive. You must capitalize the first letter of "Authorization" with the remainder in lower case.

    Using CORS with the S3-Compatible API and Native API

    The S3-Compatible API supports the PutBucketCors, GetBucketCors, and DeleteBucketCors API calls. For a guide on how to use these API calls, see the AWS CORS documentation.

    The accepted format for the calls is the same as the AWS S3 equivalents. Any differences with our implementation are documented in the S3-Compatible API.

    When viewing CORS rules that are set for the S3-Compatible API via the Native API, you see the following behavior:


    Was this article helpful?


    What's Next