Тайм-ауты подтверждений не дают старым разрешениям запускать новые действия
Тайм-ауты подтверждений не дают старым разрешениям на развёртывание, удаление и SSH-команды выполняться после изменения целей или условий. Узнайте, как привязывать, ограничивать и повторно проверять подтверждения.

Подтверждение даёт разрешение на одно предложенное действие в конкретный момент. Это не купон, который агент может обналичить, когда ему удобно.
Звучит очевидно, пока агент ставит в очередь развёртывание в production, удаление или SSH-команду, а человек занят. Проверяющий видит разумный запрос и подтверждает его, но затем мир меняется. В очередь попадает более новая сборка. Меняется набор целей. Кто-то переназначает псевдоним окружения. Инцидент меняет условия безопасности. Если старое подтверждение всё ещё можно применить, система превращает решение о вчерашнем состоянии в полномочие действовать над сегодняшним.
Тайм-ауты подтверждений решают только одну часть этой проблемы, но именно её команды часто оставляют открытой. Задайте короткий жёсткий срок для подтверждений действий, смысл которых может измениться. Затем привяжите подтверждение к точному предложенному действию и перед выполнением снова проверьте изменяемые условия. Нужны оба механизма. Каждый из них по отдельности оставляет пробел.
У подтверждения есть бюджет актуальности
Пока подтверждение ждёт выполнения, оно постепенно теряет актуальность. Чем сильнее может измениться цель, тем меньше должен быть этот бюджет.
Запрос на перезапуск одноразового preview-воркера может оставаться актуальным полчаса. Запрос на выпуск релиза в production устареет за несколько минут, если другой релиз, откат или реакция на инцидент могут изменить правильный следующий шаг. Команда, удаляющая резервную копию с указанным именем, должна быстро истекать, если список снимков активно меняется из-за политики хранения. Для SSH-команды, обращающейся к изменяемому псевдониму хоста, нужно самое короткое окно.
Плохой вариант по умолчанию, выбрать одно большое число, чтобы никого не раздражать. Восемь часов кажутся удобными. На практике это позволяет подтверждениям накапливаться во время обеда, ночью или при передаче смены. Проверяющий может подтвердить развёртывание в 10:02, забыть о нём и в 16:40 обнаружить, что его нажатие использовало гораздо более позднее состояние очереди. Интерфейс подтверждения выглядел аккуратно. Путь выполнения был безответственным.
Задайте окно, ответив на более узкий вопрос: как долго именно это предложенное действие будет точно описывать то, что произойдёт?
Для большинства команд разумная стартовая политика выглядит так:
- Развёртывание или откат в production: 5-15 минут.
- Разрушительное удаление: 2-10 минут, в зависимости от того, зафиксирован ли набор объектов.
- SSH-команда с эффектом записи: 2-5 минут.
- SSH-проверка только для чтения: подтверждение для каждого действия не нужно или можно задать более длинное окно, если среда всё же его требует.
- Обычные изменения в nonproduction с закреплённой сборкой: 15-30 минут.
Это рабочие значения по умолчанию, а не универсальные константы. Пять минут слишком много, если цикл автоматизации может менять цель каждые несколько секунд. И слишком мало, если дежурному нужно сначала собрать данные. Правильный ответ, не продлевать срок без конца. Дайте проверяющему нужный контекст и сделайте запрос простым для повторного создания на основе текущего состояния.
В GitHub Actions есть важное различие: job развёртывания может ждать обязательной проверки, а ожидающий job после подтверждения продолжает работу и получает доступ к секретам окружения. GitHub также указывает, что неподтверждённый job может завершиться ошибкой через 30 дней. Это не даёт очередям жить вечно, но 30 дней не может быть полезным окном актуальности для подтверждения меняющегося развёртывания. Собственный шлюз должен считать возраст подтверждения частью авторизации, а не обслуживанием очереди.
Привязывайте решение к действию, а не к ярлыку
Подтверждение должно охватывать конкретные данные действия. «Подтвердить развёртывание в production» это ярлык. Он почти ничего не говорит проверяющему об объекте, который будет запущен.
Для развёртывания привяжите решение к неизменяемому дайджесту артефакта или идентификатору коммита, назначению, плану миграции, если он есть, ревизии конфигурации и операции выпуска. Для удаления привяжите его к неизменяемому списку объектов или снимку результата запроса, а также к режиму удаления. Для SSH привяжите его к проверенной идентичности хоста, пользователю, шаблону команды, раскрытым аргументам, рабочему каталогу, если он важен, и ограниченному описанию входных файлов.
Чаще всего команды смешивают два понятия:
- Подтверждение намерения означает, что проверяющий согласен с общей целью, например «удалить устаревшие preview-окружения».
- Подтверждение действия означает, что проверяющий согласен с тем, что этот исполнитель удалит эти идентификаторы объектов этой командой до указанного срока.
Подтверждение намерения уместно в управлении изменениями. Оно не заменяет подтверждение выполнения, если агент может действовать в работающей системе. Если вы подтверждаете намерение, а затем позволяете агенту позже определить цели, важную часть решения вы передали агенту.
OWASP отмечает это в другом контексте в Transaction Authorization Cheat Sheet. Документ говорит, что человек, авторизующий транзакцию, должен определить и подтвердить важные данные транзакции, а изменение данных после авторизации создаёт ошибку «проверка и использование в разные моменты». Пример финансовый, но правило легко переносится: данные подтверждения нужно защищать от изменения, а изменение данных должно аннулировать существующее разрешение.
Дайджест даёт исполнителю точное значение для сравнения. Не хешируйте расплывчатое описание на естественном языке и не считайте задачу выполненной. Канонизируйте поля, которые управляют эффектом, детерминированно сериализуйте их, а затем хешируйте полученную каноническую форму.
{
"request_id": "appr_01JX...",
"action_type": "deploy",
"action_digest": "sha256:8b1d...",
"summary": {
"artifact": "registry.example/app@sha256:4fa2...",
"environment": "production",
"operation": "promote",
"config_revision": "7c0e...",
"migration": "none"
},
"issued_at": "2026-07-22T14:03:00Z",
"expires_at": "2026-07-22T14:13:00Z",
"status": "pending"
}
summary предназначен для человека. action_digest нужен исполнителю. Сохраняйте оба поля. Людям нужны понятные факты, сервисам, точная проверка равенства. Если агент изменит хотя бы одно привязанное поле, он должен отправить новый запрос и получить новое решение.
Истечение и аннулирование решают разные проблемы
Срок действия не даёт старым подтверждениям оставаться в системе. Аннулирование удаляет подтверждение сразу после изменения важных фактов. Нужны оба механизма: ждать таймера неразумно, если система уже знает, что запрос больше не соответствует действительности.
Аннулируйте ожидающее подтверждение при изменении дайджеста действия. Это обязательное правило. Также аннулируйте его при изменении зависимости, влияющей на смысл: ревизии целевого окружения развёртывания, выбранного набора для удаления, ключа хоста, владельца блокировки выпуска или состояния обязательной заявки на изменение.
Не аннулируйте подтверждение из-за любого несвязанного события. Если любая строка журнала, посторонний коммит или безобидное изменение метрики уничтожает подтверждение, проверяющие решат, что запросам нельзя доверять, и начнут подтверждать их не глядя. Правило должно отслеживать факты, меняющие запрошенный эффект или условия безопасности.
Используйте три состояния, а не два:
pendingозначает, что точный запрос всё ещё можно подтвердить до истечения срока.approvedозначает, что проверяющий его подтвердил, но исполнитель ещё не использовал подтверждение.consumedозначает, что выполнение ровно один раз получило подтверждение.
Добавьте конечные состояния expired, invalidated, rejected и failed. Отклонённый запрос не должен снова стать pending, потому что агент повторил сетевой вызов. Неудачное выполнение не должно молча использовать то же подтверждение, если только вы не можете доказать, что действие не началось и важное состояние не изменилось. В большинстве систем действий безопаснее и понятнее попросить агента подтвердить запрос ещё раз.
Исполнитель должен выполнить эти проверки в одной транзакции или одной атомарной операции compare-and-set:
if now >= expires_at: reject as expired
if status != approved: reject as unavailable
if stored_digest != supplied_digest: reject as changed
if live_preconditions fail: reject as stale
atomically change status from approved to consumed
execute the action
Не помечайте подтверждение как использованное после начала действия. Два воркера могут одновременно увидеть approved и оба выполнить его. Сначала используйте атомарный переход состояния, затем запишите начало выполнения. Если процесс завершился после потребления подтверждения, считайте результат неизвестным, пока исполнитель не установит, достигло ли действие цели. Это неудобно. Двойная разрушительная операция хуже.
Подтверждения развёртывания должны следовать за артефактом
Запрос на развёртывание устаревает, если меняется его артефакт, назначение, план выпуска или место в очереди. Имен веток и изменяемых тегов недостаточно.
В запросе нужно указывать неизменяемый артефакт. Это может быть дайджест образа, хеш подписанного пакета выпуска или неизменяемая запись сборки. Также сообщите проверяющему, будет ли исполнитель запускать миграции базы данных, менять конфигурацию функций, перезапускать экземпляры или заменять предыдущее развёртывание. Эти детали влияют на решение. Скрывать их за общей кнопкой «развернуть» значит провоцировать механическое подтверждение.
Хороший контракт подтверждения развёртывания включает:
- Неизменяемый идентификатор сборки и исходную ревизию.
- Точное целевое окружение и идентичность аккаунта или кластера.
- Операцию выпуска: promote, rollback или redeploy.
- Ревизии конфигурации и миграций, которые будут применены.
- Токен конкурентного доступа или поколение развёртывания.
Токен конкурентного доступа важен, когда более новое изменение заменяет старый запрос. Представьте, что сборка A ждёт подтверждения. Сборка B завершилась, прошла проверки и стала выпуском, который вы теперь хотите отправить. Если запрос A всё ещё действителен, проверяющий может случайно выпустить старую сборку. Когда B входит в тот же канал выпуска, аннулируйте ожидающее подтверждение A. Не рассчитывайте, что в занятой очереди проверяющие заметят временные метки.
Документация GitHub по развёртываниям разделяет защиту окружения и конкурентность workflow. Механизмы конкурентности могут отменить ожидающую работу в группе, а подтверждение окружения определяет, может ли job продолжить выполнение. Это полезное разделение: политика очереди решает, какой запуск считать текущим, а шлюз подтверждения, может ли выполниться именно этот запуск. Неосторожное объединение приводит к классической ошибке, когда нужный человек подтверждает не тот запуск.
Перед развёртыванием исполнитель должен повторить проверки. Практический preflight может убедиться, что запрошенный артефакт всё ещё существует, окружение по-прежнему указывает на ожидаемую идентичность цели, более новый выпуск не занял канал, а план миграции соответствует одобренному дайджесту. При любой ошибке пометьте запрос как аннулированный и покажите проверяющему новый запрос. Никогда молча не подменяйте сборку A сборкой B только потому, что A была подтверждена. Это другое действие.
Избегайте популярной, но слабой схемы: подтвердить pull request и считать это разрешением на production. Проверка кода отвечает на вопрос, должна ли предлагаемая правка попасть в кодовую базу. Она не отвечает на вопрос, нужно ли запускать эту сборку в production сейчас, после текущего инцидента, с текущими миграциями и состоянием целей. Разделяйте эти решения.
В запросах на удаление нужен зафиксированный набор объектов
Подтверждения удаления становятся опасными, когда запрос содержит запрос выборки, а не найденные объекты. «Удалить резервные копии старше 30 дней» может каждую минуту означать другой набор.
При создании запроса разрешите выборку в идентификаторы объектов и сохраните маркер снимка. На экране подтверждения покажите количество, несколько характерных идентификаторов, основание хранения и точный режим удаления. Исполнитель должен использовать зафиксированный набор, а не повторно запускать широкую выборку после подтверждения.
Если набор слишком велик для полного отображения, укажите стабильный идентификатор манифеста и краткую разбивку. Не сводите запрос к «удалить 8 421 объект» без границ. Одно число не скажет проверяющему, не попали ли в список другой арендатор, текущие резервные копии или неожиданный префикс.
Рассмотрим такой запрос:
{
"action_type": "delete_objects",
"scope": "archive/preview/",
"selection": {
"manifest_digest": "sha256:19e7...",
"object_count": 184,
"newest_object_at": "2026-06-19T03:11:00Z",
"oldest_object_at": "2025-11-02T18:24:00Z"
},
"mode": "permanent",
"expires_at": "2026-07-22T14:08:00Z"
}
Во время выполнения убедитесь, что манифест всё ещё существует и каждый идентификатор объекта соответствует ожидаемой версии. Если система хранения поддерживает версии, привязывайте удаление к версиям, а не к именам. Имена можно использовать повторно. Новый объект, записанный по тому же пути после подтверждения, не должен унаследовать смертный приговор старого объекта.
Короткий срок особенно важен, когда запрос основан на возрасте или текущем списке объектов. Чем дольше он ждёт, тем вероятнее, что новый подходящий объект, восстановленный элемент или переклассифицированная запись изменит предполагаемый набор. Если систему нельзя заставить работать с зафиксированным набором, одно подтверждение не должно разрешать широкую выборку для удаления. Запрашивайте более узкое и свежее действие.
Для мягкого и окончательного удаления нужны разные запросы и разные окна действия. Мягкое удаление можно отменить, но обратимость не оправдывает расплывчатое подтверждение. Восстановление часто медленное, неполное или зависит от разрешений, которыми не управляет человек, запросивший удаление.
SSH-контекст устаревает быстрее, чем кажется
SSH особенно чувствителен к устаревшему контексту: имена, сеансы, переменные окружения и рабочие деревья могут измениться, хотя текст команды останется тем же.
systemctl restart api выглядит конкретно, пока не спросить, какая машина его получит, на что там указывает api, какое развёртывание сейчас активно и не изменил ли следующий инцидент причину перезапуска. rm -rf /srv/tmp/job-123 может быть безопасной командой на одном хосте и катастрофой на другом, если изменились псевдоним, подключённая файловая система или раскрытие оболочки.
Для SSH подтверждайте структурированный запрос команды, а не расшифровку терминала. В запросе должны быть проверенная идентичность хоста, целевой пользователь, фиксированный шаблон команды, полностью раскрытые разрешённые аргументы, объявленный рабочий каталог и дайджест ожидаемых входных файлов. Если агенту нужна оболочка, ограничьте её явной полезной нагрузкой, а не разрешайте открытую интерактивную сессию.
Карточка подтверждения может выглядеть так:
Host: prod-api-03, host key SHA256:K4f...
User: deploy
Command: /usr/local/bin/release-health --release 2026.07.22.4 --repair-cache
Directory: /srv/api
Effect: writes cache state, may restart one service
Expires: 14:08 UTC
Это всё ещё не доказывает безопасность команды. Но человеку достаточно информации, чтобы понять, что именно он разрешает. Затем исполнитель заново подключается, снова проверяет идентичность хоста, подтверждает дайджест команды и запускает её до истечения срока.
Никогда не позволяйте подтверждению команды на prod-api разрешать выполнение после того, как DNS, инвентарь или схема bastion-сервера направили этот ярлык на другой хост. Если настройки соединения позволяют, привязывайте запрос к криптографической идентичности хоста. При законной смене ключа хоста во время ожидания подтверждение нужно аннулировать. Во время обслуживания это может раздражать, но лучше не подтвердить команду для одной машины и не отправить её другой.
Команды только для чтения заслуживают отдельной категории. Команды часто требуют подтверждение каждого SSH-вызова, потому что у них есть один контроль, который применяют повсюду. В результате возникает усталость от подтверждений, и проверяющие начинают нажимать на команды, которых не понимают. Разделяйте безобидные проверки и действия, которые записывают данные, перезапускают службы, меняют доступ или раскрывают чувствительный вывод. Используйте подтверждение каждого вызова там, где этого требует эффект команды, и делайте запрос достаточно компактным для чтения.
На экране подтверждения изменения должны быть заметны
Точный контракт на стороне сервера бесполезен, если проверяющий видит только предложение, написанное агентом. Экран должен показывать поля, из-за которых решение может измениться.
Начинайте с эффекта: развернуть этот дайджест в это окружение, навсегда удалить этот зафиксированный манифест, выполнить эту команду на этом проверенном хосте. Срок должен быть заметен до подтверждения, а время указано в однозначном часовом поясе. Обратный отсчёт можно показывать для удобства, но действительность определяет серверная временная метка исполнителя.
При изменении запроса не заменяйте старое содержимое на месте, оставляя активной кнопку подтверждения. Пометьте запрос как аннулированный. Создайте новый запрос с понятным объяснением: «артефакт изменился» или «изменился инвентарь целей». Проверяющий, подтвердивший прежнюю версию, должен принять новое решение. Именно это дополнительное нажатие и нужно.
NIST SP 800-63B-4 описывает намерение аутентификации как действие пользователя, подтверждающее желание пройти аутентификацию или повторно её пройти. Для подтверждения действия нужна такая же дисциплина, но в более узких рамках. Нажатие или клик должны выражать намерение выполнить показанную операцию, а не общее согласие позволить агенту продолжать.
Не превращайте нехватку времени в ловушку. Двухминутное окно для сложного удаления заставляет выбирать между слепым подтверждением и истечением срока. Запрос должен быть готов к проверке ещё до того, как попадёт к проверяющему. Задавайте короткий срок выполнения после того, как человек получил достаточный контекст, а не торопите решение так, чтобы внимательное чтение стало невозможным.
Поле комментария полезно, когда проверяющему нужно объяснить, почему необычное действие допустимо. Не делайте комментарий обязательным для обычной работы. Обязательные шаблонные фразы порождают текст, который никто не читает. Требуйте комментарий для обходов, исключительных продлений срока или действий, превышающих заданный радиус воздействия.
Исполнитель отвечает за контроль
Система, обладающая полномочиями выполнить действие, должна проверять срок, привязку и однократное использование. Интерфейс workflow, чат-бот или фреймворк агента могут запросить подтверждение, но не могут быть последним судьёй, если другой компонент способен обойти их.
Поэтому шлюз действий становится полезной границей. Агент отправляет HTTP-вызов или SSH-команду. Шлюз проверяет, есть ли актуальное подтверждение, при необходимости подставляет учётные данные, выполняет операцию и возвращает результат. Агенту не нужны многоразовые учётные данные, которые позже позволят обойти путь подтверждения.
Sallyport использует такую схему для HTTP API и SSH: агент подключается через MCP shim, а учётные данные остаются в зашифрованном хранилище приложения. Само приложение выполняет действие, не передавая секреты агенту. Ключи для каждого вызова естественно подходят для свежего подтверждения там, где контекст быстро меняется. Но тайм-аут и привязка действия всё равно должны быть явно описаны в пути запроса: подтверждение без этих проверок со временем превращается в ту же проблему.
Храните состояние подтверждения рядом с исполнителем или сделайте его криптографически проверяемым исполнителем. Подписанный токен может подойти, если содержит идентификатор запроса, дайджест действия, время выпуска, срок действия, идентичность проверяющего и nonce. Исполнитель всё равно должен проверить отзыв и использовать nonce один раз. Подписанный токен, который остаётся действительным после аннулирования запроса, это всего лишь хорошо подписанное устаревшее подтверждение.
Осторожно работайте с часами. Для решений о сроке используйте часы доверенного сервиса, храните временные метки в UTC и отклоняйте подтверждения в момент истечения или позже. Локальные часы агента и обратный отсчёт в браузере нужны только для отображения. Они не являются входными данными авторизации.
Журналы должны объяснять, почему действие произошло или не произошло
Когда подтверждение истекает, команде нужна запись содержательнее, чем «отказано». Нужно понимать, проверяющий не ответил, запрос изменился после подтверждения, исполнитель обнаружил невыполненное условие или другой воркер уже использовал подтверждение.
Создайте неизменяемую цепочку событий, связывающую предложение, показанное описание, решение, аннулирование или истечение, preflight-проверки, попытку выполнения и результат. Сохраняйте дайджест действия в каждом событии. Если запрос создан заново, укажите идентификатор нового запроса, не создавая впечатления, что старое подтверждение перенеслось.
Полезная форма события выглядит так:
{
"event": "approval.invalidated",
"request_id": "appr_01JX...",
"action_digest": "sha256:8b1d...",
"reason": "release_lane_superseded",
"replaced_by": "appr_01JY...",
"recorded_at": "2026-07-22T14:06:22Z"
}
Записывайте и попытки использовать истёкшие подтверждения. Они показывают агентов, которые слепо повторяют запросы, воркеров с неправильными часами и интерфейсы, не обновившие данные. Кроме того, это помогает во время инцидента отличить истёкший запрос от действия, которое действительно достигло production.
Журналы Sessions и Activity в Sallyport строятся из зашифрованного журнала аудита с цепочкой хешей, а команда sp audit verify проверяет эту цепочку офлайн поверх шифротекста. Такой журнал полезен только при честном словаре событий. Записывайте события истечения, аннулирования и неудачных preflight-проверок, а не только успешные вызовы, чтобы панель выглядела аккуратно.
Не путайте возможность аудита с предотвращением. Идеальная запись о том, как старое подтверждение выполнилось над новым состоянием, это свидетельство ошибки. Проверка предотвращения должна выполняться до того, как исполнитель отправит запрос или откроет SSH-канал.
Сделайте замену истёкших запросов простой
Короткие окна работают только тогда, когда новый запрос создать проще, чем спорить со старым. Если для повторной генерации нужно снова вводить номер заявки, вручную собирать команду и искать трёх человек, команды начнут просить увеличить каждый тайм-аут до бессмысленного значения.
Агент должен уметь отправить запрос заново на основе свежего состояния, но новые факты нужно показать ясно. Если изменился только срок, а все привязанные поля остались прежними, новый запрос может сохранить то же понятное описание, получив новый идентификатор и срок. Если изменилось поле действия или актуальное предварительное условие, объясните что именно. Не заставляйте проверяющего сравнивать непрозрачные хеши.
Продление срока должно оставаться исключением. Если вы его предлагаете, исполнитель обязан заново пройти все preflight-проверки, а проверяющий снова должен увидеть актуальное описание. Кнопка «продлить на 30 минут», обновляющая старый токен, это обход подтверждения с более красивой типографикой.
Начните с измерения четырёх показателей: как часто истекают подтверждения, как часто подтверждённые действия аннулируются до выполнения, сколько ждут запросы и какие типы действий вызывают повторные попытки. Эти данные покажут, слишком ли короткий срок, медленная ли очередь или агент создаёт запросы до стабилизации входных данных.
Устаревшее подтверждение должно завершаться тихо и конкретно: исполнитель отклоняет его, журнал указывает причину, а агент запрашивает актуальное решение, если работа всё ещё нужна. Именно такой небольшой отказ сохраняет человеческий контроль над действием, которое действительно произойдёт.
Вопросы и ответы
Что такое тайм-аут подтверждения?
Тайм-аут подтверждения, это жёсткий срок, после которого неиспользованное подтверждение больше не может разрешить действие. Он не даёт одобрить запрос, уйти, а затем применить старое решение после изменения цели, команды или окружающих условий.
Как долго должно действовать подтверждение развёртывания?
Подтверждение развёртывания обычно должно истекать через минуты, а не через часы. Окно стоит сократить, если выпуск быстро может быть заменён другим или идёт инцидент. Немного большее окно допустимо, только если точные сборка и цель зафиксированы и повторно проверяются во время выполнения.
Достаточно ли срока действия, чтобы предотвратить устаревшие действия?
Нет. Короткий срок ограничивает время, в течение которого решение может оставаться без внимания, но не доказывает, что действие всё ещё означает то же самое. Привяжите подтверждение к неизменяемому дайджесту действия и непосредственно перед запуском проверьте изменяемые предварительные условия.
Что должно содержать подтверждение удаления?
Подтверждение должно указывать точный объект или выборку, её версию или маркер снимка, предполагаемый эффект и срок действия. Запрос вроде «удалить старые логи» недостаточно конкретен для безопасного подтверждения.
Должны ли истекать подтверждения SSH-команд?
Используйте короткий срок действия, фиксированный шаблон команды, точную идентичность узла и новую проверку соединения или хоста перед запуском. Подтверждение команды на одном хосте не должно превращаться в разрешение выполнить тот же текст на любом хосте, который позже окажется за этим псевдонимом.
То же ли самое тайм-аут подтверждения, что и идемпотентность?
Срок действия решает проблему устаревания. Идемпотентность решает проблему повторного выполнения. У развёртывания могут быть обе проблемы, поэтому используйте срок подтверждения и ключ идемпотентности выполнения или запись о выпуске, которая делает повторный запуск безопасным либо отклоняет его.
Что происходит после истечения подтверждения?
Истекшее подтверждение нужно закрыть и создать новый запрос на основе текущих данных действия. Не предлагайте обычную кнопку «продлить»: она приучает подтверждать решение заново, не проверяя, что изменилось.
То же ли самое таймер ожидания, что и срок действия подтверждения?
Нет. Период ожидания и окно действия решают противоположные задачи. Таймер ожидания откладывает возможность запуска, а срок действия ограничивает время, в течение которого подтверждение остаётся действительным после решения проверяющего.
Где нужно проверять истечение подтверждения?
Срок действия должен проверяться на шлюзе действий или у исполнителя, где система может сравнить одобренный дайджест с запросом, который собирается выполнить. Чат может показывать срок, но не должен быть последней инстанцией.
Что журнал аудита должен записывать для истёкшего подтверждения?
В журнале должны сохраняться дайджест действия, понятное человеку описание, личность проверяющего, время решения, срок действия, время выполнения, результаты актуальных проверок и итог. Записывайте также истёкшие и аннулированные попытки: они объясняют, почему действие не произошло.