[Yandex Cloud documentation](../../index.md) > [Yandex Object Storage](../index.md) > API reference > [AWS S3 REST](index.md) > Signing requests

# Signing requests

{% note warning %}

Requests have to be signed only if using [static access key](../../iam/concepts/authorization/access-key.md) authentication. If [IAM token](../../iam/concepts/authorization/iam-token.md) authentication is used, you do not have to sign requests.

{% endnote %}


Many requests to Object Storage require authentication on the service side, so the user sending a request must sign it.

Object Storage supports the [AWS Signature V4](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html).

The signing process includes the following stages:

1. [Generating a string to sign](#string-to-sign-gen).
1. [Generating a signing key](#signing-key-gen).
1. [Signing the string with the key](#signing).

Use [HMAC](https://ru.wikipedia.org/wiki/HMAC) with the [SHA256](https://ru.wikipedia.org/wiki/SHA-2) hash function to sign. Many programming languages support relevant methods. The examples assume that there is a `sign(KEY, STRING)` function that encodes the input string with the specified key.

## Generate a string to sign {#string-to-sign-gen}

The string to sign (`StringToSign`) depends on the Object Storage use case:

* [Accessing an Amazon S3-compatible API](index.md) without an SDK or special utilities.
* [Uploading objects using an HTML form](../concepts/presigned-post-forms.md).
* [Signing a URL using query parameters](../concepts/pre-signed-urls.md).

## Generate a signing key {#signing-key-gen}

To generate a signing key, you need static access keys for Object Storage. To learn how to get them, see [Getting started](index.md#before-you-begin).

To generate a signing key:

1. Use the secret key to encode the date:

    ```
    DateKey = sign("AWS4" + "SecretKey", "yyyymmdd")
    ```

1. Encode the region using `DateKey` you got in the previous step:

    ```
    RegionKey = sign(DateKey, "ru-central1")
    ```

1. Encode the service using `RegionKey` you got in the previous step:

    ```
    ServiceKey = sign(RegionKey, "s3")
    ```

1. Get the signing key:

    ```
    SigningKey = sign(ServiceKey, "aws4_request")
    ```

{% note info %}

The signing key is valid for several minutes; after that time, its use may result in error 403: `RequestTimeTooSkewed`. Refresh the signing key regularly to extend its validity period.

The AWS SDK uses local system time to generate the signing key. 

  {% cut "If local system time is incorrect" %}

  You can use a real-time fetching function, e.g., [v4.SignSDKRequestWithCurrentTime](https://pkg.go.dev/github.com/aws/aws-sdk-go/aws/signer/v4#SignSDKRequestWithCurrentTime) in the AWS SDK for Go:

  ```Go
  client := s3.New(sess)
  client.Handlers.Sign.Swap(v4.SignRequestHandler.Name, request.NamedHandler{
      Name: v4.SignRequestHandler.Name,
      Fn: func(r *request.Request) {
          v4.SignSDKRequestWithCurrentTime(r, currentTimeFn)
      },
  })
  ```

  {% endcut %}

{% endnote %}

## Sign the string with the key {#signing}

To get a string signature, use `HMAC` with the `SHA256` hash function and convert the result to hexadecimal format.

```text
signature = Hex(sign(SigningKey, StringToSign))
```

## Debugging using the AWS CLI {#debugging}

To debug the process of generating a [canonical request](../concepts/pre-signed-urls.md#canonical-request), [signature string](../concepts/pre-signed-urls.md#composing-string-to-sign), and [signing key](../concepts/pre-signed-urls.md#signing-key-gen), use the [AWS CLI](../tools/aws-cli.md) utility with the `--debug` parameter. 

{% note info %}

Make sure that the service account you are using to run `aws` commands has the permissions required to perform the requested actions. For example, to create a bucket, [assign](../../iam/operations/sa/assign-role-for-sa.md) the `storage.editor` [role](../security/index.md#storage-uploader) for the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) to the service account. For more information, see [Access management methods in Object Storage: Overview](../security/overview.md).

{% endnote %}

{% list tabs group=instructions %}

- AWS CLI {#aws-cli}

  In the terminal, run the bucket creation command and see how request parameters are generated:

  ```bash
  aws s3api create-bucket \
    --endpoint-url=https://storage.yandexcloud.net \
    --bucket <bucket_name> \
    --debug
  ```

  Result:

  ```text
  2024-06-03 13:02:36,238 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
  PUT
  /<bucket_name>

  host:storage.yandexcloud.net
  x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b********
  x-amz-date:20240603T100236Z

  host;x-amz-content-sha256;x-amz-date
  e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b********

  2024-06-03 13:02:36,238 - MainThread - botocore.auth - DEBUG - StringToSign:
  AWS4-HMAC-SHA256
  20240603T100236Z
  20240603/ru-central1/s3/aws4_request
  7877a13bafaa45f9751e7f345b64a63acc6de279ff927736e906d7c5********

  2024-06-03 13:02:36,238 - MainThread - botocore.auth - DEBUG - Signature:
  90545034742d1e057c8eeb2cca3c23a38a3ced5ef847f61ac80cb8e1********
  ```

{% endlist %}

#### See also {#see-also}

* [Getting started with the AWS S3 API in Yandex Object Storage](s3-api-quickstart.md)
* [Example of sending a signed request using curl](../api-ref/authentication.md#s3-api-example)
* [Code example for generating a signature](../concepts/pre-signed-urls.md#code-examples)