Реализована интеграция с СМС провайдером
This commit is contained in:
@@ -39,6 +39,9 @@ Placeholders:
|
||||
<RELEASE> immutable tag/git SHA
|
||||
<ACME_EMAIL> адрес ops, не placeholder в реальном запуске
|
||||
<BITRIX_PORTAL> разрешённый портал
|
||||
<IDGTL_SENDER_NAME> согласованное в Direct имя отправителя
|
||||
<IDGTL_STATIC_EGRESS_IP> фактический статический egress IP `sms-worker`
|
||||
<IDGTL_TEST_PHONE> контролируемый номер для provider smoke
|
||||
```
|
||||
|
||||
## 3. Stage 0 — решения до provisioning
|
||||
@@ -72,7 +75,7 @@ Placeholders:
|
||||
- [ ] RPO/RTO приняты хотя бы временно: ориентир RPO PG ≤15 минут/PITR, RTO ≤4 часа.
|
||||
- [ ] Решено: images pull из registry или build на VM.
|
||||
- [ ] Remote telemetry backend выбран либо явно принят ограниченный debug-only режим.
|
||||
- [ ] Риск mock OTP и Safety stub письменно принят.
|
||||
- [ ] Риск mock OTP до SMS cutover и Safety stub письменно принят; real SMS не включается без gates module-11.
|
||||
|
||||
**Ожидаемый результат:** есть release checklist с конкретными values; не создано ни одной публичной БД/Redis.
|
||||
|
||||
@@ -90,7 +93,7 @@ Security groups:
|
||||
| internet | VM | TCP 80 | allow для redirect/ACME |
|
||||
| internet | VM | TCP 443 | allow |
|
||||
| VM private IP/SG | managed PG | `<PG_PORT>` | allow |
|
||||
| VM | internet | 443 | allow egress: registry, Bitrix, S3, OTLP, ACME |
|
||||
| VM | internet | 443 | allow egress: registry, Bitrix, S3, OTLP, ACME, i-Digital Direct |
|
||||
| internet | managed PG | any | deny |
|
||||
| internet | VM | 6379, 4317, 4318, 8000, 8080, 9000 | deny |
|
||||
|
||||
@@ -197,7 +200,7 @@ CA managed PostgreSQL скачать из панели или документа
|
||||
|
||||
Прототип `init-managed-postgres.py` выдаёт runtime roles `CREATE` на schema и печатает DSN. Это допустимо только для bootstrap/dev, но **слишком широко для production runtime**. Перед production адаптировать:
|
||||
|
||||
1. создать пять schemas: `han_app`, `bitrix_local`, `bitrix_sync`, `keycloak`, `message_safety`;
|
||||
1. создать шесть schemas: `han_app`, `bitrix_local`, `bitrix_sync`, `keycloak`, `message_safety`, `sms`;
|
||||
2. создать runtime roles;
|
||||
3. создать migration roles либо controlled admin job;
|
||||
4. schema owner = migration role;
|
||||
@@ -239,14 +242,15 @@ psql "host=<PG_PRIVATE_HOST> port=<PG_PORT> dbname=<PG_DATABASE> user=<RUNTIME_U
|
||||
2. `bitrix-local-app` Alembic владеет `bitrix_local`;
|
||||
3. `message-safety` stub не создаёт PG tables до production implementation;
|
||||
4. `bitrix-sync` stub — optional empty baseline;
|
||||
5. Keycloak мигрирует standard tables сам; custom provider имеет собственные versioned migrations.
|
||||
5. Keycloak мигрирует standard tables сам; custom provider имеет собственные versioned migrations;
|
||||
6. `sms-service` владеет versioned migrations/seed schema `sms`; runtime `sms_user` не имеет доступа к `han_app`/`keycloak`.
|
||||
|
||||
Только expand/migrate/contract. Destructive migration — отдельный backup, approval и release. Downgrade data migrations не обещается; rollback приложения требует backward-compatible schema.
|
||||
|
||||
### Gate 3
|
||||
|
||||
- [ ] Backups/PITR/TLS/deletion protection включены.
|
||||
- [ ] Пять schemas/roles созданы.
|
||||
- [ ] Шесть schemas/roles созданы, включая `sms`/`sms_user`.
|
||||
- [ ] Runtime roles не имеют DDL/чужого доступа.
|
||||
- [ ] Migration credentials отделены от runtime.
|
||||
- [ ] Empty/previous-version migration test успешен.
|
||||
@@ -366,6 +370,7 @@ openssl rand -hex 32
|
||||
- Redis ACL credentials/URLs DB0/1/2;
|
||||
- public web/API/auth URLs;
|
||||
- Keycloak realm/audience/hostname/bootstrap/provider technical secrets;
|
||||
- SMS DB URL, парные Keycloak↔SMS tokens, Direct `TOKEN_1`, callback URL и отдельные callback credentials;
|
||||
- paired service tokens из arch-02;
|
||||
- Bitrix client/application/webhook/encryption secrets;
|
||||
- S3 endpoint/buckets/API and read-only Safety credentials;
|
||||
@@ -378,6 +383,7 @@ openssl rand -hex 32
|
||||
```text
|
||||
BITRIX_LOCAL_APP_INTERNAL_TOKEN == BITRIX_INTERNAL_API_TOKEN
|
||||
BITRIX_API_FORWARD_TOKEN == BITRIX_API_INBOX_TOKEN
|
||||
KEYCLOAK_SMS_SERVICE_TOKEN == SMS_SERVICE_TOKEN
|
||||
```
|
||||
|
||||
Service token и webhook token — разные secrets.
|
||||
@@ -398,6 +404,7 @@ Service token и webhook token — разные secrets.
|
||||
- Safety timeout согласован с nginx;
|
||||
- secrets minimum length;
|
||||
- mock OTP risk flag explicitly accepted.
|
||||
- placeholders `change-me`/`<...>` запрещены; real mode требует sender/template/API key/callback credentials и recorded static egress IP;
|
||||
|
||||
```bash
|
||||
cd <BACKEND_ROOT>
|
||||
@@ -466,12 +473,13 @@ cd <BACKEND_ROOT>
|
||||
docker compose config --services
|
||||
```
|
||||
|
||||
Ожидаются: `nginx`, `api-backend`, `message-safety`, `keycloak`, `bitrix-sync`, `bitrix-local-app`, `redis`, `otel-collector` и one-shot jobs/profile components.
|
||||
В целевом real-SMS release ожидаются: `nginx`, `api-backend`, `message-safety`, `keycloak`, `sms-service`, `sms-worker` (либо документированный worker process), `bitrix-sync`, `bitrix-local-app`, `redis`, `otel-collector` и one-shot jobs/profile components.
|
||||
|
||||
Networks:
|
||||
|
||||
- `public`: nginx и минимально Keycloak/frontend path;
|
||||
- `backend`: internal services/Redis;
|
||||
- `egress`: только утверждённые outbound workers; Keycloak в неё не входит, `sms-worker` входит;
|
||||
- `observability`: services + Collector.
|
||||
|
||||
Volumes:
|
||||
@@ -661,6 +669,25 @@ docker compose run --rm api-backend python -m app.cli.validate_settings
|
||||
- [ ] Mandatory settings valid; secrets отсутствуют в `app_settings`.
|
||||
- [ ] Backward compatibility с текущими images подтверждена.
|
||||
|
||||
### 13.4. Controlled rollout real SMS
|
||||
|
||||
До переключения Keycloak:
|
||||
|
||||
1. применить App DB seed `otp.phone.code_length`, `otp.phone.ttl_seconds`, `otp.phone.sms_order_timeout_ms`;
|
||||
2. создать schema/role `sms`, применить migrations и idempotent seed `sms_setting`/active approved `auth_otp`;
|
||||
3. в test environment развернуть `sms-service`/worker с локальным mock Direct и выполнить contract/E2E;
|
||||
4. получить production Direct `TOKEN_1`, согласованные sender и template, отдельные callback credentials;
|
||||
5. определить egress IP фактическим запросом из `sms-worker`, подтвердить его статичность/NAT, записать в inventory и передать Direct для allowlist;
|
||||
6. развернуть production `sms-service`/worker и callback route, оставив `KEYCLOAK_OTP_MOCK_ENABLED=true`;
|
||||
7. применить Keycloak expand migration/SPI, мигрировать старые challenges по module-11;
|
||||
8. выполнить provider smoke отдельной ops-командой на `<IDGTL_TEST_PHONE>`; проверить journal, callback, redaction и отсутствие duplicate;
|
||||
9. только после подписанных evidence переключить `KEYCLOAK_OTP_MOCK_ENABLED=false`;
|
||||
10. проверить durable order до Direct response, resend/superseded, expiry snapshot, limits и verify при provider reject/timeout.
|
||||
|
||||
Production cutover запрещён при любом placeholder, несогласованном sender/template, отсутствующем API key/callback credentials, неподтверждённом callback IP или нестатическом egress IP. Direct API key — готовый `TOKEN_1` для Basic, повторно Base64 не кодируется.
|
||||
|
||||
Rollback SMS: немедленно вернуть Keycloak в mock mode; не удалять schema/journal и не откатывать migrations без доказанной backward compatibility. Остановить новые real orders, дать worker завершить либо зафиксировать in-flight/`uncertain`; предпочтителен forward-fix.
|
||||
|
||||
## 14. Stage 11 — Keycloak bootstrap
|
||||
|
||||
### 14.1. Первый старт
|
||||
@@ -713,22 +740,25 @@ Custom OTP tables мигрируются versioned mechanism до включен
|
||||
Архитектурный порядок:
|
||||
|
||||
1. Redis;
|
||||
2. Keycloak;
|
||||
3. OTEL Collector;
|
||||
4. Message Safety;
|
||||
5. API backend;
|
||||
6. Bitrix local app;
|
||||
7. Bitrix sync;
|
||||
8. nginx.
|
||||
2. OTEL Collector;
|
||||
3. API backend/settings;
|
||||
4. SMS service/worker после migrations (при SMS release; Keycloak пока mock);
|
||||
5. Keycloak;
|
||||
6. Message Safety;
|
||||
7. Bitrix local app;
|
||||
8. Bitrix sync;
|
||||
9. nginx.
|
||||
|
||||
Команды:
|
||||
|
||||
```bash
|
||||
cd <BACKEND_ROOT>
|
||||
docker compose up -d redis
|
||||
docker compose up -d keycloak otel-collector
|
||||
docker compose up -d message-safety
|
||||
docker compose up -d otel-collector
|
||||
docker compose up -d api-backend
|
||||
docker compose up -d sms-service sms-worker
|
||||
docker compose up -d keycloak
|
||||
docker compose up -d message-safety
|
||||
docker compose up -d bitrix-local-app bitrix-sync
|
||||
docker compose up -d nginx
|
||||
docker compose ps
|
||||
@@ -827,6 +857,7 @@ Expected: 308; public 200 strict DTO; discovery 200; internal 404; valid cert.
|
||||
- silent refresh работает без OTP;
|
||||
- logout очищает tokens;
|
||||
- wrong/replayed OTP не выдаёт tokens.
|
||||
- real mode: durable order возвращает `sms_message_id` до Direct response; callback обновляет только SMS journal; resend делает старый challenge `superseded`.
|
||||
|
||||
### 17.3. Message Safety правила stub
|
||||
|
||||
@@ -955,13 +986,14 @@ DB backup включает realm/users/signing keys/provider data. Secret-free r
|
||||
### Application-only
|
||||
|
||||
1. объявить incident/maintenance;
|
||||
2. сохранить diagnostics и current state;
|
||||
3. остановить новые claims/send при возможности;
|
||||
4. переключить image tags на previous digests;
|
||||
5. не выполнять Alembic downgrade;
|
||||
6. `docker compose up -d`;
|
||||
7. health/smoke/idempotency;
|
||||
8. проверить outbox/inbox/recovery.
|
||||
2. при SMS incident вернуть `KEYCLOAK_OTP_MOCK_ENABLED=true`, прекратить новые real orders и сохранить journal/in-flight state;
|
||||
3. сохранить diagnostics и current state;
|
||||
4. остановить новые claims/send при возможности;
|
||||
5. переключить image tags на previous digests;
|
||||
6. не выполнять Alembic downgrade;
|
||||
7. `docker compose up -d`;
|
||||
8. health/smoke/idempotency;
|
||||
9. проверить outbox/inbox/SMS pending/uncertain/recovery.
|
||||
|
||||
### После backward-incompatible migration
|
||||
|
||||
@@ -1162,7 +1194,7 @@ certbot delete active cert
|
||||
- D-A2: обязательный минимум — `otel-collector`; доступность remote backend не предполагается до закрытия D-TBD11, local Grafana stack не обязателен.
|
||||
- D-A3: managed provider даёт private network, TLS, backups/PITR.
|
||||
- D-A4: Bitrix portal/connector/line остаются разрешёнными значениями architecture.
|
||||
- D-A5: mock OTP временно разрешён как documented risk.
|
||||
- D-A5: mock OTP временно разрешён до controlled SMS cutover как documented risk.
|
||||
|
||||
### TBD до production
|
||||
|
||||
@@ -1186,8 +1218,9 @@ certbot delete active cert
|
||||
4. Прототипные TLS scripts используют отдельный service Compose/standalone downtime, тогда как целевая архитектура требует root Compose и two-phase webroot.
|
||||
5. Prototype публиковал `/bitrix-internal/*` и использовал `/internal/v1/*`; целевой контур это запрещает и использует `/internal/openlines/v1/*`.
|
||||
6. `arch-04` не содержит ряд proposed env из module-04–09; production `.env.example` должен быть синхронизирован до реализации.
|
||||
7. Точные RPO/RTO, retention, SLO, Keycloak version/TTL и Bitrix retry semantics не утверждены; начальные значения runbook не закрывают product/security decision.
|
||||
7. Точные RPO/RTO, SLO, Keycloak version и Bitrix retry semantics не утверждены; OTP TTL задаётся `app_settings`, SMS journal по module-11 хранится бессрочно.
|
||||
8. `init-managed-postgres.py` по умолчанию не задаёт TLS parameters при bootstrap connection и печатает credential-bearing DSN; его production-hardening обязателен.
|
||||
9. Текущие Compose/env/config artifacts могут ещё не содержать `sms-service`; документация не разрешает real mode до реализации и прохождения rollout gates.
|
||||
|
||||
## 29. Ссылки на прототип
|
||||
|
||||
|
||||
Reference in New Issue
Block a user