Где хранить API-ключи, токены и сервисные учётные данные

 

 

 

 

БЕЗОПАСНОСТЬ // SECRET_MANAGEMENT_FALLACY

Почему технические ключи нельзя держать в коде и документации. Как устроить хранение секретов, доступы и управление сервисными учётными данными так, чтобы утечка не превращалась в аварию.

Условный кейс: как обычно начинается проблема

Компания внедряет обмен между CRM и внешней платформой.

Для запуска нужен API-ключ. Его кладут в конфиг, чтобы «быстрее проверить». Потом конфиг попадает в репозиторий. Репозиторий — в архив для подрядчика. Подрядчик через полгода больше не работает с проектом, но архив остаётся.

Через 11 месяцев ключ всплывает в неожиданном месте.

СОСТОЯНИЕ_СИСТЕМЫ // COMPROMISED_KEY_STATE
Жизненный цикл
ключ всё ещё действует
Уровень доступа
через него можно читать и изменять данные
Прослеживаемость
никто точно не помнит, где ещё он был скопирован
Аудит и логи
в логах нет понятной картины, кто и когда им пользовался

Дальше начинается не «безопасность», а пожар: отзыв ключа, срочный выпуск нового, проверка всех интеграций, разбор, не было ли обращений извне, объяснения бизнесу.

Почти всегда цепочка одна и та же:

секрет положили туда, где удобно → удобное место оказалось неуправляемым → секрет пережил контекст, в котором его создавали.

 

 

Что является секретом

Секрет — это любое значение, которое позволяет системе или человеку выполнить действие, недоступное без него.

КЛАССИФИКАЦИЯ_ДАННЫХ // SECRET_IDENTIFICATION
API-ключ [Да]
Прямой доступ к API
Refresh-токен [Да]
Позволяет получать новые access-токены
Access-токен [Да]
Пока жив — полноценный доступ
Пароль сервисной учётки [Да]
Вход в систему от имени сервиса
Приватный ключ [Да]
Криптографический доступ
Строка подключения с паролем [Да]
Доступ к данным
Публичный ключ [Нет]
Предназначен для распространения
URL API без ключа [Нет]
Сам по себе доступ не даёт
Если значение можно украсть и сразу использовать — это секрет.
Если без него действие выполнить нельзя — тем более.

 

 

УЯЗВИМОСТИ_ХРАНЕНИЯ // UNSECURE_PLACES_ANALYSIS

Почему код и документация — плохие места хранения

[ АНАЛИЗ // КОД ]

Код

Исходники копируются. Их клонируют, архивируют, отдают подрядчикам, переносят между машинами.

Даже приватный репозиторий — это не сейф, а файл с историей.

Удалённый из текущей версии ключ почти всегда остаётся в Git-истории.
[ АНАЛИЗ // ДОКУМЕНТАЦИЯ И ЧАТЫ ]

Документация и чаты

README, Confluence, Notion, Telegram, почта, таблицы доступов.

Там секрет читают люди, которым он часто не нужен.

Его невозможно гарантированно удалить из всех копий, бэкапов и пересылок.

И почти никогда не включают в процедуру ротации.

ВИЗУАЛИЗАЦИЯ // ЦЕПОЧКА НЕУПРАВЛЯЕМОГО РАСПРОСТРАНЕНИЯ
Разработчик
[Вставил в код]
➔
Git-репозиторий
[Запись в истории]
➔
Архив / Подрядчик
[Внешняя копия]
➔
Утечка данных
[Аварийный контекст]
КРИТИЧЕСКИЙ_СБОЙ // ROOT_SECURITY_DEFECT

Главный дефект обоих вариантов

Секрет начинает жить своей жизнью.

> Он отделяется от системы контроля: кто выдал, кому, зачем, до какого срока, как отозвать.

 

 

АРХИТЕКТУРА_БЕЗОПАСНОСТИ // SECURE_STORAGE_MODELS

Где секреты должны храниться

Рабочая модель строится вокруг одного принципа:

секрет имеет единственный источник истины, а всё остальное — только временная выдача.

КРИТЕРИИ_ХРАНЕНИЯ // STORAGE_LAYERS
1. Secret Manager / Vault

Отдельный контур, который:

  • › хранит значения в зашифрованном виде
  • › выдаёт доступ по политикам
  • › пишет аудит
  • › умеет ротировать и отзывать
  • › интегрируется с CI/CD и средой исполнения

Это не «удобный сейф». Это система управления секретами.

Просто положить пароль в Kubernetes Secret без шифрования at rest и без жёстких политик — ещё не решение. Это лишь объект конфигурации.

2. Переменные окружения — транспорт, а не хранилище

Допустимо, когда секрет в момент запуска подставляется в runtime.

Недопустимо, когда .env с боевыми значениями лежит в репозитории, на общем диске или в домашней папке «чтобы не забыть».

3. Динамические секреты

Для баз данных и части внутренних сервисов лучше не использовать пароли, которые живут месяцами.

Схема:
сервис запрашивает доступ
получает временные учётные данные
работает
по истечении TTL данные автоматически становятся недействительными

Утечка в такой модели ограничена по времени.

Украденный пароль через 20–60 минут уже бесполезен.

ВИЗУАЛИЗАЦИЯ 1 // СРАВНЕНИЕ МОДЕЛЕЙ ЖИЗНЕННОГО ЦИКЛА СЕКРЕТОВ
[ СТАТИЧЕСКИЙ СЕКРЕТ ][ КЛЮЧ ]живёт месяцы / годы без ограниченийутечка = полный ущерб[ ДИНАМИЧЕСКИЙ СЕКРЕТ ]1. ЗАПРОС2. ВРЕМЕННЫЙ TTL3. РАБОТА4. АВТООТЗЫВ✔ Результат модели: утечка = короткое контролируемое окно (20–60 минут)

 

 

СЛУЖЕБНЫЙ_ДОСТУП // SERVICE_ACCOUNTS_SECURITY

Сервисные учётные записи

Сервисная учётка — это не «пользователь, под которым удобно всё запускать».

РЕВИЗИЯ_ДОСТУПОВ // SERVICE_ACCOUNTS_AUDIT
[ РИСКИ // ТИПОВЫЕ ОШИБКИ ]
  • › одна учётка на CRM, базу, файлы и внешние API
  • › права уровня администратора «на всякий случай»
  • › люди входят под сервисной учёткой, потому что так быстрее
[ СТАНДАРТ // ЧТО ДОЛЖНО БЫТЬ ]
  • › отдельная учётка под конкретный контур ответственности
  • › минимально необходимые права
  • › запрет интерактивного входа, если платформа это позволяет
  • › понятный владелец
  • › отдельный регламент ротации
ВИЗУАЛИЗАЦИЯ 2 // РАДИУС ПОРАЖЕНИЯ ПРИ УТЕЧКЕ КЛЮЧЕЙ
[ ШИРОКИЕ ПРАВА ]Учётка-АдминДоступ ко всему контуру ➔ Критический ущерб[ МИНИМАЛЬНЫЕ ПРАВА ]Изолир. учёткаОдин контур ответственности ➔ Локальный инцидент

Чем шире права сервисной учётки, тем дороже стоит её компрометация.

 

 

ДОСТАВКА_СЕКРЕТОВ // SECRET_INJECTION_PATTERNS

Как секрет должен попадать в приложение

Три рабочих паттерна.

ПАТТЕРНЫ_ИНЖЕКЦИИ // DELIVERY_METHODS
Inject при деплое
CI/CD или оркестратор забирает секрет из vault и передаёт процессу при запуске.
Приложение не знает, где секрет хранится постоянно.
Приложение само запрашивает секрет
Сервис аутентифицируется в secret manager и получает нужные значения.
Удобно для динамических секретов, но усложняет первичный bootstrap.
Sidecar / агент
Рядом с приложением работает компонент, который достаёт секреты и отдаёт их локально контролируемым способом.
ВИЗУАЛИЗАЦИЯ 2 // МАРШРУТЫ ПОСТАВКИ СЕКРЕТОВ В RUNTIME
[Secret Vault]CI/CD / OrchestratorApplication (Прямой)Sidecar / Agentruntimeruntime
ЗАПРЕТЫ_РАЗМЕЩЕНИЯ // SECURITY_LOGGING_CONSTRAINTS

На диске в открытом виде секрета быть не должно.

В логах — тоже.

 

 

ИНЦИДЕНТ // GIT_SECRET_LEAK

Если секрет уже оказался в Git

Считайте его скомпрометированным. Без исключений.
РЕГЛАМЕНТ_ЛИКВИДАЦИИ // INCIDENT_RESPONSE_PLAN
  • › Отозвать ключ в системе-источнике
  • › Выпустить новый
  • › Обновить все потребители
  • › Проверить историю репозитория, CI-логи, архивы, тикеты
  • › Закрыть путь, которым секрет снова может попасть в код

Удалить строку из текущего файла недостаточно.

> История сохраняет значение.

ПРОФИЛАКТИКА // SECURITY_PREVENTION_CONTROLS

[fn]сканеры секретов в pre-commit и CI

[fn]запрет коммита .env, ключей, credential-файлов

[fn]регулярный аудит репозиториев

 

 

ЖИЗНЕННЫЙ_ЦИКЛ // SECRET_ROTATION_POLICY

Ротация

Секрет, который никто не меняет, со временем становится обязательствами, а не защитой.

УПРАВЛЕНИЕ_РИСКАМИ // ROTATION_TRIGGERS
[ АНАЛИЗ // ПРИЧИНЫ РОТАЦИИ ]

Причины ротации прозаические:

  • › увольнения
  • › смена подрядчиков
  • › «временный» доступ, который забыли
  • › старые интеграции, которые уже не нужны, но ключ жив
[ РЕГЛАМЕНТ // МИНИМУМ ДИСЦИПЛИНЫ ]
  • › у каждого секрета есть владелец
  • › есть срок жизни или дата пересмотра
  • › процедура смены описана и выполняется
  • › после ротации старое значение гарантированно не работает
ВИЗУАЛИЗАЦИЯ 3 // ОКНО ПАРАЛЛЕЛЬНОЙ РАБОТЫ КЛЮЧЕЙ (GRACE PERIOD)
[ СТАРЫЙ КЛЮЧ ]Принимается системойОкно вывода➔ Отключение ❌[ НОВЫЙ КЛЮЧ ]Выпуск ➔ Внедрение во все потребители ➔ Полноценная работа ✔

Для критичных контуров проектируют окно параллельной работы двух ключей: новый уже принимают, старый ещё короткое время действует, затем отключается.

 

 

УЯЗВИМОСТИ // SIDE_CHANNEL_LEAKS

Побочные каналы утечки

Даже правильное хранение не помогает, если секрет всплывает рядом:

АНАЛИЗ_УГРОЗ // COMPROMISE_CHANNELS

[!]логи приложения

[!]тексты ошибок

[!]debug-режим

[!]CI-артефакты

[!]бэкапы конфигураций

[!]дампы и снимки дисков

ФУНДАМЕНТАЛЬНОЕ_ПРАВИЛО // DATA_MASKING_MANDATE

Правило простое:

секрет не должен появляться ни в одном канале, который читают люди или сохраняют системы наблюдаемости.

 

 

РЕГЛАМЕНТ_КОМАНДЫ // TEAM_OPERATIONAL_MODEL

Рабочая модель для команды

ПРАВИЛА_КОМАНДЫ // SECURITY_STANDARDS
Один источник истины
vault / secret manager
Контроль доступа
Люди не держат боевые секреты «на руках» без необходимости
Разделение сред
Среды разделены — dev, test, prod используют разные секреты
Минимум привилегий
Права минимальны — каждая сервисная учётка только под свою задачу
Обязательная ротация
Ротация обязательна — не как идея, а как процесс
Проактивный мониторинг
Обнаружение включено — сканирование кода и артефактов

Реакция на инцидент готова:

отозвать, заменить, проверить следы

ВИЗУАЛИЗАЦИЯ 3 // ЖИЗНЕННЫЙ ЦИКЛ СЕКРЕТА В ОПЕРАЦИОННОЙ МОДЕЛИ
СозданиеХранение в VaultВыдача по политикеИспользование в runtimeАудит → Ротация → Отзыв

 

 

РЕВИЗИЯ_АРГУМЕНТОВ // SECURITY_EXCUSES_BREAKDOWN

Почему отговорки не работают

КРИТЕРИИ_БЕЗОПАСНОСТИ // EXCUSES_VS_REALITY

«Репозиторий приватный»

Приватность не отменяет копирование, историю и расширение списка доступа.

«Команда небольшая, все свои»

Большинство утечек происходят без злого умысла: отладка, архив, смена подрядчика, забытый токен.

«Потом сделаем правильно»

Потом секретов уже десятки, они размазаны по местам, и наведение порядка стоит дороже, чем нормальная схема с самого начала.

«Нам пока рано»

Именно на раннем этапе секреты чаще всего кладут в код «временно». Временное становится постоянным.

ВИЗУАЛИЗАЦИЯ // СТОИМОСТЬ ИСПРАВЛЕНИЯ НА РАЗНЫХ СТАДИЯХ
Старт проектаНормальная схема = Минимальные затраты ✔ОткладываниеРазмазанные секреты = Пожарный аудит ➔ Дорогой рефакторинг ❌

 

 

ИТОГИ // ACCESS_MANAGEMENT_SUMMARY

Короткий вывод

Секрет нельзя считать просто строкой настройки.

Это privileged access, у которого должны быть:

[attr]место хранения

[attr]политика выдачи

[attr]владелец

[attr]срок жизни

[attr]способ отзыва

Если API-ключ можно случайно закоммитить, переслать в чат или найти в старом архиве, система управления доступами ещё не построена.

> Есть только набор значений, которые ждут своего инцидента.

Чеклист на одну минуту

ФИНАЛЬНАЯ_ПРОВЕРКА // COMPLIANCE_CHECKLIST
  • › Секретов нет в Git и документации
  • › Есть единое хранилище
  • › Сервисные учётки разделены и ограничены по правам
  • › Dev/test/prod не делят боевые ключи
  • › Ротация и отзыв реально выполняются
  • › Логи и CI не содержат секретов
  • › Понятно, кто владелец каждого критичного ключа
Если хотя бы два пункта из списка не выполняются, риск уже не теоретический.

 

 

НАВИГАЦИЯ // SUGGESTED_READING
 
[ Модуль // ИНТЕГРАЦИИ ]

API, Webhook или очередь сообщений?

 
[ Модуль // ИНТЕГРАЦИИ ]

Когда API есть, а интеграция всё равно не работает

 
[ Модуль // АВТОМАТИЗАЦИЯ ]

Как соединить производство и корпоративные системы

 
[ EXPERTISE JOURNAL ]

Все инженерные материалы и экспертные статьи

 
[ CORE GLOSSARY ]

Полный алфавитный справочник ИТ-терминов

 

[ DIRECT EMAIL LINE ]
info@log-ai.ru

 

🔒 Данные и доступ к системам заказчика обрабатываются в соответствии с согласованными требованиями к безопасности и конфиденциальности. Условия доступа, хранения и обработки данных определяются архитектурой проекта и договором.

Сайт носит исключительно информационный характер и не является публичной офертой в соответствии со статьёй 437 Гражданского кодекса РФ. Цены, состав и условия предоставления услуг уточняются при проектировании решения и фиксируются в договоре. Условия технического сопровождения и уровень сервиса могут дополнительно определяться отдельным соглашением (SLA).

© 2026 Log-AI Москва
Автоматизация бизнеса и ИИ-решения под ключ
Самозанятый Скопец Антон Викторович ИНН 741709260870
Политика конфиденциальности Пользовательское соглашение
AI Ассистент
×