chore: добавить каркас image-platform
- добавлен базовый pnpm workspace для будущих приложений - добавлена dev-инфраструктура PostgreSQL и MinIO - добавлены env-пример и базовые правила репозитория - зафиксированы архитектура, data model и API-контракт - описан контракт с внешним imgproxy
This commit is contained in:
71
docs/imgproxy-contract.md
Normal file
71
docs/imgproxy-contract.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Контракт с 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`.
|
||||
Reference in New Issue
Block a user