Files
SQS-service/doc/byoc-credentials.md
T
Naeel c3ba2dcae4 chore: initial import from sless/shared-sqs (v0.1.14)
- Standalone SQS-service repository
- Multi-tenant message queue service, AWS SQS compatible
- Based on GoAws, with mutable tenants, auth, WebUI, Redis persistence
- Ready for independent development and deployment
- See doc/ and README.md for architecture and usage
2026-04-10 16:47:27 +03:00

4.1 KiB

BYOC — Bring Your Own Credentials

Дата: 2026-04-09
Статус: частично реализовано (backend), UI/API — TODO


Суть

Возможность создать тенанта с произвольными Access Key и Secret Key вместо авто-генерируемых.

Нужно для:

  • демо-стенда с фиксированными credentials (README всегда актуален)
  • интеграционных тестов с предсказуемыми значениями
  • миграции с другого SQS-совместимого сервиса (сохранение существующих ключей)

Что уже сделано

app/tenant/tenant_store.goCreateFixed

func (s *TenantStore) CreateFixed(
    name      string,
    maxQueues int,
    tenantID  string,
    accessKey string,
    secretKey string,
) (*Tenant, error)

Создаёт тенанта с заранее известными credentials.
Проверяет уникальность и tenantID, и accessKey — конфликт возвращает ошибку.

app/cmd/seed.go — демо-тенант

Использует CreateFixed при SHARED_SQS_SEED_DEMO=true:

tenantID  = "t-demo-shared-sqs-ngcloud"
accessKey = "SSAK-demo-shared-sqs"
secretKey = "demo-secret-key-shared-sqs-ngcloud-2026"

Что нужно сделать (TODO)

Admin API — POST /admin/tenants

Добавить в createTenantRequest два опциональных поля:

// app/admin/admin.go
type createTenantRequest struct {
    Name      string `json:"name"`
    MaxQueues int    `json:"max_queues"`
    AccessKey string `json:"access_key,omitempty"` // TODO: BYOC
    SecretKey string `json:"secret_key,omitempty"` // TODO: BYOC
}

Логика в createTenant handler:

var t *tenant.Tenant
var err error
if req.AccessKey != "" || req.SecretKey != "" {
    // BYOC: оба поля обязательны
    if req.AccessKey == "" || req.SecretKey == "" {
        jsonErr(w, http.StatusBadRequest, "both access_key and secret_key required when specifying custom credentials")
        return
    }
    // Минимальная длина — защита от случайно слабых ключей
    if len(req.AccessKey) < 8 || len(req.SecretKey) < 16 {
        jsonErr(w, http.StatusBadRequest, "access_key min 8 chars, secret_key min 16 chars")
        return
    }
    t, err = h.store.CreateFixed(req.Name, req.MaxQueues, generateTenantID(), req.AccessKey, req.SecretKey)
} else {
    t, err = h.store.Create(req.Name, req.MaxQueues)
}

generateTenantID() — уже есть в tenant_store.go, нужно экспортировать или вынести.

UI — Web форма создания тенанта

  • Добавить в модальное окно "Создать тенанта" два опциональных поля: Access Key, Secret Key
  • Показывать только если нажата кнопка "задать свои credentials"
  • Валидация на клиенте: оба поля заполнены, мин. длина

Безопасность

  • BYOC-credentials не дают доступа к admin API — admin защищён отдельным Bearer токеном
  • Тенант видит только свои очереди — изоляция по AccessKey в auth middleware
  • Слабые ключи отклоняются на уровне API (минимальная длина)
  • Credentials передаются только по HTTPS

Демо-credentials (открыты намеренно)

Access Key SSAK-demo-shared-sqs
Secret Key demo-secret-key-shared-sqs-ngcloud-2026
Tenant ID t-demo-shared-sqs-ngcloud
Лимит очередей 10

Эти credentials жёстко прописаны в app/cmd/seed.go.
Тенант создаётся только если SHARED_SQS_SEED_DEMO=true (env var в deployment.yaml).