Getting started with the AWS S3 API in Yandex Object Storage
AWS S3 API
With the AWS S3 API, you will create a bucket, upload an object to it, get a list of objects in the bucket, download an object from the bucket, delete an object, and delete the bucket.
Note
To use the AWS S3 API directly (without an SDK or apps), you will need to sign requests yourself. You can test the request and signature generation using the AWS CLI in debug mode.
Get your cloud ready
Sign up for Yandex Cloud and create a billing account:
- Navigate to the management console
and log in to Yandex Cloud or create a new account. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one and link a cloud to it.
If you have an active billing account, you can navigate to the cloud page
Learn more about clouds and folders here.
Create a service account and static access key
To authenticate with the AWS S3 API, use a static access key. A static access key is issued for a specific service account, and all actions involving this key are performed on behalf of this service account.
-
Assign the
storage.editor
role for the folder to the service account. This will allow you to work with all buckets in the folder on behalf of this service account. -
As a result, you will get the static access key data. To authenticate in Object Storage, you will need the following:
key_id
: Static access key IDsecret
: Secret key
Save
key_id
andsecret
: you will not be able to get the key value again. -
Install curl
.Starting from version 8.3.0
, thecurl
utility supports automatic generation of the signature string, request signing, and substitution of the required headers when working with the AWS S3 API.In earlier
curl
versions, you can form the required headers and sign requests manually.
Create a bucket
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>"
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket you are creating.
-
Run an http request:
curl \ --request PUT \ --user "${AWS_KEY_ID}:${AWS_SECRET_KEY}" \ --aws-sigv4 "aws:amz:ru-central1:s3" \ --verbose \ "https://storage.yandexcloud.net/${BUCKET_NAME}"
Result:
... < HTTP/2 200 < server: nginx < date: Wed, 14 May 2025 20:00:04 GMT < content-type: application/octet-stream < location: /my-sample-bucket < x-amz-request-id: a5cf0b8d******** < * Connection #0 to host storage.yandexcloud.net left intact
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>" DATE_VALUE=`date -R` STRING_TO_SIGN="PUT\n\n${CONTENT_TYPE}\n${DATE_VALUE}\n/${BUCKET_NAME}" SIGNATURE=`echo -en ${STRING_TO_SIGN} | openssl sha1 -hmac ${AWS_SECRET_KEY} -binary | base64`
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket you are creating.
-
Run an http request:
curl \ --request PUT \ --verbose \ --header "Host: storage.yandexcloud.net" \ --header "Date: ${DATE_VALUE}" \ --header "Authorization: AWS ${AWS_KEY_ID}:${SIGNATURE}" \ "https://storage.yandexcloud.net/${BUCKET_NAME}"
Result:
... < HTTP/2 200 < server: nginx < date: Thu, 15 May 2025 07:06:22 GMT < content-type: application/octet-stream < location: /my-sample-bucket < x-amz-request-id: b8c1bd45******** < * Connection #0 to host storage.yandexcloud.net left intact
Upload an object to the bucket
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" LOCAL_FILE="<local_file_path>" BUCKET_NAME="<bucket_name>" OBJECT_PATH="<object_key>"
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
LOCAL_FILE
: Path to the local file you want to upload, e.g.,./sample.txt
.BUCKET_NAME
: Name of the bucket to upload the file to.OBJECT_PATH
: Key to assign to the object in the bucket, e.g.new-prefix/sample-object.txt
.
-
Run an http request:
curl \ --request PUT \ --user "${AWS_KEY_ID}:${AWS_SECRET_KEY}" \ --aws-sigv4 "aws:amz:ru-central1:s3" \ --upload-file "${LOCAL_FILE}" \ --verbose \ "https://storage.yandexcloud.net/${BUCKET_NAME}/${OBJECT_PATH}"
Result:
... < HTTP/2 200 < server: nginx < date: Thu, 15 May 2025 07:17:46 GMT < content-type: text/plain < etag: "f75a361db63aa4722fb8e083********" < x-amz-request-id: 40afeceb******** < * Connection #0 to host storage.yandexcloud.net left intact
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" LOCAL_FILE="<local_file_path>" BUCKET_NAME="<bucket_name>" OBJECT_PATH="<object_key>" DATE_VALUE=`date -R` STRING_TO_SIGN="PUT\n\n${CONTENT_TYPE}\n${DATE_VALUE}\n/${BUCKET_NAME}/${OBJECT_PATH}" SIGNATURE=`echo -en ${STRING_TO_SIGN} | openssl sha1 -hmac ${AWS_SECRET_KEY} -binary | base64`
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
LOCAL_FILE
: Path to the local file you want to upload, e.g.,./sample.txt
.BUCKET_NAME
: Name of the bucket to upload the file to.OBJECT_PATH
: Key to assign to the object in the bucket, e.g.new-prefix/sample-object.txt
.
-
Run an http request:
curl \ --request PUT \ --upload-file "${LOCAL_FILE}" \ --verbose \ --header "Host: storage.yandexcloud.net" \ --header "Date: ${DATE_VALUE}" \ --header "Authorization: AWS ${AWS_KEY_ID}:${SIGNATURE}" \ "https://storage.yandexcloud.net/${BUCKET_NAME}/${OBJECT_PATH}"
Result:
... < HTTP/2 200 < server: nginx < date: Thu, 15 May 2025 07:23:08 GMT < content-type: text/plain < etag: "f75a361db63aa4722fb8e083********" < x-amz-request-id: 67ccce91******** < * Connection #0 to host storage.yandexcloud.net left intact
Get a list of objects in the bucket
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>"
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket from which you want to get a list of objects.
-
Run an http request:
curl \ --request GET \ --user "${AWS_KEY_ID}:${AWS_SECRET_KEY}" \ --aws-sigv4 "aws:amz:ru-central1:s3" \ --verbose \ "https://storage.yandexcloud.net/${BUCKET_NAME}?list-type=2"
Result:
... < HTTP/2 200 < server: nginx < date: Thu, 15 May 2025 07:44:41 GMT < content-type: application/xml; charset=UTF-8 < content-length: 569 < x-amz-request-id: cab0999d******** < <?xml version="1.0" encoding="UTF-8"?> * Connection #0 to host storage.yandexcloud.net left intact <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <KeyCount>1</KeyCount> <Name>my-sample-bucket</Name> <Prefix></Prefix> <MaxKeys>1000</MaxKeys> <IsTruncated>false</IsTruncated> <Contents> <Key>text.txt</Key> <LastModified>2025-05-15T07:23:08.030Z</LastModified> <Owner> <ID>ajegtlf2q28a********</ID> <DisplayName>ajegtlf2q28a********</DisplayName> </Owner> <ETag>"f75a361db63aa4722fb8e083********"</ETag> <Size>103</Size> <StorageClass>STANDARD</StorageClass> <TagSet></TagSet> </Contents> </ListBucketResult>
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>" DATE_VALUE=`date -R` STRING_TO_SIGN="GET\n\n${CONTENT_TYPE}\n${DATE_VALUE}\n/${BUCKET_NAME}" SIGNATURE=`echo -en ${STRING_TO_SIGN} | openssl sha1 -hmac ${AWS_SECRET_KEY} -binary | base64`
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket from which you want to get a list of objects.
-
Run an http request:
curl \ --request GET \ --verbose \ --header "Host: storage.yandexcloud.net" \ --header "Date: ${DATE_VALUE}" \ --header "Authorization: AWS ${AWS_KEY_ID}:${SIGNATURE}" \ "https://storage.yandexcloud.net/${BUCKET_NAME}?list-type=2"
Result:
... < HTTP/2 200 < server: nginx < date: Thu, 15 May 2025 08:29:36 GMT < content-type: application/xml; charset=UTF-8 < content-length: 569 < x-amz-request-id: cb4b9a3d******** < <?xml version="1.0" encoding="UTF-8"?> * Connection #0 to host storage.yandexcloud.net left intact <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <KeyCount>1</KeyCount> <Name>my-sample-bucket</Name> <Prefix></Prefix> <MaxKeys>1000</MaxKeys> <IsTruncated>false</IsTruncated> <Contents> <Key>text.txt</Key> <LastModified>2025-05-15T07:23:08.030Z</LastModified> <Owner> <ID>ajegtlf2q28a********</ID> <DisplayName>ajegtlf2q28a********</DisplayName> </Owner> <ETag>"f75a361db63aa4722fb8e083********"</ETag> <Size>103</Size> <StorageClass>STANDARD</StorageClass> <TagSet></TagSet> </Contents> </ListBucketResult>
Download an object from the bucket
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>" OBJECT_PATH="<object_key>" LOCAL_FILE="<local_file_path>"
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket with the object to download.OBJECT_PATH
: Key of the object to download in the bucket, e.g.new-prefix/sample-object.txt
.LOCAL_FILE
: Path to the local file you want to save the downloaded object to, e.g.,./sample.txt
.
-
Run an http request:
curl \ --request GET \ --user "${AWS_KEY_ID}:${AWS_SECRET_KEY}" \ --aws-sigv4 "aws:amz:ru-central1:s3" \ --verbose \ "https://storage.yandexcloud.net/${BUCKET_NAME}/${OBJECT_PATH}" \ > ${LOCAL_FILE}
Result:
... < HTTP/2 200 < server: nginx < date: Thu, 15 May 2025 08:55:19 GMT < content-type: text/plain < content-length: 103 < accept-ranges: bytes < etag: "f75a361db63aa4722fb8e083********" < last-modified: Thu, 15 May 2025 07:23:08 GMT < x-amz-request-id: 1afc3ec9******** < { [103 bytes data] 100 103 100 103 0 0 1925 0 --:--:-- --:--:-- --:--:-- 1943 * Connection #0 to host storage.yandexcloud.net left intact
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>" OBJECT_PATH="<object_key>" LOCAL_FILE="<local_file_path>" DATE_VALUE=`date -R` STRING_TO_SIGN="GET\n\n${CONTENT_TYPE}\n${DATE_VALUE}\n/${BUCKET_NAME}/${OBJECT_PATH}" SIGNATURE=`echo -en ${STRING_TO_SIGN} | openssl sha1 -hmac ${AWS_SECRET_KEY} -binary | base64`
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket with the object to download.OBJECT_PATH
: Key of the object to download in the bucket, e.g.,new-prefix/sample-object.txt
.LOCAL_FILE
: Path to the local file you want to save the downloaded object to, e.g.,./sample.txt
.
-
Run an http request:
curl \ --request GET \ --verbose \ --header "Host: storage.yandexcloud.net" \ --header "Date: ${DATE_VALUE}" \ --header "Authorization: AWS ${AWS_KEY_ID}:${SIGNATURE}" \ "https://storage.yandexcloud.net/${BUCKET_NAME}/${OBJECT_PATH}" \ > ${LOCAL_FILE}
Result:
... < HTTP/2 200 < server: nginx < date: Thu, 15 May 2025 09:11:12 GMT < content-type: text/plain < content-length: 103 < accept-ranges: bytes < etag: "f75a361db63aa4722fb8e083********" < last-modified: Thu, 15 May 2025 07:23:08 GMT < x-amz-request-id: e86c7119******** < { [103 bytes data] 100 103 100 103 0 0 3433 0 --:--:-- --:--:-- --:--:-- 3433 * Connection #0 to host storage.yandexcloud.net left intact
The downloaded object was saved to the file whose path is specified in the LOCAL_FILE
variable.
Delete an object from the bucket
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>" OBJECT_PATH="<object_key>"
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket to delete the object from.OBJECT_PATH
: Key of the object to delete in the bucket, e.g.,new-prefix/sample-object.txt
.
-
Run an http request:
curl \ --request DELETE \ --user "${AWS_KEY_ID}:${AWS_SECRET_KEY}" \ --aws-sigv4 "aws:amz:ru-central1:s3" \ --verbose \ "https://storage.yandexcloud.net/${BUCKET_NAME}/${OBJECT_PATH}"
Result:
... < HTTP/2 204 < server: nginx < date: Thu, 15 May 2025 14:24:01 GMT < x-amz-request-id: 7d2f023c******** < * Connection #0 to host storage.yandexcloud.net left intact
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>" OBJECT_PATH="<object_key>" DATE_VALUE=`date -R` STRING_TO_SIGN="DELETE\n\n${CONTENT_TYPE}\n${DATE_VALUE}\n/${BUCKET_NAME}/${OBJECT_PATH}" SIGNATURE=`echo -en ${STRING_TO_SIGN} | openssl sha1 -hmac ${AWS_SECRET_KEY} -binary | base64`
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket to delete the object from.OBJECT_PATH
: Key of the object to delete in the bucket, e.g.,new-prefix/sample-object.txt
.
-
Run an http request:
curl \ --request DELETE \ --verbose \ --header "Host: storage.yandexcloud.net" \ --header "Date: ${DATE_VALUE}" \ --header "Authorization: AWS ${AWS_KEY_ID}:${SIGNATURE}" \ "https://storage.yandexcloud.net/${BUCKET_NAME}/${OBJECT_PATH}"
Result:
... < HTTP/2 204 < server: nginx < date: Thu, 15 May 2025 14:30:28 GMT < x-amz-request-id: 7dc0c426******** < * Connection #0 to host storage.yandexcloud.net left intact
Delete the bucket
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>"
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket to delete. The bucket you want to delete must not contain any objects.
-
Run an http request:
curl \ --request DELETE \ --user "${AWS_KEY_ID}:${AWS_SECRET_KEY}" \ --aws-sigv4 "aws:amz:ru-central1:s3" \ --verbose \ "https://storage.yandexcloud.net/${BUCKET_NAME}"
Result:
... < HTTP/2 204 < server: nginx < date: Thu, 15 May 2025 14:35:57 GMT < x-amz-request-id: 6a13b7ae******** < * Connection #0 to host storage.yandexcloud.net left intact
-
Set the variables containing the required data:
AWS_KEY_ID="<static_key_ID>" AWS_SECRET_KEY="<secret_key>" BUCKET_NAME="<bucket_name>" DATE_VALUE=`date -R` STRING_TO_SIGN="DELETE\n\n${CONTENT_TYPE}\n${DATE_VALUE}\n/${BUCKET_NAME}" SIGNATURE=`echo -en ${STRING_TO_SIGN} | openssl sha1 -hmac ${AWS_SECRET_KEY} -binary | base64`
Where:
AWS_KEY_ID
: Static access key ID.AWS_SECRET_KEY
: Secret key.
BUCKET_NAME
: Name of the bucket to delete. The bucket you want to delete must not contain any objects.
-
Run an http request:
curl \ --request DELETE \ --verbose \ --header "Host: storage.yandexcloud.net" \ --header "Date: ${DATE_VALUE}" \ --header "Authorization: AWS ${AWS_KEY_ID}:${SIGNATURE}" \ "https://storage.yandexcloud.net/${BUCKET_NAME}"
Result:
... < HTTP/2 204 < server: nginx < date: Thu, 15 May 2025 14:39:15 GMT < x-amz-request-id: 331b2dc4******** < * Connection #0 to host storage.yandexcloud.net left intact