Принцип наименьших привилегий
| Формулировка | Зальцер и Шрёдер, 1975 |
|---|---|
| Суть | минимум прав, минимум времени, минимум области действия |
| Смежные идеи | разделение обязанностей, защита в глубину, Zero Trust |
| Примеры в Linux | отдельные пользователи сервисов, sudo, capabilities, systemd-песочница |
| Примеры в облаке | IAM-роли, сервисные аккаунты, RBAC в Kubernetes |
Принцип наименьших привилегий (англ. principle of least privilege, PoLP) — правило проектирования систем, по которому каждый субъект — пользователь, программа, процесс, сервисный аккаунт — получает только те права, которые необходимы для выполнения своей задачи, и только на то время, пока они нужны. Принцип не предотвращает взлом сам по себе, но ограничивает его последствия: скомпрометированный компонент может навредить ровно в пределах своих прав.
История
Принцип сформулировали Джером Зальцер и Майкл Шрёдер в статье «The Protection of Information in Computer Systems» (1975) — среди восьми принципов проектирования защищённых систем: «каждая программа и каждый пользователь системы должны работать с наименьшим набором привилегий, необходимым для выполнения работы».[1] Сегодня он закреплён в стандартах, например как мера AC-6 в каталоге NIST SP 800-53,[2] и лежит в основе модели Zero Trust, где ни один запрос не считается доверенным только из-за своего места в сети.[3]
Три измерения
- Что — набор действий: чтение вместо записи, одна таблица вместо всей базы, одна команда вместо полного root.
- Где — область: один бакет, один namespace, один проект, а не «всё».
- Когда — время: временные права «по запросу» (just-in-time) вместо постоянных, короткоживущие токены вместо вечных ключей.
Примеры
Linux
- Сервисы запускаются от отдельных непривилегированных пользователей (
www-data,postgres), а не от root; права на файлы выдаются ровно на нужные каталоги. - Администраторы работают под обычной учёткой и повышают права через
sudoдля конкретных команд. - Capabilities дробят всемогущество root: чтобы слушать порт 80, программе достаточно
CAP_NET_BIND_SERVICE. - systemd позволяет запирать сервис в песочницу:[5]
[Service]
User=app
DynamicUser=yes
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lib/app
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
Команда systemd-analyze security app.service оценивает, насколько сервис изолирован.
Контейнеры и Kubernetes
- Процесс в контейнере — не root (
USER appв Dockerfile), файловая система только для чтения, лишние capabilities сброшены (--cap-drop=ALL), без--privileged. - В Kubernetes — RBAC с
Roleна конкретный namespace вместоClusterRole, отдельный ServiceAccount на каждое приложение, отключённый автоматический монтаж токена там, где API не нужен, Pod Security Standards уровняrestricted.[4]
Базы данных
Учётная запись приложения получает SELECT, INSERT, UPDATE на свои таблицы — без DROP, без прав владельца и суперпользователя. Отдельная роль для миграций, отдельная — только для чтения для аналитики. Это заметно уменьшает ущерб от SQL-инъекции.
Облако и CI
- IAM-политики перечисляют конкретные действия и ресурсы вместо
"Action": "*"; анализаторы доступа подсказывают, какие права реально использовались.[6] - Пайплайны CI/CD получают короткоживущие учётные данные через OIDC вместо долгоживущих ключей; токен в GitHub Actions ограничивают блоком
permissions:.
permissions:
contents: read
id-token: write # только для обмена на облачные креды
ИИ-агенты
Принцип особенно важен для агентов с доступом к инструментам: агенту, который читает почту и пишет сводку, не нужны права на отправку писем и удаление файлов. Так снижается ущерб от prompt injection.
Смежные принципы
- Разделение обязанностей — критичная операция требует участия двух людей или ролей (например, автор кода не может сам вливать его в main без ревью).
- Защита в глубину — несколько независимых слоёв защиты, каждый из которых ограничивает ущерб при отказе другого.
- Запрет по умолчанию — всё, что явно не разрешено, запрещено; так строятся правила файрвола и политики доступа.
Трудности
Минимальные права требуют знать, что именно нужно программе, а это меняется со временем. Отсюда типичный дрейф: права выдают «с запасом», чтобы всё заработало, и никогда не отзывают. Помогают регулярный пересмотр доступов, автоматическое истечение временных прав, журналирование и инструменты, которые сравнивают выданные права с реально использованными.