
Небольшой, аудируемый, завершающийся, детерминированный микро-движок политик
Небольшой, аудитируемый, завершающийся, детерминированный микродвижок политик.
Я создал Gate0, потому что устал отладки политик на основе RegEx в production. Мне хотелось чего-то скучного, ограниченного и не ломающегося. Если вам нужен гибкий универсальный движок политик, используйте OPA. Если вам нужен движок политик, который на безопасных критических путях показывал бы время оценки менее 50 микросекунд и нулевое выделение памяти — вам нужен Gate0.
Gate0 спроектирован для сред с высокими требованиями к безопасности, где оценка политик должна быть детерминированной и ограниченной по ресурсам. Смотрите Политику безопасности для сообщения об уязвимостях и Модель безопасности для полной модели угроз и механических гарантий.
Gate0 использует линейную стратегию оценки Deny-Overrides (приоритет запрета). Каждое правило состоит из Target (быстрое сопоставление) и опционального Condition (глубокая логика).
+----------+ +-------------+ +--------+
| Ephemera | ----> | GateBridge | ----> | Gate0 |
| (Legacy) | | (Normalize) | | (Core) |
+----------+ +-------------+ +--------+
| ^
| |
+----(Shadow Log)----+
Корректность и безопасность Gate0 механически проверяются через модульные тесты, покрывающие основную логику и пограничные случаи, тестирование на основе свойств через proptest с сотнями сгенерированных сценариев, а также верификация MIRI для работы без паник и UB. Худшие по времени сценарии тестируются на обеспечение завершаемости в ограниченных рамках.
cargo test
cargo +nightly miri test --lib
Оценщик Gate0 использует буферы фиксированного размера, размещаемые на стеке, чтобы гарантировать нулевое выделение памяти в куче во время оценки. Реализация по умолчанию использует MaybeUninit, чтобы избежать инициализации неиспользуемых слотов, что даёт стоимость инициализации O(используемые) вместо O(ёмкость).
Небезопасный код ограничен одним модулем (fixed_stack.rs) с простыми инвариантами: элементы 0..len инициализированы, элементы len..N — нет. Все небезопасные пути проверены с помощью MIRI.
Для пользователей, предпочитающих нулевой небезопасный код, Gate0 предоставляет SafeFixedStack за флагом safe-stack. Этот вариант использует [T; N] с T: Default + Copy и инициализирует все слоты заранее. Компромисс — инициализация O(ёмкость) при каждом вызове оценки.
cargo build --features safe-stack
Обе реализации предоставляют идентичную семантику и те же гарантии нулевого выделения памяти во время оценки. Выбор между производительностью (O(используемые)) и абсолютной безопасностью (O(ёмкость)). Для небольших стеков с дешёвыми типами Default, такими как bool, разница незначительна.
Gate0 спроектирован для работы как точка принятия решений (PDP) в составе более крупного приложения. Для поддержания детерминизма и строгих границ Gate0 не занимается вводом-выводом, сетевым взаимодействием или жизненным циклом объектов.
Рекомендуемый шаблон интеграции разделяет обязанности на три уровня. Хост-приложение (API-шлюз, SSH-сервер и т.д.) управляет состоянием, идентификацией и побочными эффектами. Адаптерный уровень нормализует это сложное состояние в примитивы, понятные Gate0 (строки, bool, целые числа). Gate0 чисто оценивает сплющенный контекст и возвращает решение.
Host Application (User Request)
│
▼
[Adapter Layer] → Предвычисляет контекст (время, IP-диапазоны, статус MFA)
│ Преобразует «сложное» в «примитивное»
▼
[Gate0 Engine] → Чистая оценка (0 выделений, ограниченный стек)
│
▼
Decision::Allow / Deny
Это разделение объясняет, почему Gate0 не включает сложные сопоставители, такие как проверка IP-диапазонов или регулярные выражения. Адаптерный уровень обрабатывает доменную логику и предоставляет Gate0 предвычисленные булевы или строковые атрибуты. Gate0 остаётся маленьким, аудитируемым и детерминированным.
use gate0::{Policy, Rule, Target, Request, ReasonCode};
let policy = Policy::builder()
.rule(Rule::allow(Target::any(), ReasonCode(1)))
.build()?;
let decision = policy.evaluate(&Request::new("alice", "read", "doc"))?;
assert!(decision.is_allow());
Директория examples/ содержит иллюстративные сценарии, демонстрирующие типичные шаблоны использования Gate0:
SaaS API: Стандартная логика RBAC/мультиарендности. Zero Trust Network: Управление доступом на основе атрибутов (ABAC) с проверкой MFA и местоположения. Complex Overrides: Демонстрация разрешения конфликтов по правилу Deny-Overrides.
Запустите их с помощью:
cargo run --example saas_api
cargo run --example zero_trust_network
cargo run --example complex_overrides
Gate0 намеренно ограничен для сохранения предсказуемости и производительности.
Нет сложных сопоставителей: Такая логика, как полная битовая маска CIDR или расширенные RegEx, остаётся на ответственности адаптерного уровня. Gate0 оценивает предобработанные примитивы.
Нет встроенной многопоточности: Текущая реализация FFI для Python не является потокобезопасной. Пользователям с высокой степенью параллелизма следует использовать многопроцессность или дождаться стабилизации FFI в фазе 4, которая решит проблемы с глобальными блокировками.
Нет перекрывающихся решений: Внутри одного класса эффекта (Allow/Deny) возвращается только первое совпавшее правило. Разрешение конфликтов строго зависит от порядка.
Следующие проекты расширяют движок Gate0 для специализированных случаев использования.
gate0_dsl: Собственный предметно-ориентированный язык для Gate0, разработанный hardliner66. Он использует макросы Rust для обеспечения чистого и читаемого синтаксиса определения политик непосредственно в коде. Реализация и документация доступны по адресу hardliner66/gate0_dsl.
MIT