Справочник: файл политики
Политика — один файл JSON. Путь к нему задаётся при установке параметром POLICYPATH
и хранится в реестре; его читают и служба, и окно администратора. Имена полей —
в нижнем регистре через подчёркивание (enforcement_mode, strict_mode).
Разбор снисходителен к трём вещам: незнакомые поля пропускаются (по ним новая версия
программы не ломает старую политику), комментарии // разрешены, запятая после
последнего элемента списка ошибкой не считается.
Целый пример
{
"version": 7,
"updated_utc": "2026-08-18T09:14:00Z",
"updated_by": "DOMAIN\\petrov",
"enforcement_mode": "audit",
"strict_mode": false,
"notify_user": true,
"defaults": { "flash": "block", "external_hdd": "block", "other": "allow" },
"rules": [
{ "id": "R-001", "match": { "serial": "001cc0ec34d5" }, "action": "allow",
"note": "Флешка бухгалтерии №1", "owner": "Иванова А.П." },
{ "id": "R-014", "match": { "vid": "0951", "pid": "1666" }, "action": "readonly" }
],
"log": { "retention_days": 90, "share_path": "\\\\server\\laportausb$\\logs" }
}
Поля верхнего уровня
| Поле | Обязательно | Значение |
|---|---|---|
version | да | Целое больше нуля. По нему окно администратора замечает, что файл правил кто-то ещё |
updated_utc | нет | Время последней правки |
updated_by | нет | Кто правил |
enforcement_mode | нет | audit либо enforce. Без поля — audit |
strict_mode | нет | Превентивный слой. Без поля — выключен |
notify_user | нет | Уведомления в трее. Без поля — включены |
defaults | да | Действие по классу носителя |
rules | нет | Правила по отдельным устройствам |
log | нет | Срок хранения журнала и путь выгрузки |
Поле strict_mode включает превентивный слой — запрет установки неизвестных
USB-накопителей через ветку ограничений установки устройств, а не только отключение
уже подключённых. Действует лишь вместе с enforcement_mode: enforce: в паре
с audit strict_mode ничего не включает, режим наблюдения ничего не ограничивает.
Устройство слоя, порядок регистрации носителя в белом списке и срок жизни этого
списка — в overview.md.
Незнакомое значение enforcement_mode — ошибка разбора, а не молчаливое возвращение
к audit. Иначе опечатка в слове enforce оставила бы машину в режиме наблюдения,
а администратор считал бы, что запреты включены.
Умолчания по классам устройств
"defaults": { "flash": "block", "external_hdd": "block", "other": "allow" }
| Ключ | Обязателен | Примечание |
|---|---|---|
flash | да | Флешка |
external_hdd | да | Внешний диск |
other | нет | Прочие USB-устройства. Без ключа — allow |
token | запрещён | Валидатор отвечает: «Класс token не настраивается политикой: токены никогда не блокируются» |
unknown | нет такого ключа | Класс не определён — решение по устройству не пересчитывается |
Класс unknown означает, что узел устройства отключён и не запущен: система сообщает
идентификатор, VID/PID и имя, но не сменность носителя, а без неё флешку от внешнего
диска не отличить. Догадка стоила бы неверного решения, поэтому класс остаётся
неопределённым.
Правила
Правило — отбор устройства (match) и действие над ним (action).
| Поле | Обязательно | Значение |
|---|---|---|
id | да | Неповторяющийся в пределах файла |
match | да | Условие отбора, см. ниже |
action | да | allow, readonly либо block |
note | нет | Для человека: что это за носитель |
owner | нет | Для человека: чей он |
added_utc | нет | Когда правило заведено |
Внутри match:
| Поле | Значение |
|---|---|
serial | Серийный номер устройства |
vid | Идентификатор изготовителя, ровно четыре шестнадцатеричные цифры |
pid | Идентификатор изделия, ровно четыре шестнадцатеричные цифры |
interfaces | Состав интерфейсов, записи вида класс:подкласс:протокол |
interfaces_match | equals либо none_of. Без поля — equals |
Задаётся либо serial, либо пара vid+pid целиком. Одно с другим
одновременно — ошибка; половина пары — тоже ошибка. serial, vid и pid приводятся
к верхнему регистру, так что регистр в файле значения не имеет.
Записи в interfaces — шестнадцатеричные пары, звёздочка допускается вместо целой доли:
03:*:* — любая клавиатура или мышь, 08:06:50 — обычный накопитель. equals требует
совпадения состава, none_of — отсутствия перечисленного. Устройство, состав
интерфейсов которого прочитать не удалось, не удовлетворяет никакому условию: разрешать
по неподтверждённому значит открывать ровно ту дверь, ради закрытия которой условие
и заводилось.
Пример правила с условием — разрешить этот накопитель, пока он остаётся только накопителем:
{
"version": 12,
"enforcement_mode": "enforce",
"defaults": { "flash": "block", "external_hdd": "block" },
"rules": [
{ "id": "R-021",
"match": { "serial": "001CC0EC34D5", "interfaces": ["03:*:*"], "interfaces_match": "none_of" },
"action": "allow", "note": "Отзывается, если внутри окажется клавиатура" }
]
}
Порядок применения правил
Решение принимается первым подошедшим пунктом сверху вниз. В журнал попадает причина — она в скобках.
- Токен (
token_never_enforced). Всегдаallow. Ни одно правило к токену не применяется: заблокированный токен — это потерянный вход в систему. - Точное правило по
serial(exact_rule_serial). Только если серийный номер заслуживает доверия: часть дешёвых носителей сообщает один номер на всю партию. - Групповое правило по
vid+pid(group_rule_vid_pid). Правило с заданнымserialна этом шаге не рассматривается. - Умолчание по классу (
default_flash,default_external_hdd,default_other).
Из нескольких правил, подошедших на одном шаге, выигрывает block; если запрета среди
них нет — первое по порядку в файле.
Условие interfaces уточняет правило, а не образует своё. Не совпало — правило
не применяется вовсе, и устройство уходит дальше по списку, к умолчанию. Так не возникает
вопроса о старшинстве между правилом по серийнику и правилом по составу.
Если класса нет в умолчаниях, решение — block: молча разрешить неизвестный класс
опаснее, чем запретить. При действительной политике эта ветка недостижима, потому что
flash и external_hdd обязательны.
Журнал
"log": { "retention_days": 90, "share_path": "\\\\server\\laportausb$\\logs" }
retention_days — файлы журнала старше этого срока удаляются. Значение должно быть
больше нуля. Без раздела log действует 90 дней.
share_path — каталог, куда выгружается копия журнала. Пусто или поля нет — выгрузка
не выполняется.
Ошибки разбора
Политика, которая не разобралась, не применяется. Служба продолжает работать по последней удачно прочитанной политике из кэша, а если и кэша нет — уходит в запасной режим и разрешает всё. Молчаливого частичного применения не бывает: либо файл разобран целиком, либо не принят целиком.
Отказы выглядят так:
Поле version обязательно и должно быть больше нуля
Класс token не настраивается политикой: токены никогда не блокируются
Правило R-007: serial и vid/pid нельзя задавать одновременно
Неизвестное действие 'deny'. Допустимы: allow, readonly, block
Проверить файл до раскатки можно в окне администратора, на вкладке политики: оно разбирает файл тем же кодом, что и служба, и показывает те же строки.