# Аутентификация запросов вебхуков

Для предоставления возможности достоверно установить, что автором [запроса](https://ati.su/developers/raw/api/webhooks/authentication.md#получение-сообщений) является ATI.SU,
реализован механизм подписывания запросов, который позволяет проверить их подлинность (аутентифицировать).

## Аутентификация

Аутентификация запросов проводится по следующему принципу: необходимо создать [строку подписания](#строка-подписания),
применить к ней алгоритм HMAC с использованием хеш-функции SHA-256 и сравнить результат в кодировке base64[^4] с
[параметром аутентификации `Signature`](#заголовок-authorization). В случае, если значение параметра совпадает с
полученным значением, запрос является подлинным.

## Создание подписи

Подпись создается посредством алгоритма HMAC[^1] с использованием хеш-функции SHA-256[^2]
на основе:

- <span id='auth-key'>ключа вебхука</span>, генерируемого на стороне ATI.SU,
  узнать который можно с помощью [GET-метода проверки состояния
  вебхука](https://ati.su/developers/raw/api/webhooks/authentication.md#get-webhooks-v1-status-%7Bid%7D) (поле `hook.key`)

- <span id='строка-подписания'>
    строки подписания, сформированной из содержимого запроса
  </span>

**Пример строки подписания**

```http
POST
/webhook?topic=orders
Thu, 01 Jan 1970 00:00:00 GMT;sha-256=SypZnuCTiysyLuUz9DOYckaU/vf0zrzdxKL1j/sHemg=;example.org:443
```


**Грамматика строки подписания**

```text
<signing_string> ::= <method> "" <path_and_query> "" <signed_headers_values>

<method> ::= "GET" | "POST"

<signed_headers_values> ::= (<header_value> | ((<header_value> ";")+ <header_value>))
```


- `<method>` — HTTP метод запроса;
- `<path_and_query>` — путь запроса вместе с параметрами;
- `<signed_headers_values>` – список значений заголовков через точку с запятой;
- `<header_value>` — значение заголовка.

Для создания строки подписания всегда используются значения заголовков `Date`[^5], `Digest`[^6] и `Host`[^7]. Таким
образом, подпись различается в зависимости от времени её создания, содержимого запроса и от цели запроса. В
совокупности с использованием протокола HTTPS это позволяет защитить вебхук от перехвата и модификации
сообщений.

:::caution

Порядок, а также набор заголовков, принимающих участие в подписании, может быть изменён, поэтому при создании строки
необходимо выбирать их на основе значения [параметра аутентификации][signed-headers] [`SignedHeaders`][signed-headers].

[signed-headers]: #заголовок-authorization

:::

## Заголовок Authorization

Все подписываемые запросы имеют заголовок `Authorization`[^3], который содержит информацию об используемом алгоритме
создания подписи, ключе, заголовках запроса, принимающих участие в подписании, и саму подпись в кодировке base64[^4].

**Пример заголовка Authorization**

```http
Authorization: HMAC-SHA-256
  Credential=6447f577905114d5b9b2c618&SignedHeaders=Date;Digest;Host&Signature=V8CpKji2ysF5h5VVerhcq/GMQGxoHwf0EcGiDIL41e0=
```

**Грамматика заголовка Authorization**

```text
<authorization> ::= <scheme> "" <parameters>

<scheme> ::= "HMAC-SHA-256"

<parameters> ::= <credential> "&" <signed_headers> "&" <signature>

<credential> ::= "Credential=" <key_id>
<signed_headers> ::= "SignedHeaders=" (<header> | ((<header> ";")+ <header>))
<signature> ::= "Signature=" <base64_digest>
```


- `<scheme>` — схема аутентификации;
- `<parameters>` — параметры аутентификации;
- `<key_id>` — идентификатор [ключа вебхука](#auth-key);
- `<header>` — название заголовка, принимающего участие в подписании;
- `<base64_digest>` — подпись, представляет собой 264-битную строку в кодировке base64[^4].

:::caution

Идентификатор ключа на данный момент совпадает с идентификатором вебхука, что в дальнейшем может быть изменено,
поэтому он **не** должен использоваться для выявления принадлежности сообщения конкретному вебхуку.
:::

## Ротация ключей

Отправка сообщения, оповещающего о ротации, пока не предусмотрена, поэтому в случае если подпись не совпадает, следует
запросить актуальный ключ. В том случае, если полученный ключ совпадает с текущим, запрос является поддельным.

## Остались вопросы?

Напишите нам: [Контакты](https://ati.su/developers/raw/introduction/contacts.md).

[^1]: [RFC 2104 | HMAC: Keyed-Hashing for Message Authentication](https://datatracker.ietf.org/doc/html/rfc2104)

[^2]: [RFC 6234 | US Secure Hash Algorithms](https://datatracker.ietf.org/doc/html/rfc6234)

[^3]: [RFC 7235 | Hypertext Transfer Protocol (HTTP/1.1): Authentication](https://datatracker.ietf.org/doc/html/rfc7235#section-4.2)

[^4]: [RFC 4648 | The Base16, Base32, and Base64 Data Encodings](https://datatracker.ietf.org/doc/html/rfc4648#section-4)

[^5]: [RFC 9110 | HTTP Semantics](https://datatracker.ietf.org/doc/html/rfc9110#name-date)

[^6]: [RFC 3230 | Instance Digests in HTTP](https://datatracker.ietf.org/doc/html/rfc3230#section-4.3.2)

[^7]: [RFC 9110 | HTTP Semantics](https://datatracker.ietf.org/doc/html/rfc9110#name-host-and-authority)
---

## llms.txt

Индекс ключевых страниц документации для LLM и AI-агентов доступен в [основном llms.txt](https://ati.su/developers/llms.txt).
