Canonical requests

Canonical requests define the elements of a request that a user must includewhen sending V4 signature-authenticated requests, such assigned URLs,to Cloud Storage.

Overview

Acanonical request is a string that represents a specific HTTP request toCloud Storage. You use a canonical request along with a cryptographickey, such as an RSA key, to create asignature that is then includedin the actual request as authentication.

A canonical request includes information such as the HTTP verb, query stringparameters, and headers expected to be used in the actual request,as well as the object, bucket, or other resource to be requested.

A canonical request ensures that when Cloud Storage receives therequest, it can calculate the same signature that you calculated. If yourversion and the version calculated by Cloud Storagedon't match, the request fails.

Structure

Canonical requests have the following structure, including the use of newlinesbetween each element:

HTTP_VERBPATH_TO_RESOURCECANONICAL_QUERY_STRINGCANONICAL_HEADERSSIGNED_HEADERSPAYLOAD

HTTP verbs

Signed requests can use the following HTTP verbs, which must be specified aspart of the canonical request:

  • DELETE
  • GET
  • HEAD
  • POST1
  • PUT

1 Signed URLs can only be used forPOST requests that initiate aresumable upload. SeeUsing signed URLs with resumable uploads for moreinformation.

Resource path

Canonical requests include the path to the resource that the request applies to.The path to the resource is everything that follows the hostname but precedesany query string.

For example, if the Cloud Storage URL ishttps://storage.googleapis.com/example-bucket/cat-pics/tabby.jpeg,then the path to the resource is/example-bucket/cat-pics/tabby.jpeg.

If you use an alternative Cloud Storage URL such ashttps://example-bucket.storage.googleapis.com/cat-pics/tabby.jpegthen the path to the resource is/cat-pics/tabby.jpeg.

For additional URL endpoints that can be used with signed URLs, seeXML API request endpoints.

When defining the resource path, you mustpercent encode thefollowing reserved characters:?=!#$&'()*+,:;@[]" Any other percent encodingused in the URL should also be included in the resource path.

Canonical Query string

Canonical requests specify each query string parameter that will be subsequentlyincluded in any signed request that uses the relevant signature, with theexception of theX-Goog-Signature orX-Amz-Signature query string parameter.The query string specified in the canonical request is called thecanonical query string

The query string is everything that follows the question mark (?) at the endof the resource path.

For example, if the Cloud Storage URL ishttps://storage.googleapis.com/example-bucket/cat-pics/tabby.jpeg?generation=1360887697105000&userProject=my-project,then the query string isgeneration=1360887697105000&userProject=my-project.

When constructing the canonical query string:

  • The parameters in the query string must be sorted by name using alexicographical sort by code point value.

  • Each parameter in the query string must be separated with&.

  • If your canonical query string is empty, this portion of the overallcanonical request is just a new line (\n).

Required query string parameters

Most query string parameters are added as needed, but the followingmustbe included in your canonical request when you intend to use it to make asigned URL:

  • X-Goog-Algorithm: The algorithm you will use to sign the URL. Valid valuesareGOOG4-RSA-SHA256 andGOOG4-HMAC-SHA256.
  • X-Goog-Credential: The credentials you will use to sign the URL. Credentialsconsist of an authorizer and acredential scope given in the format:AUTHORIZER%2FCREDENTIAL_SCOPE. Theauthorizer can be aservice account name or anHMAC key access ID.
  • X-Goog-Date: The date and time the signed URL becomes usable, in theISO 8601 basic formatYYYYMMDD'T'HHMMSS'Z'.
  • X-Goog-Expires: The lifetime of the signed URL, measured in seconds fromX-Goog-Date. The longest expiration value is 604800 seconds (7 days).
  • X-Goog-SignedHeaders: A semicolon-separated list of names of headersdefined in the canonical request. These are also known assigned headers.host must be one of the header names.

These query string parameters subsequently must be used in the signed URLitself, along with theX-Goog-Signature query string parameter, which containsthe signature authenticating the request.

Note: Cloud Storage also accepts these query string parameters ifthey are consistently prefixed withX-Amz- instead ofX-Goog-.

Canonical Headers

Canonical requests include any headers thatmust be subsequently included insigned requests that use the relevant signature. However, such signed requestscan include additional headers that were not specified in the canonicalrequest, except as noted inrequired headers. Headersspecified in the canonical request are calledcanonical headers.

Canonical headers can include custom headers as well asextension headersthat begin withx-goog-.

When specifying canonical headers, keep in mind the following:

  • Make all header names lowercase.
  • Sort all headers by header name using a lexicographical sort by code pointvalue.
  • Separate each header with a newline (\n).
  • Eliminate duplicate header names by creating one header name with acomma-separated list of values. Be sure there is no whitespace between thevalues, and be sure that the order of the comma-separated list matches theorder that the headers appear in your request. For more information, seeRFC 7230 section 3.2.
  • Replace any folding whitespace or newlines (CRLF or LF) with a single space.For more information about folding whitespace, seeRFC 7230, section 3.2.4..
  • Remove any whitespace around the colon that appears after the header name.

    For example, using the custom headerx-goog-acl: private without removingthe space after the colon returns a403 Forbidden error, because therequest signature you calculate does not match the signatureCloud Storage calculates.

Example

If you have the following set of headers:

host: storage.googleapis.comcontent-type: text/plainx-goog-meta-reviewer: janex-goog-meta-reviewer: john

The construction of the canonical headers in the canonical request would be:

content-type:text/plainhost:storage.googleapis.comx-goog-meta-reviewer:jane,john
Note: In these examples, newlines are shown as actual new lines and not\n.

Required canonical headers

Most headers, such ascontent-type, are added as needed, but the followingheaders must always be defined in the canonical headers if you intend to usethem in the signed request:

Signed headers

Asigned header is the name portion of a canonical header.

To create the signed headers list, convert all header names to lowercase, sortthem by character code, and use a semicolon (;) to separate each.

Example

If you have the following set of headers:

host: storage.googleapis.comcontent-type: text/plainx-goog-meta-reviewer: janex-goog-meta-reviewer: john

The construction of the signed headers in the canonical request would be:

content-type;host;x-goog-meta-reviewer

Payload

  • If your canonical request will be used to create asigned URL, this valueshould be the stringUNSIGNED-PAYLOAD.

  • If your canonical request will be used to create a signature for use in anAuthorization header:

    • UseUNSIGNED-PAYLOAD if you want to allow arbitrary payloads as part ofthe request.

    • UseUNSIGNED-PAYLOAD if the request will initiate a resumable upload,because thex-goog-content-sha256 header is ignored forresumable uploads.

    • If you want to allow only a specific payload, this value should be alowercase, hex-encoded, SHA-256 hash of the intended payload. To requirean empty payload, use an empty string as the input to the hash function.An example of a hashed payload (in this case an empty payload) is:

      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Example

The following is an example of a properly formed canonical request, withnewlines shown as actual new lines and not\n:

GET/example-bucket/tabby.jpeghost:storage.googleapis.comx-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855x-amz-date:20190301T190859Zhost;x-amz-content-sha256;x-amz-datee3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.