Pre-signed URLs
Object Storage incorporates multiple mechanisms for managing access to resources. To learn how these mechanisms interact, see Overview of access management methods in Object Storage.
With pre-signed URLs, any web user can perform various operations in Object Storage, such as:
- Download an object
- Upload an object
- Create a bucket
A pre-signed URL is a URL containing request authorization data in its parameters. Pre-signed URLs can be created by users with static access keys.
This section outlines the common principles for generating pre-signed URLs using AWS Signature V4.
Note
SDKs for various programming languages and other tools for AWS S3 feature out-of-the-box methods for generating pre-signed URLs that you can also use for Object Storage.
General pre-signed URL format
https://storage.yandexcloud.net/<bucket_name>/<object_key>?
X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Expires=<interval>
&X-Amz-SignedHeaders=<list_of_headers>
&X-Amz-Signature=<signature>
&X-Amz-Date=<time>
&X-Amz-Credential=<access_key_ID>%2F<date>%2Fru-central1%2Fs3%2Faws4_request
Pre-signed URL parameters:
Parameter | Description |
---|---|
X-Amz-Algorithm |
Identifies the signature version and algorithm for its calculation. Value: AWS4-HMAC-SHA256 . |
X-Amz-Expires |
Link validity time in seconds. The starting point is the time specified in X-Amz-Date . The maximum value is 2592000 seconds (30 days). |
X-Amz-SignedHeaders |
Headers of the request you want to sign. Make sure to sign the Host header and all X-Amz-* headers used in the request. You do not have to sign other headers; however, the more headers you sign, the safer your request is. Request headers are separated by ; . |
X-Amz-Signature |
Request signature. |
x-amz-date |
Time in ISO860120180719T000000Z . The date specified must match the date in the X-Amz-Credential parameter (by value rather than by format). |
X-Amz-Credential |
Signature ID. This is a string in <access_key_ID>/<date>/ru-central1/s3/aws4_request format, where <date> (specified in YYYYMMDD format: year, month, day) must match the date set in the X-Amz-Date header. |
Creating pre-signed URLs
Note
Generating pre-signed URLs is optional for public buckets. You can get files from a publicly available bucket via both HTTP and HTTPS even if the bucket has no website hosting configured.
To get a pre-signed URL, do the following:
- Calculate the signature.
- Compose a string to sign.
- Calculate the signature using the string signature algorithm.
- Compose a pre-signed URL for your request.
To compose a pre-signed URL, you must have static access keys.
String to sign
String to sign:
"AWS4-HMAC-SHA256" + "\n" +
<time> + "\n" +
<date> + "\n" +
Hex(Hash-SHA256(<canonical_request>))
Where:
AWS4-HMAC-SHA256
: Hashing algorithm.<time>
: Current time in ISO 8601 format, e.g.,20190801T000000Z
. The specified date must match the<date>
parameter (by value rather than by format).<date>
:<date>/ru-central1/s3/aws4_request
, where<date>
is provided inYYYYMMDD
format: year, month, day.<canonical_request>
: Canonical request. To include your request in the string, hash it using the SHA256 algorithm and convert it to hexadecimal format.
Canonical request
The general canonical request format is as follows:
<HTTPVerb>\n
<CanonicalURL>\n
<CanonicalQueryString>\n
<CanonicalHeaders>\n
<SignedHeaders>\n
UNSIGNED-PAYLOAD
A canonical request must always end with the UNSIGNED-PAYLOAD
string.
HTTPVerb
HTTPVerb stands for the HTTP method used to send a request: GET
, PUT
, HEAD
, or DELETE
.
CanonicalURL
Canonical URL is the URL-encoded path to the resource, e.g., /<bucket_name>/<object_key>
.
Note
Do not normalize the path. For example, if an object has a some//strange//key//example
key, normalizing the path to /<bucket_name>/some/strange/key/example
will invalidate it.
CanonicalQueryString
The canonical query string must include all query parameters of the destination URL, except X-Amz-Signature
. The parameters in the string must be URL-encoded and sorted alphabetically.
For example:
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=JK38EXAMPLEAKDID8%2F20190801%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20190801T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
CanonicalHeaders
This section includes the list of the request headers and their values.
The requirements are as follows:
- Each header must be separated with the
\n
newline character. - Header names must be lowercase.
- Headers must be sorted alphabetically.
- There may not be any extra spaces.
- The list must contain the
host
header and allx-amz-*
headers used in the request.
You can also add any request header to the list. The more headers you sign, the safer your request is.
For example:
host:storage.yandexcloud.net
x-amz-date:20190801T000000Z
SignedHeaders
This is a list of lowercase request header names, sorted alphabetically and separated by semicolons.
For example:
host;x-amz-date
Pre-signed URLs
To create a pre-signed URL, add the parameters required to authorize the request, including the X-Amz-Signature
parameter with the calculated signature, to the Object Storage resource URL.
Example of composing a pre-signed URL for downloading an object
Here is an example of creating a signed URL to download the object-for-share.txt
object from the bucket valid for an hour.
-
Static key:
access_key_id = 'JK38EXAMP********' secret_access_key = 'ExamP1eSecReTKeykdo********'
-
Canonical request:
GET /<bucket_name>/object-for-share.txt X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=JK38EXAMP********%2F20190801%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20190801T000000Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host host:storage.yandexcloud.net host UNSIGNED-PAYLOAD
-
String to sign:
AWS4-HMAC-SHA256 20190801T000000Z 20190801/ru-central1/s3/aws4_request 2d2b4efefa9072d90a646afbc0fbaef4618c81396b216969ddfc2869********
-
Signing key:
sign(sign(sign(sign("AWS4" + "ExamP1eSecReTKeykdokKK38800","20190801"),"ru-central1"),"s3"),"aws4_request")
Here, we introduce the
sign
function to indicate the method of key calculation that uses the HMAC algorithm with SHA256 . -
Signature:
56bdf53a1f10c078c2b4fb5a26cefa670b3ea796567d85489135cf33********
-
Pre-signed URL:
https://storage.yandexcloud.net/<bucket_name>/object-for-share.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=JK38EXAMPLEAKDID8%2F20190801%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20190801T000000Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=56bdf53a1f10c078c2b4fb5a26cefa670b3ea796567d85489135cf33********
Examples of getting pre-signed links in Object Storage tools
- In the management console
, select the folder. - Select Object Storage.
- Click the name of the bucket you need.
- Click the object name.
- Click Get link in the top-right corner.
- If your bucket has restricted access, specify the link Lifetime in hours or days (the maximum time is thirty days).
- Click Get link.
- Copy the link.
You can also use AWS CLI to generate a link for downloading an object. To do this, run the following command:
aws s3 presign s3://<bucket_name>/<object_key> --endpoint-url "https://storage.yandexcloud.net/" [--expires-in <value>]
To generate the link properly, make sure to provide the --endpoint-url
parameter pointing to the Object Storage hostname. For detailed information, see this section covering AWS CLI specifics.
The example below generates a pre-signed URL for downloading the object-for-share
object from the bucket-with-objects
bucket. The URL is valid for 100 seconds.
# coding=utf-8
import boto3
from botocore.client import Config
ENDPOINT = "https://storage.yandexcloud.net"
ACCESS_KEY = "JK38EXAMP********"
SECRET_KEY = "ExamP1eSecReTKeykdo********"
session = boto3.Session(
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
region_name="ru-central1",
)
s3 = session.client(
"s3", endpoint_url=ENDPOINT, config=Config(signature_version="s3v4")
)
presigned_url = s3.generate_presigned_url(
"get_object",
Params={"Bucket": "<bucket_name>", "Key": "<object_key>"},
ExpiresIn=100,
)
print(presigned_url)
This example generates a pre-signed URL for creating a bucket:
# coding=utf-8
import boto3
from botocore.client import Config
ENDPOINT = "https://storage.yandexcloud.net"
ACCESS_KEY = "JK38EXAMP********"
SECRET_KEY = "ExamP1eSecReTKeykdo********"
session = boto3.Session(
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
region_name="ru-central1",
)
s3 = session.client(
"s3", endpoint_url=ENDPOINT, config=Config(signature_version="s3v4")
)
presigned_url = s3.generate_presigned_url(
"create_bucket",
Params={"Bucket":"<bucket_name>"},
)
print(presigned_url)