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.
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.
Generate a new private key, or use an existing private key. The key can be in either JSON or PKCS12 format.
Expand for instructions on how to generate a private key.
- Open the list of credentials in the Google Cloud Platform Console.
- Click Create credentials.
- Select Service account key.
A Create service account key window opens.
- Click the drop-down box below Service account, then click New service account.
- Enter a name for the service account in Name.
- Choose a Cloud Storage Role that grants the service account the desired level of access.
- Use the default Service account ID or generate a different one.
- Select the Key type: JSON or P12.
- Click Create.
A Service account created window is displayed and the private key for the Key type you selected is downloaded automatically. If you selected a P12 key, the private key's password ("notasecret") is displayed.
- Click Close.
For more information on private keys and service accounts, see Service Account Authentication.
Construct the string to be signed.
Choose the HTTP_Verb (such as
DELETE) that the requests utilizing the signed URL must use.
Add an MD5 digest value if you want to include the value in the requests that will use the signed URL.
Content-Typeof the object if the requests that will use the signed URL are going to have a
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).
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-sha256headers, even if the requests to access the associated object will use them.
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
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
GET rmYdCNHKFXam78uCt7xQLw== text/plain 1388534400 x-goog-encryption-algorithm:AES256 x-goog-meta-foo:bar,baz /bucket/objectname
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])
[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.
Base64 encode the signature.
For example, in Python you can use the following code to encode your signature:
encoded_signature = base64.b64encode(signature)
Assemble the URL.
After you construct the query string and sign it, assemble the URL as follows:
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:
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
/). These values must be replaced by safe encodings (
Concatenate the URL you want to distribute as follows:
BASE_URL + "?GoogleAccessId=" + GOOGLE_ACCESS_STORAGE_ID + "&Expires=" + EXPIRATION + "&Signature=" + URL_ENCODED_SIGNATURE
BASE_URLcontains the URL you created in part a.
GOOGLE_ACCESS_STORAGE_IDcontains the email form of the client ID.
EXPIRATIONcontains the same value that you used in the query string you signed.
URL_ENCODED_SIGNATUREcontains the signature you encoded in part b.
Here is a sample completed URL:
https://storage.googleapis.com/google-testbucket/testdata.txt?GoogleAccessId= email@example.com&Expires=1331155464&Signature=BCl z9e4UA2MRRDX62TPd8sNpUCxVsqUDG3YGPWvPcwN%2BmWBPqwgUYcOSszCPlgWREeF7oPGowkeKk 7J4WApzkzxERdOQmAdrvshKSzUHg8Jqp1lw9tbiJfE2ExdOOIoJVmGLoDeAGnfzCd4fTsWcLbal9 sFpqXsQI8IQi1493mw%3D