Опирается на правила:
R-KFK-SEC-1…R-KFK-SEC-3иR-KFK-SEC-X1…R-KFK-SEC-X2из Kafka Style Guide → раздел 9. Security.
Важно знать
- TLS обязателен в проде (
security.protocol: SSL). SASL/PLAIN over plaintext — запрещено.- ACLs per-сервис — каждый service-account имеет ACL только на свои топики.
- PII — отдельные restricted topics с узким ACL, либо «слабая ссылка»: в широком топике
customerId, PII подгружается через customer-service.PLAINTEXT— только локальная разработка.- Один service-account на кластер — компрометация одного сервиса даёт доступ ко всем topics.
Kafka — это общий бус между сервисами. Без security broker становится open relay: любой компонент видит все сообщения, любой может публиковать в любой topic, PII разлетается по подписчикам. UCP формулирует три слоя защиты: транспортный (TLS), авторизационный (ACLs), data-classification (PII в restricted topics).
TLS обязателен
R-KFK-SEC-1: cross-network — только зашифрованно.
spring:
kafka:
bootstrap-servers: ${KAFKA_BROKERS}
properties:
security.protocol: SSL
ssl.truststore.location: ${KAFKA_TRUSTSTORE_PATH}
ssl.truststore.password: ${KAFKA_TRUSTSTORE_PASSWORD}
ssl.keystore.location: ${KAFKA_KEYSTORE_PATH}
ssl.keystore.password: ${KAFKA_KEYSTORE_PASSWORD}
ssl.endpoint.identification.algorithm: https
security.protocol: SSL — все сообщения зашифрованы TLS 1.2+.
ssl.endpoint.identification.algorithm: https — клиент проверяет, что hostname в Kafka-broker-сертификате совпадает с подключаемым адресом. Без этого — MITM возможен.
mTLS (mutual TLS) — broker верифицирует клиента через client-сертификат. Это даёт автоматическую identity-привязку для ACLs (см. ниже).
Альтернатива — SASL/SCRAM-SHA-512 over TLS (SASL_SSL), если client-сертификаты тяжело раздавать. SASL/PLAIN over TLS — допустимо для test, не для prod (password в plain после TLS-decrypt).
Никогда PLAINTEXT в проде
# КАТАСТРОФА
security.protocol: PLAINTEXT
В сетевом capture все сообщения, headers, токены, payload — в открытом виде. Insider attack возможен на любом hop в сети.
Только локальная разработка (docker-compose с одним broker, своя сеть).
ACLs per-сервис
R-KFK-SEC-2: каждый сервис имеет identity и ACL.
service-account: order-service
ACL:
READ: payment.events, inventory.events
WRITE: order-service.order.created, order-service.order.confirmed, order-service.order.cancelled
service-account: billing-service
ACL:
READ: order-service.order.confirmed
WRITE: billing-service.invoice.created
order-service не может писать в payment.events (это публикует payment-service). billing-service не может писать в order.confirmed (это публикует order-service).
Идентификация client → service-account идёт через mTLS-сертификат (CN=order-service-prod в client cert) или SASL-username.
ACLs управляются через kafka-acls.sh:
kafka-acls.sh --bootstrap-server kafka:9092 \
--add --allow-principal User:order-service-prod \
--operation Read \
--topic payment.events
В реальной инфре ACLs описываются в IaC (Terraform, Pulumi), не руками. Проектирование — DevOps/SRE, использование — application через clientId в KafkaSettings.
PII в restricted topics
R-KFK-SEC-3: два паттерна.
Паттерн 1: отдельный restricted topic
customer-service публикует:
- customer.events ← широкий, без PII (customerId only)
- customer.events.full ← restricted, с PII
ACL для customer.events.full:
READ: notification-service, customer-support-service
Большинство подписчиков читают customer.events (Id-only). Только сервисы, которым реально нужен email/phone, имеют ACL на customer.events.full.
Паттерн 2: «слабая ссылка»
order-service публикует:
- order.confirmed { orderId, customerId, totalAmount }
notification-service:
- получает event
- GET /customers/{customerId}/email (HTTP к customer-service)
- sendEmail(email, ...)
PII никогда не появляется в Kafka. Каждый раз когда notification нужен email — отдельный API-вызов с audit log.
Цена — больше HTTP-нагрузки на customer-service. Преимущество — нет PII в Kafka backup, в DLQ, в logs.
Для большинства случаев слабая ссылка предпочтительнее: проще, меньше уязвимостей.
Что запрещено
PLAINTEXT в проде
R-KFK-SEC-X1: см. секцию выше. Только локальная разработка.
Один service-account на весь кластер
R-KFK-SEC-X2: классическая ошибка.
service-account: app
ACL:
READ: *
WRITE: *
Все сервисы (order-service, payment-service, billing-service, …) используют один и тот же kafka-username: app. ACLs не реализованы — broker даёт всем доступ ко всему.
Что ломается:
- Blast radius — компрометация одного сервиса (XSS, RCE, leaked credentials) даёт attacker'у доступ ко всем топикам.
- Audit — невозможно понять, какой сервис опубликовал spurious event («кто-то от имени
app»). - Mistakes — bug в order-service может писать в
payment.events, downstream payment-side consumer обрабатывает «лишнее» событие.
Per-сервис identity + ACLs — must для production.
Что запрещено — таблица
| Антипаттерн | Правило | Что взамен |
|---|---|---|
PLAINTEXT в проде | R-KFK-SEC-X1 | TLS / SASL_SSL |
| Один service-account на кластер | R-KFK-SEC-X2 | per-сервис identity + ACLs |
| PII в широковещательных topics | R-KFK-SEC-3 | restricted topic или слабая ссылка |
ssl.endpoint.identification.algorithm: пустой | R-KFK-SEC-1 | https для MITM защиты |
| SASL/PLAIN over PLAINTEXT | R-KFK-SEC-1 | минимум SASL_SSL |
Credentials в application.yml | R-KFK-SEC-2 | env / Vault |
| ACLs только на read, не на write | R-KFK-SEC-2 | both, и --operation Create для topic creation |
Куда дальше
- Kafka → раздел 9. Security — нормативные формулировки.
- Event design — PII не в payload broadcast топиков.
- Configuration — credentials через env.
- Auth → AUTH-16 — PII в логах + Kafka общая политика.
- Security style guide — общие принципы.
- Distributed → idempotency — ACLs не заменяют idempotency.