Creating Signed URLs with a Program

This page describes how to programmatically create signed URLs, which are a mechanism for query string authentication for buckets and objects. Signed URLs are one way to control access to buckets and objects. A signed URL is associated with a bucket or object and gives time-limited read or write access to that specific resource. Anyone in possession of the URL has the access granted by the URL, regardless of whether they have a Google account.

To learn more about Signed URLs, read the Overview of Signed URLs. To learn how to create signed URLs quickly using gsutil, read Creating Signed URLs with gsutil.

Creating a signed URL with a program

You can create a program that generates signed URLs in a number of different languages. Such a program needs to implement the steps for generating a signed URL that are outlined below.

  1. Generate a new private key, or use an existing private key. The key can be in either JSON or PKCS12 format.

    For more information on private keys and service accounts, see Service Account Authentication.

  2. Construct the string to be signed.

    1. Choose the HTTP_Verb (such as GET, PUT, or DELETE) that the requests utilizing the signed URL must use.

    2. Add an MD5 digest value if you want to include the value in the requests that will use the signed URL.

    3. Specify the Content-Type of the object if the requests that will use the signed URL are going to have a Content-Type header.

    4. Specify the timestamp (in seconds since the Unix Epoch) for when the signed URL expires (that is, when it no longer gives access to the associated object).

    5. Specify any extension headers, separated by newlines, if the requests that will use the signed URL are going to contain such headers. However, do not specify the x-goog-encryption-key or x-goog-encryption-key-sha256 headers, even if the requests to access the associated object will use them.

    6. Specify the path to the resource, beginning at the bucket level.

    You can find a table describing each of the components in this string on the Overview of Signed URLs page.

    A signature string containing only the required components might look like the following (note that newlines are shown as actual new lines and not \n):

    GET
     
     
    1388534400
    /bucket/objectname
    

    Alternatively, the following signature string contains every component and applies to an object with a customer-supplied encryption key (note that newlines are shown as actual new lines and not \n):

    GET
    rmYdCNHKFXam78uCt7xQLw==
    text/plain
    1388534400
    x-goog-encryption-algorithm:AES256
    x-goog-meta-foo:bar,baz
    /bucket/objectname
    

  3. Sign the string.

    In order to sign the string, you must have an OAuth client ID and private keys for a service account type application, as detailed in the first step of this guide.

    Sign the string you constructed using RSA signatures with SHA256 to authenticate requests.

    For example, in Python you can use the following code to sign your string:

    from oauth2client.service_account import ServiceAccountCredentials
    creds = ServiceAccountCredentials.from_json_keyfile_name([KEY_FILENAME])
    client_id = creds.service_account_email
    signature = creds.sign_blob([SIGNATURE_STRING])[1]
    

    where:

    • [KEY_FILENAME] is the filename containing your private key.
    • [SIGNATURE_STRING] is the string you constructed for signing.

    Within a Google App Engine application, you can use the App Engine App Identity service to sign your string.

  4. Base64 encode the signature.

    For example, in Python you can use the following code to encode your signature:

    encoded_signature = base64.b64encode(signature)
    

  5. Assemble the URL.

    After you construct the query string and sign it, assemble the URL as follows:

    1. Create the base URL, which refers to the resource, making sure you use the same value as you used in the query string you just signed. For example:

      https://storage.googleapis.com/google-testbucket/testdata.txt

    2. Encode characters in the signature you created as needed so that they can be used in the URL.

      The Base64 encoded signature may contain characters not legal in URLs (specifically + and /). These values must be replaced by safe encodings (%2B and %2F, respectively).

    3. Concatenate the URL you want to distribute as follows:

      BASE_URL + "?GoogleAccessId=" + GOOGLE_ACCESS_STORAGE_ID + "&Expires="
      + EXPIRATION + "&Signature=" + URL_ENCODED_SIGNATURE

      where:

      • BASE_URL contains the URL you created in part a.
      • GOOGLE_ACCESS_STORAGE_ID contains the email form of the client ID.
      • EXPIRATION contains the same value that you used in the query string you signed.
      • URL_ENCODED_SIGNATURE contains the signature you encoded in part b.

    Here is a sample completed URL:

    http://storage.googleapis.com/google-testbucket/testdata.txt?GoogleAccessId=
    1234567890123@developer.gserviceaccount.com&Expires=1331155464&Signature=BCl
    z9e4UA2MRRDX62TPd8sNpUCxVsqUDG3YGPWvPcwN%2BmWBPqwgUYcOSszCPlgWREeF7oPGowkeKk
    7J4WApzkzxERdOQmAdrvshKSzUHg8Jqp1lw9tbiJfE2ExdOOIoJVmGLoDeAGnfzCd4fTsWcLbal9
    sFpqXsQI8IQi1493mw%3D

Back to top

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

Cloud Storage Documentation