Конфигурация API сервера
Сервер API Bencher требует JSON-конфигурацию при запуске. Конфигурация может быть предоставлена тремя способами:
- Переменная окружения
BENCHER_CONFIG: Значение должно быть установлено как JSON-конфигурация - Переменная окружения
BENCHER_CONFIG_PATH: Значение должно быть установлено как путь к файлу, содержащему JSON-конфигурацию - Файл
/etc/bencher/bencher.json: Файл в этом расположении, содержащий JSON-конфигурацию
Если конфигурация не найдена, загружается конфигурация по умолчанию.
Пример JSON-конфигурации:
{ "console": { "url": "https://bencher.example.com" }, "security": { "issuer": "https://api.bencher.example.com", "secret_key": "UJu7Cpxb-zFaJYqXD-3mDDSDyj-ZvfxZFZs-X58xjxPy" }, "server": { "bind_address": "0.0.0.0:6610", "request_body_max_bytes": 1048576, "tls": { "type": "as_file", "cert_file": "/path/to/cert.pem", "key_file": "/path/to/key.pem" } }, "logging": { "name": "Bencher API", "log": { "stderr_terminal": { "level": "info" } } }, "database": { "file": "/var/lib/bencher/data/bencher.db", "busy_timeout": 5000, "cache_size": 65536 }, "smtp": { "hostname": "mailbonobo.com", "port": 587, "starttls": true, "username": "bencher", "secret": "WM3F2u9cqSNdBPLfy9sJ5kk9", "from_name": "Bencher", "from_email": "info@bencher.example.com" }, "plus": { "disaster_recovery": { "replica": { "scheme": "s3", "bucket": "my-bucket", "path": "path/to/replicate", "access_key_id": "ABC123DoRemMiABC123", "secret_access_key": "AA3Chr-JSF5sUQqKwayx-FvCfZKsMev-5BqPpcFC3m7" } }, "registry": { "url": "https://registry.bencher.example.com", "storage": { "scheme": "s3", "bucket": "my-bucket", "path": "registry", "endpoint": "https://s3.example.com", "region": "auto", "access_key_id": "AKIAIOSFODNN7EXAMPLE", "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "chunk_size": 5242880 }, "upload_timeout": 3600, "max_body_size": 1073741824 }, "runners": { "heartbeat_timeout": 90, "job_timeout_grace_period": 60, "update_base_url": "https://github.com/bencherdev/bencher/releases/download/" }, "rate_limiting": { "window": 86400, "unclaimed_limit": 255, "claimed_limit": 65536, "plus_limit": 1048576, "public": { "requests": { "minute": 1024, "hour": 4096, "day": 8192 }, "attempts": { "minute": 32, "hour": 64, "day": 128 }, "runs": { "minute": 64, "hour": 128, "day": 256 } }, "user": { "requests": { "minute": 2048, "hour": 8192, "day": 16384 }, "attempts": { "minute": 2, "hour": 4, "day": 8 }, "credentials": { "minute": 4, "hour": 8, "day": 16 }, "organizations": { "minute": 2, "hour": 4, "day": 8 }, "invites": { "minute": 8, "hour": 16, "day": 32 }, "runs": { "minute": 64, "hour": 1024, "day": 4096 } }, "project": { "requests": { "minute": 2048, "hour": 8192, "day": 16384 }, "runs": { "minute": 64, "hour": 1024, "day": 4096 } }, "runner": { "requests": { "minute": 16, "hour": 256, "day": 4096 } }, "oci_bandwidth": { "unclaimed": 1073741824, "free": 10737418240, "plus": 107374182400 } }, "stats": { "offset": 11242, "enabled": true }, "mcp": { "openai_apps_challenge": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" }, "oauth": { "issuer": "https://api.bencher.example.com", "resources": [ "https://mcp.bencher.example.com/mcp", "https://api.bencher.example.com/mcp" ], "signing_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASC...\n-----END PRIVATE KEY-----\n" } }}console
| Имя | Пример | По умолчанию | Обяз. | Описание |
|---|---|---|---|---|
| url | “https://bencher.example.com” | “http://localhost:3000” | Да | Указывает URL для хоста консоли Bencher UI. |
security
| Имя | Пример | По умолчанию | Обяз. | Описание |
|---|---|---|---|---|
| issuer | “https://api.bencher.example.com” | “bencher.dev” | Нет | Указывает выпускающий орган JSON Web Token (JWT). ВНИМАНИЕ Изменение этого значения приведет к тому, что все ранее созданные JWT больше не проходят проверку. |
| secret_key | “UJu7Cpxb-zFaJYqXD-3mDDSDyj-ZvfxZFZs-X58xjxPy” | Случайный UUID v4 | Да | Указывает ключ, используемый для генерации всех токенов и для запечатывания ожидающих callback. ОН ДОЛЖЕН БЫТЬ ОЧЕНЬ БЕЗОПАСНЫМ! Значение по умолчанию - это случайно сгенерированный UUID v4. При записи он будет выглядеть как ************. |
server
Этот раздел основан на конфигурации сервера Dropshot.
| Имя | Пример | По умолчанию | Обяз. | Описание |
|---|---|---|---|---|
| bind_address | “0.0.0.0:6610” | “0.0.0.0:6610” | Да | Указывает, что сервер должен привязываться к данному IP-адресу и TCP-порту. В общем случае серверы могут привязываться к более чем одному IP-адресу и порту, но это пока не поддерживается. |
| request_body_max_bytes | 1048576 | 1048576 | Да | Указывает максимальное количество байт, разрешенное в теле запроса. Большие запросы получат ошибку 400. |
| tls.type | “as_file” | — | Нет | Указывает, используется ли и как информация о сертификате и ключе TLS. Действительные значения включают “as_file” и “as_bytes”. |
| tls.cert_file | “/path/to/cert.pem” | — | Только если tls.type = as_file | Указывает путь к файлу PEM, содержащему сертификат для идентификации сервера. Первый сертификат - это конечный сертификат субъекта, а оставшиеся - промежуточные сертификаты на пути к доверенному CA. Если указано, сервер будет прослушивать только TLS-соединения. |
| tls.key_file | “/path/to/key.pem” | — | Только если tls.type = as_file | Указывает путь к файлу PEM, содержащему закрытый ключ, который будет использовать сервер. Если указано, сервер будет прослушивать только TLS-соединения. |
| tls.certs | — | — | Только если tls.type = as_bytes | То же, что и tls.cert_file, но предоставляемое в виде массива байт данных сертификата. |
| tls.key | — | — | Только если tls.type = as_bytes | То же, что и tls.key_file, но предоставляемое в виде массива байт данных ключа. |
logging
Этот раздел основан на конфигурации журнала Dropshot.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| name | “Bencher API” | “Bencher API” | Да | Задает название логгера. |
| log.level | “info” | “info” | Да | Задает уровень тяжести сообщений в логе. Допустимые значения включают “trace”, “debug”, “info”, “warn”, “error” и “critical”, которые отражают растущую тяжесть. Сообщения лога указанного уровня и более высоких уровней будут включены в лог. |
| log.path | — | — | Только если log.mode = “file” | Если log.mode равно “file”, это свойство определяет путь к файлу журнала. Смотри также log.if_exists. |
| log.if_exists | — | — | Только если log.mode = “file” | Если log.mode равно “file”, это свойство задает что делать, если файл журнала уже существует. Допустимые значения включают “append” (что добавляет к существующему файлу), “truncate” (приведение существующего файла к изначальному), и “fail” (сервер немедленно остановит работу с выводом ошибки). |
database
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| file | “path/to/database.db” | “/var/lib/bencher/data/bencher.db” | Да | Управляет расположением базы данных сервера. |
| busy_timeout | 5000 | 5000 | Нет | Указывает тайм-аут занятости для базы данных в миллисекундах. Предотвращает немедленные ошибки SQLITE_BUSY при блокировке. |
| cache_size | 65536 | 65536 | Нет | Указывает размер страничного кэша в КиБ для соединения записи базы данных. Больший кэш позволяет избежать повторного чтения вытесненных страниц при больших загрузках и удалениях отчетов. Должен быть больше 0. |
smtp
Этот раздел определяет конфигурацию службы SMTP.
Весь раздел является необязательным.
Если не указано, все сообщения будут отправляться в logging.
| Имя | Пример | Значение по умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| hostname | “mailbonobo.com” | — | Да | Указывает имя хоста SMTP. |
| port | 587 | 587 | Нет | Указывает порт SMTP. |
| insecure_host | — | false | Нет | Управляет разрешением недействительных TLS-сертификатов для подключения SMTP. |
| starttls | true | true | Нет | Управляет использованием протокола STARTTLS для подключения SMTP. |
| username | “bencher” | — | Да | Указывает имя пользователя на хосте SMTP. |
| secret | “WM3F2u9cqSNdBPLfy9sJ5kk9” | — | Да | Указывает секрет для имени пользователя на хосте SMTP. При записи он будет отображаться в виде ************. |
| from_name | “Bencher” | — | Да | Указывает имя, которое будет отображаться в разделе “от” всех электронных писем. |
| from_email | “info@bencher.example.com” | — | Да | Указывает email, который будет отображаться в разделе “от” всех электронных писем. |
plus
Этот раздел посвящен функциям, которые покрываются лицензией Bencher Plus.
plus.github
В этом разделе указывается конфигурация приложения GitHub, используемого для аутентификации OAuth2. У вас должна быть действующая лицензия Bencher Plus Enterprise для хотя бы одной организации на сервере. Весь раздел является необязательным. Если он не указан, то аутентификация с помощью GitHub не будет включена.
| Название | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| client_id | Iv1.12864abcd1232048 | — | Да | Указывает идентификатор клиента для вашего приложения GitHub. Идентификатор клиента отличается от идентификатора приложения. Вы можете найти идентификатор клиента на странице настроек вашего приложения. Для получения дополнительной информации о переходе на страницу настроек вашего приложения GitHub, см. Изменение регистрации приложения GitHub. |
| client_secret | 00000abcd12345wxyz123456789abcdefgh0000 | — | Да | Секретный ключ клиента для вашего приложения GitHub. Вы можете сгенерировать секретный ключ на странице настроек вашего приложения. |
| app | { … } | — | Нет | Указывает приложение GitHub, которое выпускает токен dispatch для связанного репозитория проекта. Это должно быть то же приложение GitHub, чей идентификатор клиента указан в client_id. Приложению нужен доступ на чтение и запись к содержимому репозитория. Если он не указан, то ни один проект не может связать репозиторий. |
| app.slug | my-bencher-app | — | Да | Имя вашего приложения GitHub в его URL, как в https://github.com/apps/my-bencher-app. Оно указывает страницу, на которой пользователь устанавливает приложение. |
| app.private_key | “—–BEGIN RSA PRIVATE KEY—–\n…” | — | Да | Закрытый ключ вашего приложения GitHub в формате PEM. Вы можете создать закрытый ключ на странице настроек вашего приложения. |
| app.webhook_secret | 0123456789abcdef0123456789abcdef | — | Да | Секрет вебхука вашего приложения GitHub. Вы можете задать секрет вебхука на странице настроек вашего приложения. |
plus.google
В этом разделе задаётся конфигурация для Google-клиента, используемого для аутентификации через OAuth2. У вас должна быть действительная лицензия Bencher Plus Enterprise хотя бы для одной организации на сервере. Весь раздел является необязательным. Если раздел не указан, аутентификация через Google не будет включена.
| Name | Example | Default | Required | Description |
|---|---|---|---|---|
| client_id | 0123456789-abcdefg0112358envs.apps.googleusercontent.com | — | Да | Указывает идентификатор клиента для вашего клиента Google OAuth2. |
| client_secret | GOCSPX-xyz987654321 | — | Да | Секрет клиента для вашего клиента Google OAuth2. |
plus.disaster_recovery
Этот раздел описывает конфигурацию восстановления после аварий. Bencher поддерживает непрерывное реплицирование всех изменений базы данных.
Существует две схемы репликации:
file: Реплицирование в локальную файловую системуpath: Путь для репликации
s3: Реплицирование в любое совместимое S3 хранилищеbucket: Имя bucketpath: (Опционально) Путь в bucketendpoint: (AWS: Опционально | Не AWS: Обязательно) Конечная точка репликацииregion: (Опционально) Регион bucketaccess_key_id: Ключ доступа S3secret_access_key: Секретный ключ доступа S3
Обе схемы репликации имеют следующие дополнительные опции:
snapshot.interval: (Опционально) Указывает, как часто будут создаваться новые snapshots. Это используется для уменьшения времени восстановления, так как новые snapshots будут содержать меньшее количество WAL кадров для применения. Политика retention также применяется к этим snapshots. Если вы не указываете интервал создания snapshot, то новый snapshot будет создан при каждом выполнении retention. По умолчанию retention выполняется каждые 24 часа.snapshot.retention: (Опционально) Время, в течение которого будут сохраняться файлы snapshot и WAL. По истечении этого времени будет создан новый snapshot, а старый будет удален. Файлы WAL, которые существуют до самого старого snapshot, также будут удалены. Значение по умолчанию:24h.validation.interval: (Опционально) Если указано, Bencher автоматически восстановит и проверит, что данные на реплике соответствуют локальной копии. По умолчанию отключено. Включение этой функции может значительно увеличить стоимость запуска Bencher, так как большинство облачных сервисов взимают плату за загрузки.sync_interval: (Опционально) Частота, с которой кадры передаются на реплику. Значение по умолчанию:1s. Увеличение частоты может значительно повысить затраты на облачное хранилище.checkpoint.interval: (Опционально) Как часто Litestream выполняет неблокирующий PASSIVE чекпоинт вне зависимости от количества страниц. Litestream пропускает чекпоинт, если активны читатели или писатели. Значение по умолчанию:1m.checkpoint.min_page_count: (Опционально) Минимальное количество WAL-страниц перед запуском неблокирующего PASSIVE чекпоинта (~4КБ на страницу). Litestream пропускает чекпоинт, если активны читатели или писатели. Значение по умолчанию:1000(~4МБ).checkpoint.truncate_page_n: (Опционально) Пороговое количество страниц для блокирующего TRUNCATE чекпоинта. При достижении этого порога Litestream выполняет блокирующий чекпоинт, ожидающий завершения всех читателей и писателей, что может вызвать ошибкиdatabase is lockedпри нагрузке. Значение по умолчанию:0(отключено). Устанавливайте ненулевое значение только если вам нужен верхний предел размера WAL-файла и вы понимаете последствия блокировки.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| replica | { … } | — | Да | Указывает объект реплики. |
| replica.scheme | “s3” | — | Да | Указывает схему репликации. Для всех остальных ключей replica см. список выше. |
| snapshot.interval | “1h” | — | Нет | Частота создания новых снапшотов. Сокращает время восстановления. |
| snapshot.retention | “24h” | 24h | Нет | Как долго хранятся файлы snapshot и WAL до замены. |
| validation.interval | “6h” | — | Нет | Частота восстановления и проверки данных реплики на соответствие локальной копии. По умолчанию отключено. |
| checkpoint.interval | “1m” | 1m | Нет | Частота выполнения неблокирующего PASSIVE чекпоинта. Пропускается, если активны читатели/писатели. |
| checkpoint.min_page_count | 1000 | 1000 | Нет | Минимальное количество WAL-страниц (~4КБ каждая) перед PASSIVE чекпоинтом. Пропускается, если активны читатели/писатели. |
| checkpoint.truncate_page_n | 0 | 0 | Нет | Пороговое значение страниц для блокирующего TRUNCATE чекпоинта. 0 отключает. Ненулевые значения могут вызвать database is locked при нагрузке. |
plus.registry
Этот раздел определяет конфигурацию хранилища реестра OCI (Open Container Initiative). Bencher может функционировать как OCI-совместимый реестр контейнеров/артефактов.
Если этот раздел не настроен, Bencher будет использовать локальное файловое хранилище
в директории registry рядом с файлом базы данных.
Это подходит для разработки и развёртываний с одним экземпляром.
Для производственных развёртываний с несколькими экземплярами или для надёжности настройте S3-совместимое хранилище.
Доступны два scheme хранилища:
file: Хранение OCI-артефактов в локальной файловой системе (по умолчанию)path: (Опционально) Директория для данных реестра. По умолчанию директорияregistryрядом с файлом базы данных.
s3: Хранение OCI-артефактов в любом совместимом S3 хранилищеbucket: Имя bucketpath: (Опционально) Префикс ключа в bucket. Ведущие, завершающие и повторяющиеся слеши удаляются, поэтомуregistry,registry/и/registryсохраняют всё подregistry.endpoint: (AWS: Опционально | Не AWS: Обязательно) Конечная точка хранилищаregion: (Опционально) Регион bucket. Обязателен для AWS. По умолчаниюauto, что ожидают S3-совместимые хранилища.access_key_id: Ключ доступа S3secret_access_key: Секретный ключ доступа S3chunk_size: (Опционально) Минимальный размер фрагмента в байтах для буферизации данных загрузки перед сохранением. По умолчанию: 5 МБ. Тела HTTP-запросов поступают в виде маленьких сетевых фреймов (обычно от 8 до 64 КБ). Без буферизации каждый фрейм становится отдельным объектом, создавая тысячи объектов на каждый слой. Это значение также соответствует минимальному размеру части для многочастной загрузки S3.
Задайте правило жизненного цикла bucket, которое прерывает незавершённые многочастные загрузки. Сбой в середине завершения загрузки блоба оставляет такую загрузку, и сервер её не прерывает.
Если ранее вы настроили path, начинающийся или заканчивающийся слешем, перенесите существующие объекты на нормализованный префикс перед обновлением. path вида registry/ сохранял ключи под registry//<project>/..., а теперь сохраняет их под registry/<project>/.... Каждый сегмент path также кодируется процентами в сохранённом ключе, если он содержит управляющий символ ASCII, символ вне ASCII или один из \ {` `^` `} % ` ] " > [ ~ < # | * ?, а сегмент, равный ровно . или .., сохраняется как %2E или %2E%2E. Все остальные символы, включая пробелы, +, =, @ и :, сохраняются как есть, поэтому team#1 становится team%231, а team+1 остаётся team+1. Данные, сохранённые под префиксом, который теперь кодируется, требуют того же переноса. Перед переносом любых данных выведите список ключей, фактически сохранённых в бакете, и сравните их с новым префиксом.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| url | “https://registry.bencher.example.com” | “http://localhost:6610” | Нет | Внешне доступный URL API-сервера для доступа к OCI-реестру. |
| storage | { … } | — | Нет | Указывает бэкенд хранилища реестра. Локальные файлы, если не указан. |
| storage.scheme | “s3” | — | Да | Указывает scheme хранилища. Все остальные ключи storage смотрите в списке выше. |
| upload_timeout | 3600 | 3600 | Нет | Тайм-аут сессии загрузки в секундах. Устаревшие загрузки очищаются при запуске новых загрузок. |
| max_body_size | 1073741824 | 1073741824 | Нет | Максимальный размер тела в байтах для загрузки блобов и манифестов. Запросы, превышающие этот лимит, отклоняются с ошибкой 413 Payload Too Large. По умолчанию: 1 ГиБ. |
plus.runners
Этот раздел настраивает систему раннеров для выполнения бенчмарков на bare metal. Раннеры — это серверные агенты, которые запрашивают и выполняют задачи бенчмарков.
Если этот раздел не настроен, Bencher будет использовать значения по умолчанию.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| heartbeat_timeout | 90 | 90 | Нет | Время в секундах без хартбита до пометки задачи как неизвестной. |
| job_timeout_grace_period | 60 | 60 | Нет | Дополнительное время в секундах сверх настроенного тайм-аута задачи до её отмены сервером. |
| update_base_url | https://example.com/downloads/ | GitHub Releases | Нет | Базовый URL для загрузок самообновления раннера. По умолчанию используется URL загрузки GitHub Releases Bencher. |
plus.rate_limiting
Этот раздел определяет ограничения скорости для сервера API. Весь раздел является необязательным. Если не указано, будут использоваться перечисленные значения по умолчанию.
Чтобы предотвратить создание unclaimed проектов,
установите unclaimed_limit на 0.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| window | 86400 | 86400 | Нет | Определяет окно ограничения скорости в секундах. По умолчанию установлено на один день. |
| unclaimed_limit | 255 | 255 | Нет | Контролирует ограничение скорости для unclaimed проектов. Чтобы предотвратить создание unclaimed проектов, установите это значение на 0. |
| claimed_limit | 65536 | 65536 | Нет | Контролирует ограничение скорости для claimed проектов. |
| plus_limit | 1048576 | 1048576 | Нет | Контролирует ограничение скорости метрик для организаций с планом Bencher Plus. |
public
Ограничитель скорости public применяется к каждому IP-адресу для неаутентифицированных запросов.
Каждое подполе содержит ограничения minute, hour и day.
Весь раздел является необязательным.
Если не указано, будут использоваться перечисленные значения по умолчанию.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| requests | { … } | — | Нет | Определяет ограничения скорости запросов по IP-адресу. |
| requests.minute | 1024 | 1024 | Нет | Максимум запросов в минуту на IP-адрес. |
| requests.hour | 4096 | 4096 | Нет | Максимум запросов в час на IP-адрес. |
| requests.day | 8192 | 8192 | Нет | Максимум запросов в день на IP-адрес. |
| attempts | { … } | — | Нет | Определяет ограничения скорости попыток аутентификации по IP-адресу. |
| attempts.minute | 32 | 32 | Нет | Максимум попыток аутентификации в минуту на IP-адрес. |
| attempts.hour | 64 | 64 | Нет | Максимум попыток аутентификации в час на IP-адрес. |
| attempts.day | 128 | 128 | Нет | Максимум попыток аутентификации в день на IP-адрес. |
| runs | { … } | — | Нет | Определяет ограничения скорости запусков бенчмарков по IP-адресу для невостребованных проектов. |
| runs.minute | 64 | 64 | Нет | Максимум запусков бенчмарков в минуту на IP-адрес. |
| runs.hour | 128 | 128 | Нет | Максимум запусков бенчмарков в час на IP-адрес. |
| runs.day | 256 | 256 | Нет | Максимум запусков бенчмарков в день на IP-адрес. |
user
Ограничитель скорости user применяется к каждому аутентифицированному пользователю.
Каждое подполе содержит ограничения minute, hour и day.
Весь раздел является необязательным.
Если не указано, будут использоваться перечисленные значения по умолчанию.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| requests | { … } | — | Нет | Определяет ограничения скорости запросов на пользователя. |
| requests.minute | 2048 | 2048 | Нет | Максимум запросов в минуту на пользователя. |
| requests.hour | 8192 | 8192 | Нет | Максимум запросов в час на пользователя. |
| requests.day | 16384 | 16384 | Нет | Максимум запросов в день на пользователя. |
| attempts | { … } | — | Нет | Определяет ограничения скорости попыток аутентификации на пользователя. |
| attempts.minute | 2 | 2 | Нет | Максимум попыток аутентификации в минуту на пользователя. |
| attempts.hour | 4 | 4 | Нет | Максимум попыток аутентификации в час на пользователя. |
| attempts.day | 8 | 8 | Нет | Максимум попыток аутентификации в день на пользователя. |
| credentials | { … } | — | Нет | Определяет ограничения скорости создания учётных данных на пользователя. |
| credentials.minute | 4 | 4 | Нет | Максимум созданий учётных данных в минуту на пользователя. |
| credentials.hour | 8 | 8 | Нет | Максимум созданий учётных данных в час на пользователя. |
| credentials.day | 16 | 16 | Нет | Максимум созданий учётных данных в день на пользователя. |
| organizations | { … } | — | Нет | Определяет ограничения скорости создания организаций на пользователя. |
| organizations.minute | 2 | 2 | Нет | Максимум созданий организаций в минуту на пользователя. |
| organizations.hour | 4 | 4 | Нет | Максимум созданий организаций в час на пользователя. |
| organizations.day | 8 | 8 | Нет | Максимум созданий организаций в день на пользователя. |
| invites | { … } | — | Нет | Определяет ограничения скорости приглашений на пользователя. |
| invites.minute | 8 | 8 | Нет | Максимум приглашений в минуту на пользователя. |
| invites.hour | 16 | 16 | Нет | Максимум приглашений в час на пользователя. |
| invites.day | 32 | 32 | Нет | Максимум приглашений в день на пользователя. |
| runs | { … } | — | Нет | Определяет ограничения скорости запусков бенчмарков на пользователя. |
| runs.minute | 64 | 64 | Нет | Максимум запусков бенчмарков в минуту на пользователя. |
| runs.hour | 1024 | 1024 | Нет | Максимум запусков бенчмарков в час на пользователя. |
| runs.day | 4096 | 4096 | Нет | Максимум запусков бенчмарков в день на пользователя. |
project
Ограничитель скорости project применяется к каждому проекту.
Каждое подполе содержит ограничения minute, hour и day.
Весь раздел является необязательным.
Если не указано, будут использоваться перечисленные значения по умолчанию.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| requests | { … } | — | Нет | Определяет ограничения скорости запросов на проект. |
| requests.minute | 2048 | 2048 | Нет | Максимум запросов в минуту на проект. |
| requests.hour | 8192 | 8192 | Нет | Максимум запросов в час на проект. |
| requests.day | 16384 | 16384 | Нет | Максимум запросов в день на проект. |
| runs | { … } | — | Нет | Определяет ограничения скорости запусков бенчмарков на проект. |
| runs.minute | 64 | 64 | Нет | Максимум запусков бенчмарков в минуту на проект. |
| runs.hour | 1024 | 1024 | Нет | Максимум запусков бенчмарков в час на проект. |
| runs.day | 4096 | 4096 | Нет | Максимум запусков бенчмарков в день на проект. |
runner
Ограничитель скорости runner применяется к каждому раннеру.
Каждое подполе содержит ограничения minute, hour и day.
Весь раздел является необязательным.
Если не указано, будут использоваться перечисленные значения по умолчанию.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| requests | { … } | — | Нет | Определяет ограничения скорости запросов на раннер. |
| requests.minute | 16 | 16 | Нет | Максимум запросов в минуту на раннер. |
| requests.hour | 256 | 256 | Нет | Максимум запросов в час на раннер. |
| requests.day | 4096 | 4096 | Нет | Максимум запросов в день на раннер. |
oci_bandwidth
oci_bandwidth определяет дневные лимиты пропускной способности OCI-реестра для каждого уровня организации.
Весь раздел является необязательным.
Если не указано, будут использоваться перечисленные значения по умолчанию.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| unclaimed | 1073741824 | 1073741824 | Нет | Максимум байт в день для невостребованных организаций (0 участников). По умолчанию 1 ГиБ. |
| free | 10737418240 | 10737418240 | Нет | Максимум байт в день для бесплатных (востребованных, без платного плана) организаций. По умолчанию 10 ГиБ. |
| plus | 107374182400 | 107374182400 | Нет | Максимум байт в день для организаций Plus (Pro/Enterprise). По умолчанию 100 ГиБ. |
plus.stats
В этом разделе указывается, собираются ли и когда статистические данные сервера.
Весь раздел является необязательным.
Если он не указан, будут использованы перечисленные значения по умолчанию.
То есть, статистика сервера собирается, если вы на это не отказываетесь.
Установите значение enabled в false, чтобы отключить сбор статистики сервера.
| Название | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| offset | 11242 | 11242 | Нет | Определяет смещение от полуночи в секундах для сбора статистики сервера. По умолчанию это происходит в 03:07:22 UTC. |
| enabled | true | true | Нет | Контролирует, собирается ли статистика сервера. Установите значение false, чтобы отказаться. |
plus.mcp
Этот раздел настраивает MCP-сервер Bencher. Весь раздел является необязательным.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| openai_apps_challenge | a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 | — | Нет | Токен подтверждения домена, который OpenAI выдаёт при отправке приложения, использующего этот MCP-сервер. API-сервер отдаёт его как обычный текст по адресу /.well-known/openai-apps-challenge. Если он не указан, этот маршрут возвращает 404 Not Found. |
plus.oauth
Этот раздел позволяет MCP-клиентам, таким как ChatGPT, claude.ai и Claude Code, входить в Bencher MCP через OAuth.
API-сервер становится для них сервером авторизации OAuth, а пользователи одобряют каждое приложение в Bencher Console по адресу console.url.
Весь раздел является необязательным.
Если он не указан, OAuth выключен: его эндпоинты возвращают 404 Not Found, а Bencher MCP принимает только API-ключи и анонимные запросы.
| Имя | Пример | По умолчанию | Обязательно | Описание |
|---|---|---|---|---|
| issuer | “https://api.bencher.example.com” | — | Да | Публичный origin этого API-сервера, по которому приложения находят его эндпоинты OAuth: https, или http только для loopback-хоста, например localhost. Это должен быть origin без пути, иначе сервер не запустится. ВНИМАНИЕ Если в resources не указан ни один URL, ресурс по умолчанию следует за этим значением, поэтому его изменение отключает приложения, вошедшие через прежний ресурс по умолчанию, пока прежнее значение не будет восстановлено; если в resources указан URL, изменение ничего не отключает, пока прежний origin ещё доходит до этого сервера. |
| resources | ["https://mcp.bencher.example.com/mcp", "https://api.bencher.example.com/mcp"] |
[<issuer>/mcp] |
Нет | URL эндпоинта MCP этого сервера, в которые входят приложения, канонический первым: https, или http только для loopback-хоста. Приложение, которое не указывает ни один, получает первый. Удаление URL отключает приложения, вошедшие через него, пока он снова не будет указан в списке; если не осталось ни одного URL, обслуживается ресурс по умолчанию. |
| clients | [{ … }] | — | Нет | Единственные приложения, которым разрешено входить. Удаление приложения отключает его, пока оно снова не будет указано в списке. Перечисленные приложения помечаются как проверенные на странице согласия. Если не указано, войти может попросить любое приложение, если API-сервер может получить действительный документ метаданных клиента по его идентификатору клиента. |
| clients.id | “https://app.example.com/oauth/client.json” | — | Да | Идентификатор клиента приложения: https URL его документа метаданных клиента. |
| clients.metadata | { … } | — | Нет | Документ метаданных клиента приложения, который используется вместо получения его по id, например на сервере без доступа к интернету. Это должен быть действительный документ метаданных клиента, чей client_id совпадает с id, иначе сервер не запустится. |
| signing_key | "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n" |
— | Нет | Закрытый ключ RSA длиной не менее 2048 бит в формате PEM (PKCS #1 или PKCS #8), которым подписываются ID-токены. Он включает OpenID Connect: области доступа openid, email и profile, ID-токены, а также эндпоинты UserInfo, JWKS и discovery. Если не указан, OpenID Connect выключен. Если ключ недействителен, сервер не запустится. ОН ДОЛЖЕН БЫТЬ ОЧЕНЬ БЕЗОПАСНЫМ! При записи в журнал он будет выглядеть как ************. |
Строка JSON не может содержать перевод строки, поэтому записывайте каждый перевод строки в signing_key как \n.
Например, сгенерируйте ключ и выведите его как строку JSON, не записывая в файл:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 | jq -Rs .Чтобы сменить ключ подписи, замените его. Это не отключает ни одно приложение.
API-сервер обслуживает свои эндпоинты и метаданные OAuth в корне issuer.
Если обратный прокси обслуживает API-сервер под префиксом пути, например https://bencher.example.com/api,
укажите в issuer origin (https://bencher.example.com) и перечислите полный URL эндпоинта MCP в resources (https://bencher.example.com/api/mcp).
Тогда прокси должен направлять запросы к /oauth/, /.well-known/oauth-authorization-server и /.well-known/openid-configuration в корне origin на те же пути API-сервера,
а запросы к пути метаданных каждого ресурса, здесь /.well-known/oauth-protected-resource/api/mcp, на /.well-known/oauth-protected-resource/mcp API-сервера.
Если ресурсов больше одного, прокси также должен передавать заголовок Host без изменений, поскольку по нему API-сервер выбирает, какой ресурс объявить.