Задания, отчёты и патчи, лежавшие в C:\Users\Ochenstarik\projects и в домашней папке, перенесены в agents/. Разложено по агентам там, где имя файла позволяло определить автора; остальное — в _salvage-2026-08-18/ и разбирается вручную. Патчи в notes/salvage-2026-08-18/ — незакоммиченная работа из брошенных рабочих копий: она существовала только на диске. Тяжёлое (релизные архивы, инсталляторы, наборы данных) в репозиторий не попало: оно лежит рядом, в Agent_projects/_archive и Agent_projects/_data. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7.4 KiB
Жизненный цикл клиентских сертификатов
Репозиторий и ветка
- Репозиторий: https://github.com/ochenstarik-ui/server-monitor-manager
- Локальный клон:
C:\Users\Ochenstarik\projects\server-monitor-manager - База:
main@b11c277 - Ветка:
hermes/cert-lifecycle
Задание не пересекается по файлам с b3r-fact-reconciliation и выполняется параллельно в отдельном worktree. Затрагиваемые файлы (CertificateAuthority.cs, CertificateLifecycleService.cs, AgentClient.cs) веткой B-3R не изменяются.
Зачем
CertificateAuthority.cs, выдача клиентского сертификата:
var requestedNotAfter = DateTimeOffset.UtcNow.AddYears(1);
Срок — один год, автопродления нет ни у Agent, ни у Operator. Через год после развёртывания весь парк перестаёт проходить mTLS одновременно, и восстановление требует ручной перерегистрации каждого Node через одноразовый enrollment token. Процедуры ротации Control CA в проекте нет вообще.
Отзыв работает через таблицу identity в Control (ResolveIdentityAsync), CRL не используется — это осознанное решение и менять его не нужно.
Работы
1. Срок жизни
- сократить срок клиентского сертификата до 30–90 дней;
- вынести значение в
ControlOptionsс валидацией в общей цепочке.Validate(...)вProgram.cs, по образцуLinkReconciliationSeconds; - значение по умолчанию в
appsettings.jsonи вcontrol.env, который пишет bootstrap; - срок сертификата не может превышать остаточный срок Control CA — существующая логика ограничения сохраняется.
2. Автопродление Agent
- Agent проверяет остаточный срок собственного сертификата при старте и далее периодически;
- при остатке меньше трети срока формирует новый CSR и запрашивает выдачу по действующему mTLS-каналу, без enrollment token;
- новый эндпоинт выдачи требует действующий сертификат того же
node_id, idempotency key и запись в audit; - замена
agent.pfxатомарная: запись во временный файл с правами0600, затем rename; при любой ошибке остаётся действующий сертификат; - отозванный сертификат продлению не подлежит — запрос отклоняется, Node требует повторной регистрации.
3. Продление Operator-сертификата Desktop
- Desktop проверяет остаточный срок при подключении к Control;
- продление по тому же принципу, с явным уведомлением пользователя в интерфейсе;
- защищённое хранение DPAPI сохраняется, приватный ключ не покидает устройство.
4. Уведомление об истечении
- событие
certificate.expiringв поток событий Control при остатке меньше трети срока; - поле остаточного срока в ответе
/api/v1/control/agents; - отображение в Desktop на странице Servers.
5. Ротация Control CA
Документ docs/certificate-rotation.md:
- когда ротация требуется: компрометация, истечение, смена алгоритма;
- порядок: выпуск нового CA, период двойного доверия, перевыпуск клиентских сертификатов, вывод старого CA;
- что делает оператор руками и что делает bootstrap;
- как проверить, что ни один Node не остался на старом CA;
- почему ротация CA требует режима подтверждения
two_person— см.docs/approval-policies.md.
Реализация автоматической ротации в эту задачу не входит — только процедура и то, что нужно для её ручного выполнения.
Тесты
- Сертификат с остатком меньше трети срока продлевается;
agent.pfxзаменён, старый сертификат больше не используется. - Сертификат с достаточным остатком не продлевается — лишних запросов нет.
- Hub недоступен в момент продления: Agent продолжает работать на действующем сертификате, повторяет попытку позже, метрики не теряются.
- Отозванный сертификат продлить нельзя — запрос отклонён.
- Запрос продления сертификатом другого
node_idотклонён. - Замена
agent.pfxпрервана на середине: остаётся действующий сертификат, Agent поднимается. - Срок вне диапазона в конфигурации: Control не стартует, ошибка валидации внятная.
Критерий приёмки
- Node, проработавший дольше срока сертификата, продолжает работать без вмешательства оператора;
- отзыв по-прежнему немедленно закрывает доступ;
- существующие тесты
CertificateAuthorityTestsи сценарии перерегистрации зелёные без правок логики; docs/certificate-rotation.mdописывает выполнимую процедуру, а не намерение;- Control suite прогнан на Linux;
- PR создан, CI зелёный;
- независимый review получил полный текст этого задания.
Границы
- не трогать
LinkService.cs,LinkPolicyApplier.cs,LinkReconciliationBackgroundService.cs,ControlStore.csв части Links,Provisioning.Helper/*иdeploy/ochenstarik-smm-policy-apply— они заняты заданием B-3R; - CRL не вводить;
- автоматическую ротацию CA не реализовывать;
- приватный ключ Control CA остаётся на Hub и в enrollment-коды не попадает.
Отчётность
Раздельно перечислить: что запущено локально, что в CI, что не запускалось и почему. Статус после merge — merged / verified.