314 lines
12 KiB
Markdown
314 lines
12 KiB
Markdown
# Runtime Config
|
||
|
||
## 1. Назначение документа
|
||
|
||
Этот документ фиксирует конфигурацию окружения, storage и базовые operational assumptions для MVP.
|
||
|
||
Его задача - убрать неявные решения, которые обычно всплывают уже в процессе написания кода.
|
||
|
||
## 2. Базовые решения для MVP
|
||
|
||
- каноническая БД: `PostgreSQL`
|
||
- локальная разработка и тесты используют ту же `PostgreSQL`-модель хранения
|
||
- artifact storage: локальная файловая система
|
||
- MCP transport: `Streamable HTTP`
|
||
- admin API и mcp-server запускаются как отдельные приложения
|
||
|
||
## 3. Artifact storage
|
||
|
||
В MVP sample JSON, `.proto`, `descriptor set` и YAML import payload должны храниться в локальном файловом storage.
|
||
|
||
Требования:
|
||
|
||
- все файлы кладутся в контролируемый базовый каталог;
|
||
- в БД хранится только `storage_ref`;
|
||
- структура каталогов должна быть детерминированной;
|
||
- storage слой должен быть абстрагирован, чтобы потом заменить его на S3-compatible backend.
|
||
|
||
Рекомендуемая структура:
|
||
|
||
```text
|
||
var/crank/
|
||
samples/
|
||
descriptors/
|
||
yaml-imports/
|
||
```
|
||
|
||
## 4. Секреты и auth profiles
|
||
|
||
Для целевой модели:
|
||
|
||
- operation хранит только `auth_profile_ref`;
|
||
- `AuthProfile` хранит только ссылки на `secret_id`;
|
||
- plaintext секреты не должны попадать в YAML export;
|
||
- plaintext секреты не должны логироваться;
|
||
- runtime получает секрет только на короткое время перед upstream вызовом.
|
||
|
||
Стартовая реализация:
|
||
|
||
- `PostgreSQL`-backed secret store;
|
||
- `ciphertext` хранится в БД;
|
||
- шифрование выполняется через `CRANK_MASTER_KEY`;
|
||
- ключ шифрования приходит только из env.
|
||
|
||
## 5. Переменные окружения
|
||
|
||
Минимально ожидаются:
|
||
|
||
- `POSTGRES_HOST`
|
||
- `POSTGRES_PORT`
|
||
- `POSTGRES_DB`
|
||
- `POSTGRES_USER`
|
||
- `POSTGRES_PASSWORD`
|
||
- `POSTGRES_MAX_CONNECTIONS`
|
||
- `POSTGRES_MIN_CONNECTIONS`
|
||
- `POSTGRES_ACQUIRE_TIMEOUT_MS`
|
||
- `POSTGRES_IDLE_TIMEOUT_MS`
|
||
- `POSTGRES_MAX_LIFETIME_MS`
|
||
- `CRANK_ADMIN_API_IMAGE`
|
||
- `CRANK_MCP_SERVER_IMAGE`
|
||
- `CRANK_UI_IMAGE`
|
||
- `CRANK_STORAGE_ROOT`
|
||
- `CRANK_PUBLISH_BIND`
|
||
- `CRANK_ADMIN_BIND`
|
||
- `CRANK_ADMIN_RATE_LIMIT_RPS`
|
||
- `CRANK_ADMIN_RATE_LIMIT_BURST`
|
||
- `CRANK_MCP_BIND`
|
||
- `CRANK_MCP_REFRESH_MS`
|
||
- `CRANK_MCP_RATE_LIMIT_RPS`
|
||
- `CRANK_MCP_RATE_LIMIT_BURST`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS`
|
||
- `CRANK_LOG_LEVEL`
|
||
- `CRANK_MASTER_KEY`
|
||
- `CRANK_BASE_URL`
|
||
|
||
Опционально:
|
||
|
||
- `CRANK_ADMIN_TOKEN`
|
||
- `CRANK_DEMO_SEED`
|
||
- `CRANK_CACHE_BACKEND`
|
||
- `CRANK_CACHE_URL`
|
||
- `CRANK_CACHE_DEFAULT_TTL_MS`
|
||
|
||
Стартовое значение для refresh published tools:
|
||
|
||
- `CRANK_ADMIN_RATE_LIMIT_RPS=30`
|
||
- `CRANK_ADMIN_RATE_LIMIT_BURST=60`
|
||
- `CRANK_MCP_REFRESH_MS=5000`
|
||
- `CRANK_MCP_RATE_LIMIT_RPS=60`
|
||
- `CRANK_MCP_RATE_LIMIT_BURST=120`
|
||
|
||
Стартовые значения для runtime concurrency limits:
|
||
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY=64`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW=16`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS=16`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS=16`
|
||
|
||
## 6. Логирование и трассировка
|
||
|
||
Для MVP нужно использовать:
|
||
|
||
- structured logging через `tracing`;
|
||
- correlation id для test runs и runtime execution;
|
||
- раздельные стадии ошибок: schema, mapping, adapter, external service.
|
||
|
||
## 7. Таймауты и retries
|
||
|
||
Рекомендуемые стартовые значения:
|
||
|
||
- default timeout: `10s`
|
||
- retry default: `1` attempt, то есть без автоматического повтора
|
||
|
||
Причина:
|
||
|
||
- сначала важнее детерминированность и прозрачность;
|
||
- aggressive retries могут маскировать реальные ошибки интеграции.
|
||
|
||
## 8. Режимы запуска
|
||
|
||
Минимально нужны два режима:
|
||
|
||
- local development
|
||
- demo/deployment
|
||
|
||
Local development:
|
||
|
||
- локальное окружение должно иметь доступ к `PostgreSQL`;
|
||
- локальный storage;
|
||
- app-level auth и bootstrap admin user через `.env`.
|
||
- при необходимости UI можно наполнить живыми demo-данными через `CRANK_DEMO_SEED=true`.
|
||
|
||
Demo/deployment:
|
||
|
||
- `PostgreSQL`;
|
||
- локальный или сетевой storage;
|
||
- включенная app-level auth-защита admin-api;
|
||
- стабильный `Streamable HTTP` endpoint для MCP.
|
||
- containerized runtime через `Docker` и `docker-compose`.
|
||
- optional shared cache layer через `Valkey/Redis`.
|
||
- registry-backed image rollout через Gitea Container Registry или совместимый registry.
|
||
|
||
### Cache env
|
||
|
||
Для optional cache/coordination layer должны быть предусмотрены:
|
||
|
||
- `CRANK_CACHE_BACKEND`
|
||
- `CRANK_CACHE_URL`
|
||
- `CRANK_CACHE_DEFAULT_TTL_MS`
|
||
|
||
Рекомендуемая модель:
|
||
|
||
- `CRANK_CACHE_BACKEND=memory` по умолчанию;
|
||
- `CRANK_CACHE_BACKEND=valkey` или `redis` при наличии внешнего cache store;
|
||
- без этих переменных система должна оставаться полностью работоспособной.
|
||
|
||
### Cache boundaries
|
||
|
||
В платформе должны существовать два разных cache-контура:
|
||
|
||
- `platform / coordination cache`
|
||
- `response cache`
|
||
|
||
Первый контур хранит служебное краткоживущее состояние:
|
||
|
||
- ingress rate limiting;
|
||
- replay guard;
|
||
- ephemeral coordination state;
|
||
- shared snapshots published MCP catalogs between instances;
|
||
|
||
Второй контур хранит только кэшируемые ответы операций.
|
||
|
||
Текущий безопасный runtime scope для response cache:
|
||
|
||
- `REST GET`;
|
||
|
||
Это не означает автоматическое кэширование всех REST-вызовов. Кэширование
|
||
разрешается только для безопасных `GET` operations без upstream auth profile.
|
||
|
||
Эти контуры не должны смешивать ключи друг с другом.
|
||
|
||
### Cache key isolation
|
||
|
||
Базовое правило изоляции:
|
||
|
||
- разные `workspace` не должны делить одни и те же cache keys;
|
||
- разные `agent` внутри одного `workspace` тоже не должны делить одни и те же response cache keys по умолчанию;
|
||
- разные `operation` внутри одного `agent` не должны попадать в общий response cache namespace.
|
||
|
||
Стартовая модель namespace для response cache:
|
||
|
||
- `workspace + agent + operation + operation version + request fingerprint`
|
||
|
||
Стартовая модель namespace для platform / coordination cache:
|
||
|
||
- `workspace + agent + cache scope + logical key`
|
||
|
||
Это позволяет безопасно использовать один внешний `Valkey/Redis` сразу для нескольких агентов и рабочих областей без взаимного пересечения данных.
|
||
|
||
### Auth env
|
||
|
||
Для app-level auth нужны:
|
||
|
||
- `CRANK_SESSION_SECRET`
|
||
- `CRANK_PASSWORD_PEPPER`
|
||
- `CRANK_BOOTSTRAP_ADMIN_EMAIL`
|
||
- `CRANK_BOOTSTRAP_ADMIN_PASSWORD`
|
||
- `CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME`
|
||
|
||
Для secret store foundation нужен:
|
||
|
||
- `CRANK_MASTER_KEY`
|
||
|
||
`CRANK_MASTER_KEY` обязателен и для `admin-api`, и для `mcp-server`, потому что оба приложения
|
||
должны уметь резолвить `secret_id` в runtime.
|
||
|
||
Для опционального demo-seed:
|
||
|
||
- `CRANK_DEMO_SEED=true`
|
||
|
||
В deployment workflow больше не используется монолитный `DEPLOY_ENV_FILE`.
|
||
|
||
`.env` на сервере собирается из OpenBao. В Gitea Actions хранятся только AppRole credentials
|
||
`BAO_ADDR`, `BAO_ROLE_ID` и `BAO_SECRET_ID`, а внутри OpenBao ключи проекта
|
||
`projects/crank/runtime` совпадают с именами runtime env-переменных. Это значит, что:
|
||
|
||
- `CRANK_MASTER_KEY` хранится в OpenBao как ключ `CRANK_MASTER_KEY`;
|
||
- `CRANK_DEMO_SEED` хранится в OpenBao как ключ `CRANK_DEMO_SEED`;
|
||
- и так же для остальных runtime-переменных.
|
||
|
||
Для БД основной runtime-контракт теперь компонентный:
|
||
|
||
- `POSTGRES_HOST`
|
||
- `POSTGRES_PORT`
|
||
- `POSTGRES_DB`
|
||
- `POSTGRES_USER`
|
||
- `POSTGRES_PASSWORD`
|
||
- `POSTGRES_MAX_CONNECTIONS`
|
||
- `POSTGRES_MIN_CONNECTIONS`
|
||
- `POSTGRES_ACQUIRE_TIMEOUT_MS`
|
||
- `POSTGRES_IDLE_TIMEOUT_MS`
|
||
- `POSTGRES_MAX_LIFETIME_MS`
|
||
|
||
Для pool behavior используются явные defaults:
|
||
|
||
- `POSTGRES_MAX_CONNECTIONS=20`
|
||
- `POSTGRES_MIN_CONNECTIONS=2`
|
||
- `POSTGRES_ACQUIRE_TIMEOUT_MS=5000`
|
||
- `POSTGRES_IDLE_TIMEOUT_MS=600000`
|
||
- `POSTGRES_MAX_LIFETIME_MS=1800000`
|
||
|
||
Для runtime concurrency используются явные defaults:
|
||
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY=64`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW=16`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS=16`
|
||
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS=16`
|
||
|
||
Для MCP transport ingress throttling используются явные defaults:
|
||
|
||
- `CRANK_MCP_RATE_LIMIT_RPS=60`
|
||
- `CRANK_MCP_RATE_LIMIT_BURST=120`
|
||
|
||
Для admin-api ingress throttling используются явные defaults:
|
||
|
||
- `CRANK_ADMIN_RATE_LIMIT_RPS=30`
|
||
- `CRANK_ADMIN_RATE_LIMIT_BURST=60`
|
||
|
||
`CRANK_DATABASE_URL` допускается только как backward-compatible fallback для локальных тестов и
|
||
переходного периода, но не как основная deployment-модель.
|
||
|
||
## 8.1. Delivery artifacts
|
||
|
||
Для production-like запуска проект должен поставляться с:
|
||
|
||
- `Dockerfile` для backend приложений;
|
||
- `deploy/community/docker-compose.yml` как canonical Community deployment manifest;
|
||
- `deploy/community/.env.example` как canonical Community env template;
|
||
- optional `Valkey` service как рекомендованный, но не обязательный компонент Community deployment;
|
||
- root `docker-compose.yml` и root `.env.example` только как local development convenience files;
|
||
- healthcheck endpoints;
|
||
- reverse proxy configuration examples.
|
||
|
||
Подробности вынесены в `docs/deployment.md`.
|
||
|
||
## 9. Что важно не допустить
|
||
|
||
- пути к storage, зашитые в код;
|
||
- секреты в `.yaml` exports;
|
||
- разные конфигурационные модели для local и production без причины;
|
||
- смешивание runtime config и business config operation.
|
||
|
||
## 10. Практический итог
|
||
|
||
До старта разработки должны быть приняты как минимум такие решения:
|
||
|
||
- где лежит БД;
|
||
- где лежат artifacts;
|
||
- как резолвятся `secret_id` и как ротируется `CRANK_MASTER_KEY`;
|
||
- на каких bind-address запускаются `admin-api` и `mcp-server`;
|
||
- какой transport использует MCP server.
|