Allows the creation of URLs to provide temporary access to objects. For example, a website may wish to provide a link to download a large object in OpenStack Object Storage, but the Object Storage account has no public access. The website can generate a URL that provides GET access for a limited time to the resource. When the web browser user clicks on the link, the browser downloads the object directly from Object Storage, eliminating the need for the website to act as a proxy for the request. If the user shares the link with all his friends, or accidentally posts it on a forum, the direct access is limited to the expiration time set when the website created the link.
A temporary URL is the typical URL associated with an object, with two additional query parameters:
temp_url_sigA cryptographic signature
temp_url_expiresAn expiration date, in Unix time
An example of a temporary URL:
https://swift-cluster.example.com/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709&
temp_url_expires=1323479485
To create temporary URLs, first set the
X-Account-Meta-Temp-URL-Key header on your
Object Storage account to an arbitrary string. This string serves
as a secret key. For example, to set a key of
b3968d0207b54ece87cccc06515a89d4 by using the
swift command-line tool:
$ swift post -m "Temp-URL-Key:b3968d0207b54ece87cccc06515a89d4"Next, generate an HMAC-SHA1 (RFC 2104) signature to specify:
Which HTTP method to allow (typically
GETorPUT)The expiry date as a Unix timestamp
The full path to the object
The secret key set as the
X-Account-Meta-Temp-URL-Key
Here is code generating the signature for a GET for 24
hours on
/v1/AUTH_account/container/object:
import hmac
from hashlib import sha1
from time import time
method = 'GET'
duration_in_seconds = 60*60*24
expires = int(time() + duration_in_seconds)
path = '/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30/container/object'
key = 'mykey'
hmac_body = '%s\n%s\n%s' % (method, expires, path)
sig = hmac.new(key, hmac_body, sha1).hexdigest()
s = 'https://{host}/{path}?temp_url_sig={sig}&temp_url_expires={expires}'
url = s.format(host='swift-cluster.example.com', path=path, sig=sig, expires=expires)
Any alteration of the resource path or query arguments results in a 401 Unauthorized error. Similarly, a PUT where GET was the allowed method returns a 401 error. HEAD is allowed if GET or PUT is allowed. Using this in combination with browser form post translation middleware could also allow direct-from-browser uploads to specific locations in Object Storage.
![]() | Note |
|---|---|
Changing the |
Object Storage includes the swift-temp-url script that generates the query parameters automatically:
$ bin/swift-temp-url GET 3600 /v1/AUTH_account/container/object mykey /v1/AUTH_account/container/object? temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91& temp_url_expires=1374497657
Because this command only returns the path, you must
prefix the Object Storage host name (for example,
https://swift-cluster.example.com).
With GET Temporary URLs, a
Content-Disposition header is set
on the response so that browsers interpret this as a file
attachment to be saved. The file name chosen is based on
the object name, but you can override this with a
filename query parameter. The
following example specifies a filename of My
Test File.pdf:
https://swift-cluster.example.com/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30/container/object? temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_expires=1323479485& filename=My+Test+File.pdf
If you do not want the object to be downloaded, you can cause
Content-Disposition: inline
to be set on the response by adding
the inline parameter to the query string, as follows:
https://swift-cluster.example.com/v1/AUTH_account/container/object? temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_expires=1323479485&inline
To enable Temporary URL functionality, edit
/etc/swift/proxy-server.conf to
add tempurl to the
pipeline variable defined in the
[pipeline:main] section. The
tempurl entry should appear
immediately before the authentication filters in the
pipeline, such as authtoken,
tempauth or
keystoneauth. For
example:
[pipeline:main]
pipeline = pipeline = healthcheck cache tempurl authtoken keystoneauth proxy-server
| Configuration option = Default value | Description |
|---|---|
incoming_allow_headers = |
Headers allowed as exceptions to incoming_remove_headers. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
incoming_remove_headers = x-timestamp |
Headers to remove from incoming requests. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
methods = GET HEAD PUT POST DELETE |
HTTP methods allowed with Temporary URLs |
outgoing_allow_headers = x-object-meta-public-* |
Headers allowed as exceptions to outgoing_allow_headers. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
outgoing_remove_headers = x-object-meta-* |
Headers to remove from outgoing responses. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
use = egg:swift#tempurl |
Entry point of paste.deploy in the server |

![[Note]](../common/images/admon/note.png)
