Files
image-platform/docs/imgproxy-contract.md
S.Gromov 37592c8b81 chore: добавить каркас image-platform
- добавлен базовый pnpm workspace для будущих приложений

- добавлена dev-инфраструктура PostgreSQL и MinIO

- добавлены env-пример и базовые правила репозитория

- зафиксированы архитектура, data model и API-контракт

- описан контракт с внешним imgproxy
2026-05-04 22:53:55 +03:00

72 lines
1.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Контракт с imgproxy
`imgproxy` всегда внешний сервис для `image-platform`.
## Env
```env
IMGPROXY_UPSTREAM=http://external-imgproxy.internal:8080
IMGPROXY_SIGNING_ENABLED=false
IMGPROXY_KEY=
IMGPROXY_SALT=
```
## Dev режим
В dev можно использовать unsigned `/unsafe` URL, если внешний `imgproxy` запущен без key/salt.
Пример path:
```text
/unsafe/resize:fit:800:0:0/q:80/plain/https://example.com/photo.jpg
```
## Prod режим
В prod нужно перейти на signed URLs и закрыть `/unsafe`.
Path для подписи строится без `/unsafe`:
```text
/resize:fit:800:0:0/q:80/plain/https://example.com/photo.jpg
```
Signature:
```text
HMAC-SHA256(binary_key, binary_salt + path_bytes)
base64url without padding
```
Node implementation reference:
```ts
import crypto from "node:crypto"
export function signImgproxyPath(keyHex: string, saltHex: string, path: string) {
const key = Buffer.from(keyHex, "hex")
const salt = Buffer.from(saltHex, "hex")
const hmac = crypto.createHmac("sha256", key)
hmac.update(Buffer.concat([salt, Buffer.from(path)]))
return hmac.digest("base64url")
}
```
Final signed URL:
```text
{IMGPROXY_UPSTREAM}/{signature}{path}
```
## Security rules
- Не отдавать `IMGPROXY_KEY` и `IMGPROXY_SALT` в браузер.
- Source URL валидировать в API/worker.
- Разрешать только `http` и `https`.
- Запрещать localhost, private IP, loopback, link-local.
- Source host должен быть enabled в `allowed_image_hosts`.
- Не давать клиенту произвольные imgproxy options.
- Использовать presets и deterministic `variantHash`.