В предыдущей статье мы рассказывали, как пришли к идее Единого Хранилища Секретов — ЕХС. Задача на первый взгляд была понятной: перестать разбрасывать ключи, пароли и другие чувствительные данные по серверам и рабочим станциям, собрать их в одном месте и централизованно управлять доступом и жизненным циклом.

Но довольно быстро выяснилось, что безопасно хранить секрет — только половина задачи.

Администратору всё равно нужен SSH‑ключ. Пользователю — закрытый ключ сертификата. Скрипту автоматизации — credentials для подключения к системе. А старому корпоративному приложению совершенно всё равно, насколько красивую архитектуру мы построили: оно по‑прежнему ожидает пароль в конфигурационном файле.

Получается интересная ситуация: секрет мы с сервера убрали, но существующие процессы от этого никуда не исчезли.

Значит, следующий вопрос звучит уже не «где хранить секреты?», а «как пользоваться секретами из централизованного хранилища так, чтобы не вернуть их обратно в файлы, скрипты и переменные окружения?»

Именно здесь в архитектуре ЕХС появляется ещё один компонент — Wallet.

Но обо всём по порядку.

Где на самом деле лежит закрытый ключ

Возьмём обычный Linux‑сервер, которому нужен закрытый ключ для подключения по SSH или выполнения другой криптографической операции.

Самый очевидный вариант — сохранить ключ в файле, ограничить права доступа и продолжить работу. Именно так устроено огромное количество существующих систем.

Пока всё работает штатно, проблем может быть не видно. Но если злоумышленник получает доступ к файловой системе, вместе с ней он потенциально получает и ключевой материал.

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

В Windows ситуация несколько отличается. Например, Data Protection API позволяет связать возможность локального хранения данных в зашифрованном виде с пользовательским или машинным контекстом. Поэтому просто скопировать защищённый файл на другой компьютер уже недостаточно.

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

Есть и ещё один, менее очевидный риск — потеря самого устройства.

Если закрытый ключ существует в единственном экземпляре на рабочей станции, то вместе с вышедшим из строя диском можно потерять и возможность расшифровать данные. В отдельных PKI‑сценариях здесь помогает Key Recovery Agent, но только если механизм восстановления был предусмотрен заранее.

Поэтому идея, к которой мы пришли в предыдущей статье, выглядит вполне естественно: убрать секреты из множества локальных хранилищ и перенести их в ЕХС, где можно централизованно управлять доступом, аудитом и жизненным циклом.

Казалось бы, вопрос закрыт, но на практике всё только начинается.

Секреты — хранить нельзя использовать

Допустим, ключи, пароли и другие чувствительные данные уже находятся в ЕХС.

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

А теперь администратору нужно подключиться к серверу по SSH. Что делать?

Самый простой вариант — открыть веб‑интерфейс ЕХС, найти нужный секрет, получить его значение, скопировать и вставить в нужную команду.

Формально задача решена, но довольно быстро секрет начинает жить собственной жизнью.

Сегодня пользователь скопировал его в буфер обмена. Завтра положил во временный файл, потому что так удобнее. Через неделю кто‑то вставил его в конфигурацию. Ещё позже этот же ключ оказался в скрипте или CI/CD.

В результате мы потратили усилия на централизацию, а секрет постепенно снова расползся по инфраструктуре.

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

Так появился локальный кошелек секретов, наш Wallet.

Wallet — локальный кошелёк секретов

Wallet — это полноценное кроссплатформенное приложение для Windows, Linux и macOS, которое работает совместно с ЕХС и предоставляет пользователю локальный доступ к разрешённым ему секретам на конечном устройстве.

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

При этом Wallet — не отдельное хранилище со своей независимой базой секретов.

Пользователь аутентифицируется в Wallet, а он обращается к ЕХС, получает информацию о доступных ему секретах и предоставляет возможность работать с ними через графический интерфейс или CLI.

Таким образом получается разделение ролей:

  • ЕХС — место постоянного хранения секретов и управления ими.

  • Wallet — приложение для контролируемой работы с секретами на конечном устройстве.

На бумаге модель выглядит довольно просто, но как только мы начали применять её к реальным сценариям, почти сразу возник вопрос: а что произойдёт, если ЕХС окажется недоступен?

А если сам ЕХС недоступен?

Представим администратора, который ежедневно использует сертификат или закрытый ключ.

Пока есть соединение с ЕХС, всё хорошо: Wallet обращается к серверу и получает необходимые данные. Но сеть может пропасть. Пользователь может оказаться в изолированном сегменте. Сам ЕХС может стать временно недоступен.

Если Wallet при каждой операции обязан связываться с сервером, то вместе с ЕХС остановятся и зависящие от него процессы.

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

Поэтому в Wallet появился offline‑режим. Он позволяет заранее получить разрешённые секреты из ЕХС и сохранить их локально на ограниченный срок.

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

Разница — в контроле.

Локально кэшированные секреты хранятся в зашифрованном виде, а сам пользователь не решает произвольно, что и как долго можно сохранить. Эти правила задаются централизованно в ЕХС. Администратор может определить, разрешён ли конкретному Wallet offline‑режим, какие секреты можно кэшировать и на какой срок.

Например, инженеру можно разрешить заранее получить ключевые пары на 12 часов перед работами в изолированном сегменте. Для другой группы устройств кэширование можно полностью запретить. А для третьей разрешить offline‑доступ только к определённым секретам.

В итоге offline‑режим становится не просто функцией удобства, а частью политики безопасности.

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

Кто запрашивает секрет — и откуда

Следующий вопрос возник уже вокруг самого доступа.

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

Достаточно ли этого, чтобы открыть Wallet и получить закрытый ключ? Хотелось бы, чтобы нет.

Поэтому Wallet поддерживает двухфакторную аутентификацию, где в качестве второго фактора используется TOTP. Причем второй фактор администратор ЕХС может назначить как на аутентификацию в Wallet, так и на прочтение значения отдельных критичных секретов. Таким образом, украсть учетную запись недостаточно. Нужен второй фактор, который генерируется на мобильном устройстве пользователя.

Но два фактора всё ещё отвечают в основном на вопрос: кто перед нами?

Они ничего не говорят о том, с какого устройства выполняется запрос.

Представим, что пользователь настоящий, пароль корректный, второй фактор тоже. Но Wallet запущен на неизвестной машине или устройстве, которое не соответствует корпоративным требованиям. Стоит ли в таком случае отдавать ему закрытый ключ?

Для этого в Wallet появился ещё один механизм — проверка окружения.

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

В результате решение о доступе начинает выглядеть уже не как обычная проверка логина и пароля:

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

Секрет в истории bash — это уже инцидент

Представим, что есть в компании DevOps‑инженер, который устал делать одну и ту же рутину на каждом сервере и в итоге написал скрипты для автоматизации. Это может быть простой bash‑скрипт или ansible playbook, который по очереди подключается к 100 серверам по SSH и выполняет однотипные операции.

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

Но предложение «теперь перепишите всю автоматизацию под новую систему хранения» тоже вряд ли обрадует инженера.

Поэтому Wallet изначально задумывался не только как графическое приложение для пользователя. У него есть CLI, через который локальные процессы могут получать доступ к разрешённым секретам.

Если инженер уже работает через bash, PowerShell или Ansible, он может продолжать использовать знакомые инструменты.

Был скрипт — остаётся скрипт.

Был Ansible — остаётся Ansible.

Меняется только способ, которым процесс получает чувствительные данные: вместо ключа, который годами лежит рядом со скриптом, секрет запрашивается через Wallet только тогда, когда он действительно нужен.

В итоге ЕХС продолжает оставаться централизованным источником секретов, а Wallet становится локальной точкой взаимодействия между ним и существующей автоматизацией.

А что делать с браузером?

Похожая проблема возникает с веб‑приложениями.

Представим старую систему, которая не знает ничего ни про ЕХС, ни про внешние хранилища секретов и ожидает обычный пароль в HTML‑форме. Интегрировать её напрямую с ЕХС долго или вообще невозможно.

Можно заставить пользователя каждый раз открывать Wallet, копировать его и вставлять в браузер. Но тогда в нашу цепочку действий снова возвращается буфер обмена, а вместе с ним — возможность случайно вставить значение не туда, сохранить его или просто оставить в истории работы.

Поэтому следующий логичный шаг для Wallet — браузерное расширение, которое сможет получать разрешённый секрет через локальное приложение и подставлять его непосредственно в нужную форму.

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

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

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

Где хранится ≠ где используется

В итоге архитектура, к которой мы пришли, состоит уже не из одного хранилища.

ЕХС отвечает за постоянное хранение секретов, политики, доступ и жизненный цикл.

Wallet работает непосредственно на пользовательском устройстве или сервере и становится клиентским приложением ЕХС: через него пользователь и локальные процессы могут безопасно работать с разрешёнными секретами.

А между ними находится набор правил, который определяет: кто запрашивает секрет, с какого устройства, разрешён ли offline‑доступ, как долго может существовать локальная копия.

Именно поэтому после внедрения централизованного хранилища работа с секретами не заканчивается.

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

Можно построить хорошо защищённый ЕХС, но, если пользователи после этого продолжают копировать пароли через буфер обмена в bash, а инженеры один раз выгружают закрытые ключи и складывают их рядом со скриптами, часть эффекта от централизации довольно быстро исчезнет.

Поэтому мы постепенно пришли к другому вопросу.

Не: «как сделать так, чтобы секрет никогда не появлялся на конечном устройстве?»,

а: «как сделать так, чтобы секрет появлялся там только тогда, когда действительно нужен, на контролируемых условиях и без необходимости человеку работать с его значением напрямую?»

На этом не заканчиваем

В этих двух статьях мы показали путь от зарождения централизованного хранения секретов в ЕХС до их контролируемого использования через Wallet.

Но на практике этим всё не заканчивается. Каждое внедрение приносит новые ограничения и нестандартные сценарии: особенности существующей инфраструктуры, требования к отказоустойчивости, автоматизации, локальной работе и интеграции с системами, которые изначально не рассчитывали на централизованное управление секретами.

Именно такими кейсами мы и хотим делиться дальше — не просто рассказывать о новых функциях, а показывать, какие задачи за ними стояли, с какими ограничениями мы столкнулись и к каким решениям пришли.

Спасибо всем, кто прочитал обе статьи и проявил интерес к теме. Будем держать вас в курсе развития ЕХС и Wallet и продолжать делиться практическим опытом внедрения.

Комментарии (0)