Глава 19. Политика как код
«Если политика не в Git — её не существует.»
Zero Trust требует сотен политик: сетевых, identity-based, data access, compliance. Ручное управление ими не масштабируется. Policy as Code (PaC) — подход, при котором политики безопасности описываются в машиночитаемом формате, версионируются в Git и применяются автоматически.
19.1 Зачем: от ручных политик к автоматизации
Типичная организация управляет политиками через:
- Таблицы в Confluence
- Ручные чек-листы при деплое
- Регулярные аудиты (раз в квартал)
Проблемы: политики устаревают, не применяются единообразно, аудит отстаёт от изменений.
Policy as Code решает три задачи:
| Задача | Ручной процесс | Policy as Code |
|---|---|---|
| Определение | Документ в Wiki | Rego, Cedar, YAML |
| Применение | Человек проверяет | CI/CD pipeline, admission controller |
| Аудит | Квартальная проверка | Каждый commit = проверка |
NIST SP 800-207, тенет 4: «Access to resources is determined by dynamic policy.» Dynamic policy подразумевает автоматизацию — ручное одобрение каждого запроса невозможно при тысячах микросервисов.
19.2 Языки политик
OPA / Rego
Open Policy Agent (CNCF Graduated, январь 2021) — универсальный движок политик. Текущая версия: OPA v1.13.1 (январь 2026).
Rego v1 — язык политик OPA с улучшенным синтаксисом:
package terraform.security
import rego.v1
# Запретить S3 бакеты без шифрования
deny contains msg if {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not has_encryption(resource)
msg := sprintf("S3 bucket '%s' must have encryption enabled", [resource.name])
}
has_encryption(resource) if {
resource.change.after.server_side_encryption_configuration
}Где используется OPA:
- Kubernetes admission control (Gatekeeper, см. главу 13)
- Terraform validation (conftest)
- API authorization (Envoy ext_authz)
- Data access control (см. главу 17, Lab)
Источник: openpolicyagent.org/docs/latest/policy-language
Cedar
Cedar — язык авторизации от AWS. Открыт в мае 2023 (Apache 2.0), с октября 2025 — проект CNCF Sandbox. Текущая версия: v4.9.0.
// Разрешить аналитикам читать данные своего отдела
permit (
principal in Role::"Analyst",
action == Action::"Read",
resource
)
when {
principal.department == resource.department &&
context.device_compliant == true
};Ключевые отличия Cedar от Rego:
| Характеристика | OPA / Rego | Cedar |
|---|---|---|
| Модель | General-purpose policy | Authorization-focused |
| Синтаксис | Datalog-like | permit/forbid statements |
| Верификация | Нет | Формальная верификация (Cedar Analysis) |
| Производительность | Миллисекунды | Микросекунды (Rust) |
| Экосистема | CNCF Graduated, широкая | CNCF Sandbox, растущая |
Где используется Cedar:
- AWS Verified Access (см. главу 11)
- AWS Verified Permissions
- Cloudflare, MongoDB, StrongDM
Источник: docs.cedarpolicy.com, github.com/cedar-policy/cedar
Sentinel (HashiCorp)
Sentinel — проприетарный язык политик для Terraform Cloud/Enterprise. Не open source.
Три уровня применения:
| Уровень | Поведение при отказе | Применение |
|---|---|---|
| Advisory | Предупреждение, run продолжается | Информационные проверки |
| Soft-mandatory | Блокировка (с возможностью override) | Важные политики |
| Hard-mandatory | Блокировка без override | Критические требования |
# sentinel: S3 bucket должен иметь versioning
import "tfplan/v2" as tfplan
main = rule {
all tfplan.resource_changes as _, rc {
rc.type is "aws_s3_bucket" implies
rc.change.after.versioning[0].enabled is true
}
}Для организаций, использующих Terraform OSS (не Cloud), conftest + OPA — открытая альтернатива Sentinel.
19.3 Infrastructure as Code для Zero Trust
Terraform (v1.14.4, январь 2026) — стандарт для провизионирования ZT-инфраструктуры.
Паттерн: модульная ZT-инфраструктура
# modules/zt-vpc/main.tf — Zero Trust VPC
resource "aws_vpc" "main" {
cidr_block = var.cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "${var.environment}-zt-vpc"
ManagedBy = "terraform"
ZTComponent = "network"
}
}
# Ни одна подсеть не должна быть public по умолчанию
resource "aws_default_security_group" "deny_all" {
vpc_id = aws_vpc.main.id
# Пустые ingress/egress = deny all по умолчанию
}
# Flow Logs для наблюдаемости (глава 18)
resource "aws_flow_log" "vpc" {
vpc_id = aws_vpc.main.id
traffic_type = "ALL"
log_destination = var.security_lake_s3_arn
log_destination_type = "s3"
max_aggregation_interval = 60
}Ключевые провайдеры:
| Облако | Провайдер | Версия |
|---|---|---|
| AWS | hashicorp/aws | v6.31.0 |
| GCP | hashicorp/google | v7.18.0 |
| Azure | hashicorp/azurerm | v4.x |
19.4 GitOps для security policies
GitOps — паттерн, при котором Git-репозиторий является единственным источником истины для состояния кластера.
ArgoCD
ArgoCD (CNCF Graduated) — GitOps controller с UI. Текущая версия: v3.3.0 (февраль 2026).
Важно: ArgoCD v2.x достиг end-of-life в ноябре 2025 (v2.14 — последний релиз v2.x). Миграция на v3.x обязательна.
Применение security policies через ArgoCD:
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: security-policies
namespace: argocd
spec:
project: security
source:
repoURL: https://github.com/org/security-policies.git
targetRevision: main
path: policies/production
destination:
server: https://kubernetes.default.svc
namespace: kyverno
syncPolicy:
automated:
prune: true
selfHeal: trueСтруктура Git-репозитория:
security-policies/
├── policies/
│ ├── production/
│ │ ├── kyverno/ # Admission policies (глава 13)
│ │ ├── cilium/ # Network policies (глава 10)
│ │ └── istio/ # AuthorizationPolicy (глава 12)
│ └── staging/
├── compliance/
│ └── checkov/ # IaC validation rules
└── tests/
└── policy-tests/ # OPA/Rego unit testsFlux CD
Flux (CNCF Graduated) — GitOps toolkit. Текущая версия: v2.7.5.
# flux: Kustomization для security policies
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: security-policies
namespace: flux-system
spec:
interval: 5m
path: ./policies/production
prune: true
sourceRef:
kind: GitRepository
name: security-policies
healthChecks:
- apiVersion: kyverno.io/v2
kind: ClusterPolicy
name: require-labelsArgoCD занимает ~50% рынка GitOps, Flux ~11%. Оба CNCF Graduated, выбор зависит от предпочтений команды.
19.5 Compliance as Code
Автоматическая проверка IaC на соответствие стандартам безопасности.
Инструменты
| Инструмент | Версия | Что проверяет | Лицензия |
|---|---|---|---|
| Checkov | 3.2.500 | Terraform, K8s, CloudFormation, Dockerfile | Apache 2.0 |
| Trivy | v0.69.1 | Контейнеры, IaC, SBOM, секреты | Apache 2.0 |
| KICS | v2.1.15 | Terraform, K8s, Docker, Ansible | Apache 2.0 |
Консолидация: tfsec (Aqua Security) интегрирован в Trivy. Для новых проектов используйте Trivy.
Checkov в CI/CD
# GitHub Actions: проверка Terraform на безопасность
name: Security Scan
on: [pull_request]
jobs:
checkov:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Checkov
uses: bridgecrewio/checkov-action@v12
with:
directory: terraform/
framework: terraform
output_format: sarif
# Пропуск конкретных проверок (с обоснованием)
skip_check: CKV_AWS_144 # Cross-region replication not needed for labTrivy для IaC
# Сканирование Terraform-конфигурации
trivy config --severity HIGH,CRITICAL ./terraform/
# Сканирование Kubernetes-манифестов
trivy config --severity HIGH,CRITICAL ./k8s/
# Генерация SBOM + проверка уязвимостей
trivy image --format spdx-json --output sbom.json myapp:latestИсточник: trivy.dev/latest/docs
19.6 Лаборатория: Terraform + OPA для валидации ZT-инфраструктуры
Цель
Настроить валидацию Terraform-планов с помощью conftest (OPA) для обеспечения Zero Trust требований.
Предварительные требования
- Terraform CLI (v1.x)
- conftest (
brew install conftest) - OPA CLI (
brew install opa)
Шаг 1: Terraform-конфигурация
mkdir -p zt-policy-lab/terraform zt-policy-lab/policyФайл terraform/main.tf:
terraform {
required_version = ">= 1.0"
}
# Пример: S3 бакет (для проверки политикой)
resource "aws_s3_bucket" "data" {
bucket = "zt-lab-data-bucket"
}
resource "aws_s3_bucket_versioning" "data" {
bucket = aws_s3_bucket.data.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "data" {
bucket = aws_s3_bucket.data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
bucket_key_enabled = true
}
}
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# Пример нарушения: Security Group с 0.0.0.0/0
resource "aws_security_group" "bad_example" {
name = "overly-permissive"
description = "This should be flagged by policy"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Нарушение: SSH открыт всему миру
}
}Шаг 2: Политики OPA
Файл policy/zt_security.rego:
package main
import rego.v1
# ZT-1: Запретить Security Groups с 0.0.0.0/0 на SSH
deny contains msg if {
resource := input.resource_changes[_]
resource.type == "aws_security_group"
ingress := resource.change.after.ingress[_]
ingress.cidr_blocks[_] == "0.0.0.0/0"
ingress.from_port <= 22
ingress.to_port >= 22
msg := sprintf(
"ZT-1: Security group '%s' allows SSH from 0.0.0.0/0. Use ZTNA instead.",
[resource.name]
)
}
# ZT-2: S3 бакеты должны иметь шифрование
deny contains msg if {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not has_encryption_config(resource.name)
msg := sprintf(
"ZT-2: S3 bucket '%s' must have server-side encryption.",
[resource.name]
)
}
has_encryption_config(bucket_name) if {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket_server_side_encryption_configuration"
resource.change.after.bucket == bucket_name
}
# ZT-3: S3 бакеты должны блокировать публичный доступ
deny contains msg if {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not has_public_access_block(resource.name)
msg := sprintf(
"ZT-3: S3 bucket '%s' must have public access block.",
[resource.name]
)
}
has_public_access_block(bucket_name) if {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket_public_access_block"
resource.change.after.bucket == bucket_name
resource.change.after.block_public_acls == true
resource.change.after.block_public_policy == true
}Шаг 3: Генерация плана и проверка
cd terraform
# Генерация плана в JSON
terraform init
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
# Проверка плана политикой OPA
conftest test tfplan.json --policy ../policy/
# Ожидаемый результат:
# FAIL - tfplan.json - main - ZT-1: Security group 'bad_example' allows SSH
# from 0.0.0.0/0. Use ZTNA instead.
#
# 2 tests, 1 passed, 0 warnings, 1 failureШаг 4: Интеграция в CI/CD
# .github/workflows/zt-policy-check.yaml
name: ZT Policy Check
on: [pull_request]
jobs:
policy-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init & Plan
run: |
cd terraform
terraform init
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
- name: Install conftest
run: |
LATEST=$(curl -s https://api.github.com/repos/open-policy-agent/conftest/releases/latest | jq -r .tag_name)
curl -sL "https://github.com/open-policy-agent/conftest/releases/download/${LATEST}/conftest_${LATEST#v}_Linux_x86_64.tar.gz" | tar xz
sudo mv conftest /usr/local/bin/
- name: Run ZT Policy Check
run: conftest test terraform/tfplan.json --policy policy/Очистка
cd terraform && rm -f tfplan tfplan.json19.7 Чек-лист
- [ ] Политики безопасности описаны как код (Rego, Cedar, YAML)
- [ ] Политики хранятся в Git с code review процессом
- [ ] CI/CD pipeline включает валидацию политик (conftest, Checkov, Trivy)
- [ ] GitOps controller (ArgoCD / Flux) применяет политики к кластерам
- [ ] Terraform-конфигурации проверяются на ZT-соответствие перед apply
- [ ] Compliance checks автоматизированы (CIS benchmarks, PCI DSS)
- [ ] Sentinel или OPA enforcement настроен для critical policies (hard-mandatory)
- [ ] Policy tests написаны и выполняются при каждом изменении
19.8 Итоги
Policy as Code — это операционная основа Zero Trust:
- Git = единый источник истины — все политики версионируются, ревьюятся и аудитируются через Git
- OPA + Rego — универсальный движок для Kubernetes, Terraform, API, data access (CNCF Graduated)
- Cedar — специализированный язык авторизации с формальной верификацией (CNCF Sandbox, растёт быстро)
- GitOps — ArgoCD/Flux обеспечивают автоматическое применение политик к кластерам
- Compliance as Code — Checkov, Trivy, KICS проверяют IaC до деплоя, ловя нарушения на этапе PR
Ключевой принцип: политика, которая не проверяется автоматически — не политика, а пожелание.
В следующей главе мы рассмотрим реагирование на инциденты в контексте Zero Trust: как принцип «предполагай взлом» меняет IR-процессы.