MAATRIX / Блог / Дать доступ разработчику на неделю и забрать обратно: как это устроить

Дать доступ разработчику на неделю и забрать обратно: как это устроить

MAATRIX

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

Почему «на неделю» — это отдельный случай, а не короткий найм

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

Практические следствия:

  • Механизм отзыва выбирается сразу, а не придумывается потом — раз срок известен, можно сразу поставить его в сертификате, аккаунте или токене.
  • Не нужен реестр на десятки записей — достаточно одной строки с двумя датами и календарного напоминания.
  • Расширять права по ходу работы — плохая идея вдвойне. У недельной задачи узкий периметр по определению: конкретный баг, конкретный сервис. Если на третий день просят доступ «ещё вот сюда» — задача выросла за исходные рамки, и это повод пересмотреть объём доступа, а не молча расширить его.

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

Выбрать механизм истечения до выдачи доступа

Три рабочих варианта, от самого надёжного к самому простому:

  1. SSH-сертификат с фиксированным окном действия — если у вас настроена своя CA для SSH, сертификат сам перестаёт проходить проверку по истечении срока.
  2. Отдельный аккаунт с датой блокировки на уровне ОС — без своей CA chage -E даёт похожий эффект: система сама блокирует вход после указанной даты.
  3. Обычный ключ плюс жёсткое календарное напоминание — самый простой вариант, но единственный, где отзыв полностью зависит от человека. Годится для мелкой разовой задачи, но лучше не останавливаться на нём, если доступны первые два.

Дата должна быть той же, что зафиксирована в задаче, — не «примерно через неделю», а конкретное число: «доступ с 8 по 15 сентября 2026», а не «на неделю с момента начала работы».

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Временный SSH-ключ с фиксированным сроком

Если под инфраструктурой уже есть SSH-CA — например, для входа админов через bastion, — для недельного подрядчика это даёт готовый self-expiring доступ:

# Сертификат на 7 суток: с 8 по 15 сентября 2026 включительно
ssh-keygen -s /etc/ssh/ca_user_key \
  -I "dev_contractor_ivanov_task5521" \
  -n devops_readonly \
  -V "20260908000000:20260915235959" \
  -O force-command="/usr/local/bin/restricted-shell.sh" \
  ivanov_temp_key.pub

Явные даты «от—до» надёжнее относительного +7d: они не зависят от момента, когда вы фактически выполнили команду, а совпадают с датами из задачи. После 15 сентября 23:59:59 сервер откажет в подключении по этому сертификату, даже если про ручной отзыв все забыли.

Если сертификатов нет и используется обычный публичный ключ, у самого authorized_keys нет поля срока действия — эту дату придётся хранить отдельно, в связке с блокировкой аккаунта (см. ниже). Что можно ограничить прямо в файле без даты — команду и опции подключения:

command="/usr/local/bin/deploy-fix.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...ключ_разработчика...

Отдельная учётная запись, которая сама перестаёт пускать в срок

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

useradd -m -s /bin/bash -c "Contractor Ivanov, task #5521, expires 2026-09-15" ivanov_temp
mkdir -p /home/ivanov_temp/.ssh
cp ivanov_temp_key.pub /home/ivanov_temp/.ssh/authorized_keys
chown -R ivanov_temp:ivanov_temp /home/ivanov_temp/.ssh
chmod 700 /home/ivanov_temp/.ssh
chmod 600 /home/ivanov_temp/.ssh/authorized_keys
passwd -l ivanov_temp
chage -E 2026-09-15 ivanov_temp

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

Права стоит выдавать так же точечно, как постоянному подрядчику, — через sudoers под конкретные команды, а не общий root:

# /etc/sudoers.d/ivanov_temp — только рестарт и логи одного сервиса
ivanov_temp ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp.service, /usr/bin/journalctl -u myapp.service *

Про то, почему root «для скорости» на разовой задаче обычно того не стоит, — в статье «Антипаттерн: выдать подрядчику root и забыть»: недельный срок сам по себе от этого риска не защищает.

Доступ за пределами сервера: репозиторий, панель, облако

Реальная задача редко ограничивается SSH — обычно нужен ещё репозиторий, иногда панель хостинга или облачный аккаунт. У каждого свой способ ограничить срок:

ДоступВстроенный срок действияЧто делать
GitLab (проект/группа)Да — поле «Access expiration date» при добавлении участникаУказать дату сразу при выдаче роли Developer/Maintainer
GitHub (репозиторий)У приглашения коллаборатора — нет; у fine-grained personal access token — даПросить выпустить fine-grained PAT со сроком вместо доступа с постоянного аккаунта
Панель хостинга/VPSОбычно нетЗаводить отдельный логин, если провайдер поддерживает, и удалять вручную по чек-листу
Облако (AWS IAM и подобные)У временной сессии STS — да; у постоянных ключей IAM-пользователя — нетВыдавать доступ через AssumeRole с ограниченной длительностью сессии, а не постоянные ключи

GitLab здесь удобнее большинства систем: срок действия участника — штатное поле, а не самодельная надстройка. Выставили дату 15 сентября — 16-го участник автоматически теряет доступ, ничего дополнительно отзывать не нужно.

Если задачу можно решить без доступа к боевому серверу вообще — например, дать копию на отдельном тестовом стенде, — это снижает риск сильнее любого таймера. Но здесь есть ловушка: стенд снижает риск только тогда, когда на нём нет боевых данных и боевых доступов. О том, как стенд с прод-доступами внутри сам стал точкой входа, — отдельный разбор инцидента: «Тестовый стенд с боевыми доступами стал точкой входа в прод». Прежде чем выдавать разработчику доступ к стенду вместо прода, стоит убедиться, что стенд действительно изолирован, а не прод под другим именем.

Автоматизация отзыва, чтобы конец недели не зависел от памяти

chage -E и срок сертификата закрывают вход технически, но не убирают саму учётную запись, ключ в authorized_keys и временные правила firewall — это нужно подчистить отдельно. Надёжный вариант — systemd-таймер, который в день Х выполнит финальную очистку сам, даже если про неё все забыли:

# /etc/systemd/system/revoke-ivanov-temp.timer
[Unit]
Description=Trigger revoke for ivanov_temp on 2026-09-15

[Timer]
OnCalendar=2026-09-15 20:00:00
Persistent=true

[Install]
WantedBy=timers.target
# /usr/local/bin/revoke-contractor.sh — вызывается сервисом revoke-ivanov-temp.service
#!/bin/bash
USER_TO_REVOKE="$1"
usermod -L "$USER_TO_REVOKE"
> "/home/$USER_TO_REVOKE/.ssh/authorized_keys"
echo "Доступ $USER_TO_REVOKE отозван автоматически $(date)" | \
  mail -s "Отзыв временного доступа: $USER_TO_REVOKE" admin@example.com

Для одной разовой задачи заводить systemd-юнит может показаться избыточным — тогда обязательный минимум — два конкретных календарных напоминания, а не одно расплывчатое: на дату выдачи («создан временный доступ ivanov_temp, отзыв — 15 сентября») и на дату отзыва («отозвать ivanov_temp: заблокировать, очистить ключ, проверить sudoers и firewall»). Таймер не заменяет chage -E — это подстраховка на случай, если срок продлевали вручную и забыли сдвинуть дату блокировки, а заодно способ гарантированно очистить authorized_keys, чего сама блокировка аккаунта не делает.

Чек-лист на день Х

К дате планового окончания стоит подходить с готовым списком, а не вспоминать по ходу, что ещё выдавалось за неделю:

  • [ ] Заблокирована или удалена временная учётная запись (usermod -L или userdel -r)
  • [ ] Ключ убран из authorized_keys, сертификат истёк или отозван вручную
  • [ ] Удалена запись из sudoers.d
  • [ ] Отозван доступ в репозитории — участник удалён или истёк выданный токен
  • [ ] Закрыты временные правила firewall под задачу (например, доступ к порту БД только с IP разработчика)
  • [ ] Отозван доступ в панели хостинга или облаке, если заводился отдельно от SSH
  • [ ] Результат работы принят и зафиксирован — прежде чем отзывать доступ, стоит убедиться, что фикс закрыт, а не «почти готов»
  • [ ] Реестр доступов (если ведёте) обновлён — запись помечена закрытой с датой

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Разработчик не успел за неделю, задача выросла — что со сроком?

Продление — отдельное осознанное решение, а не автоматическое «пусть повисит ещё». Сдвиньте chage -E и, если используете сертификат, выпустите новый на новый срок — старый пусть истечёт как планировалось. Если продления случаются регулярно, вероятно, задача на самом деле не недельная.

Стоит ли заводить отдельный сервер под недельную задачу вместо доступа на боевой?

Если задача позволяет — да, это снимает почти все риски разом: после недели сервер просто удаляется целиком, вместо того чтобы вычищать права на общей машине. Для мелкого фикса на существующем сервисе это не всегда реалистично, но для разработки нового модуля отдельная VPS на неделю часто дешевле, чем разбор инцидента после.

Что если у разработчика уже был доступ раньше, по прошлому проекту, и нет уверенности, что всё отозвали?

Не полагайтесь на память — проверьте authorized_keys, список пользователей и sudoers перед тем, как выдавать новый доступ. Найдёте старые следы — почистите сразу, а не откладывайте до отдельного аудита.

Нужен ли NDA на недельный доступ, если задача маленькая?

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

Можно ли сразу удалить учётную запись в день Х, а не блокировать?

Для недельной задачи разумнее сначала заблокировать (usermod -L) и подержать так пару дней на случай вопросов по итогам работы, а полное удаление через userdel -r поставить отдельным шагом чуть позже, когда результат точно принят.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →