Конфигурация на Rye по принципу белого списка
- title
- Конфигурация на Rye по принципу белого списка
- type
- summary
- summary
- Доводы Refaktor в пользу встраивания Rye в Go-приложения как языка конфигурации без зашитых ключевых слов и с белым списком возможностей
- parent
- rye-lang
- tags
- config-languages, go, embedded-scripting, capability-security
- sources
- ryelang-whitelist-config
- created
- 2026-05-11
- updated
- 2026-05-11
- lang
- ru
- translation_of
- ryelang-whitelist-config
- source_updated
- 2026-05-11
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Разбор в блоге refaktor/rye, где проектирование языков конфигурации представлено как выбор между двумя тупиками: начать со слишком простого формата и потом на живую нитку прикручивать самодельный язык (путь YAML/HCL) либо взять полноценный язык и пытаться заблокировать в нём лишнее (путь Lua/Python). rye-lang предлагается как третий вариант: стартовать вообще без каких-либо языковых конструкций и регистрировать ровно те возможности, которые вы хотите дать автору конфигурации.
В статье упоминается десятое правило Гринспена и приводятся привычные примеры: шаблонизация в два языка у Helm, эмуляция отсутствующего if через блоки dynamic в Terraform, разросшиеся конструкции управления потоком в Nginx. Затем разбирается альтернатива: встроить Lua, отключить os, io, require. Блог комментирует это так: "чёрные списки защищают от известных опасностей, но всегда остаются неизвестные". Общую концепцию см. в whitelist-capability-config.
В чём отличие Rye
В Rye нет зарезервированного синтаксиса для управления потоком исполнения. Такие слова, как if, fn, loop, +, *, представляют собой обычные функции, зарегистрированные на уровне библиотеки. Базовый интерпретатор умеет лишь:
- Загружать синтаксис в блоки значений
- Привязывать значения к словам через
set-word:иmod-word::
Это и есть нулевой уровень возможностей. Всё остальное нужно явно регистрировать из Go. В сравнении со Starlark, который более зрелый, но безусловно предоставляет if/for/def и подключает модули по принципу "всё или ничего", Rye позволяет зарегистрировать _+ без _* и выдать if без loop.
Практический пример
Веб-сервер на Go, раздающий markdown-файлы и настроенный через Rye. В статье показано шесть шагов с постепенным добавлением возможностей и подсчётом необходимых строк на Go:
| Шаг | Строки Go | Добавленная возможность |
|---|---|---|
| 1 | ~80 | Статические значения, данные в стиле INI |
| 2 | +2 | Арифметика (_*, _+) |
| 3 | +6 | Встроенная функция get-env + any для значений по умолчанию |
| 4 | +14 | Встроенная функция route, if, _= |
| 5 | +6 | fn, replace, capitalize, str - пользовательские функции, вызываемые из Go на каждый запрос |
| 6 | +2 | probe и enter-console (живой REPL внутри контекста работающей конфигурации) |
Каждая возможность подключается одним вызовом RegisterBuiltinsFilter или RegisterBuiltin. К пятому шагу в конфигурации уже можно писать так:
page-title: fn { slug } {
slug .replace "-" " " |capitalize
}
...а рантайм Go вызывает page-title при каждом запросе через ps.Ctx.GetFunction + evaldo.CallFunctionArgsN. Конфигурация превратилась в расширение самого приложения.
Шестой шаг особенно необычен. enter-console переводит работающий процесс в Rye REPL с уже загруженным контекстом текущей конфигурации. В интерактивном режиме можно выполнить lc, чтобы посмотреть привязки, вызвать probe port для инспекции значения или переопределить его через port:: "8080". По нажатию Ctrl-c выполнение продолжается уже с изменённым контекстом. Задумка в том, чтобы отлаживать конфигурацию удобнее, чем через вывод отладочной печати, не теряя при этом надёжности в продакшене, поскольку REPL подключается строго выборочно при регистрации.
Ограничения исполнения
Помимо набора доступных слов, объём работы интерпретатора ограничивается двумя лимитами:
ps.MaxCallDepth = 50
ps.MaxOps = 10_000
Значение по умолчанию 0 означает отсутствие ограничений. Установка этих параметров перед вызовом EvalBlock гарантирует, что бесконечная рекурсия или зацикливание вернут ошибку, а не подвесят процесс.
На что статья не претендует
В заключении прямо подчёркивается: речь идёт об управлении возможностями, а не о песочнице безопасности. Rye исполняется прямо в процессе хоста. Если зарегистрировать небезопасную встроенную функцию, конфигурация тут же получит к ней доступ. Автор не предлагает Rye как замену Lua для работы с недоверенным вводом - это способ уберечь дружественную конфигурацию от превращения в HCL со странностями.
Связанные страницы
- whitelist-capability-config - общий паттерн: встраиваемый скриптинг с запретом по умолчанию
- rye-lang - описание языка (гомоиконичный, встраиваемый в Go, без зарезервированных конструкций)
- ryelang-blog - трекер публикаций блога
- no-silver-bullet - разрастание языков конфигурации как случайная сложность
- sandboxing-ai-agents - разграничение уровней возможностей как сквозная тема в публикациях 2026 года