Як прибрати постійний токен Docker Hub із GitHub Actions і не зупинити збірки

Docker HubGitHub Actionsбезпека CI

Поетапний план переходу на OIDC: знайти залежності від старого секрету, обмежити довіру репозиторієм і гілкою, перевірити push та лише потім відкликати PAT або OAT

Видимий ризик: секрет працює не лише всередині CI

Токен Docker Hub колись додали до GitHub Secrets, і workflow запрацював. Але PAT або OAT — особистий чи організаційний токен доступу — може залишатися чинним до завершення строку дії або відкликання. Той, хто отримає його значення, потенційно зможе використати надані права поза GitHub Actions.

Тому міграцію не слід починати з видалення секрету. Спочатку знайдіть усіх його споживачів, налаштуйте OIDC для потрібного запуску та окремо доведіть, що отримання й надсилання образів працюють без старого токена.

Що змінює OIDC

OpenID Connect, або OIDC, дає GitHub Actions змогу підтвердити особу конкретного запуску без збереженого постійного ключа. GitHub видає підписаний JWT — токен із відомостями про запуск. Docker перевіряє потрібні поля, або твердження, за правилом довіри й повертає короткоживучий токен.

Різниця полягає у строку дії та умовах видачі. Статичний PAT/OAT можна використовувати, доки він чинний. OIDC-токен видається лише після перевірки запуску й швидко втрачає чинність. Проте його значення все одно треба захищати: якщо воно витече, ним потенційно можна скористатися до завершення строку дії.

Вузьке правило довіри не менш важливе за короткий строк. Воно має приймати лише очікуваний репозиторій і ref — посилання на потрібну гілку або тег — замість усіх workflow організації.

Перевірте передумови та знайдіть залежності

Перед змінами перевірте три речі:

  • OIDC-підключення доступне для вашої Docker Org;
  • у вас є адміністративний доступ до налаштувань цієї організації;
  • ви маєте право редагувати потрібний workflow GitHub Actions.

Потім знайдіть назву старого secret у .github/workflows, повторно використовуваних workflow та налаштуваннях середовищ. Перевірте інші репозиторії й зовнішні завдання, які могли отримувати той самий токен. Якщо це секрет рівня GitHub organization, не обмежуйте пошук одним репозиторієм.

Зафіксуйте цільовий реєстр, назву образу, потрібні операції, дозволені гілки або теги й останній успішний запуск. Не копіюйте значення секрету до документації, задачі або чату.

Міграція без різкого перемикання

1. Спочатку визначте очікувану область довіри

Запишіть, який саме GitHub repository має отримувати доступ, з якого ref він запускається та чи потрібні йому pull, push або обидві операції. Це дає критерій перевірки до зміни налаштувань.

Створіть OIDC-підключення в Docker Org за актуальною інструкцією Docker. Почніть із конкретного репозиторію та потрібної гілки або тега. Не розширюйте правило на всю GitHub organization лише для того, щоб перший тест став успішним.

Окремо перевірте sub — твердження JWT, яке описує суб’єкта запуску. Запуски з гілки, pull request і тега можуть мати різні значення. Якщо правило очікує основну гілку, інший контекст не повинен автоматично отримати доступ.

2. Дозвольте workflow запросити OIDC-токен

Для запиту токена GitHub Actions потрібен дозвіл id-token: write. Типовий фрагмент для job, який також читає вміст репозиторію, виглядає так:

permissions:
  contents: read
  id-token: write

contents: read потрібен лише тоді, коли кроки job справді читають вміст репозиторію. Це не частина самого OIDC-обміну. Перегляньте решту permissions і залиште лише ті, що потрібні конкретному workflow.

id-token: write не надає права надсилати образи до Docker Hub. Він лише дозволяє workflow запросити доказ своєї особи. Docker окремо перевіряє, чи відповідає цей доказ підключенню та чи дозволена потрібна операція.

3. Перевірте новий шлях без старого секрету

Для першої перевірки використайте окремий job або тимчасовий workflow, який узагалі не посилається на старий secret. Інакше чинний старий крок входу може дати хибний успішний результат.

Рухайтеся від найменш ризикованої перевірки до операцій, що змінюють реєстр:

  1. Виконайте OIDC-вхід саме за актуальною інструкцією Docker та переконайтеся, що обмін завершився успішно.
  2. Якщо workflow потребує pull, отримайте відомий дозволений тестовий образ.
  3. Якщо потрібен push, використайте призначене для тесту, неproduction-сховище та унікальний тег.
  4. Перевірте digest — незмінний ідентифікатор вмісту образу — і виконайте pull того самого посилання.
  5. Переконайтеся, що job не звертався до старого secret на жодному кроці.

Зелений статус без перевірки фактичного образу доводить лише те, що job завершився, а не те, що новий шлях автентифікації працює правильно.

Якщо обмін не спрацював

Почніть із простих перевірок:

  1. Чи є id-token: write у потрібного workflow або job?
  2. Чи справді запустився потрібний job?
  3. Чи повністю вилучено старий шлях входу з тесту?
  4. Чи правильно вказані repository, гілка або тег?
  5. Чи відповідає контекст запуску очікуваному sub?

Не виводьте повний JWT або короткоживучий токен у журнал і не передавайте їх до публічного декодера. Якщо для діагностики потрібен sub, переглядайте лише необхідні дані в довіреному середовищі та звіряйте їх із документацією GitHub і Docker.

Якщо виправлення начебто вимагає шаблону для всіх репозиторіїв або гілок, зупиніться. Безпечніше виправити точне правило чи неправильний контекст запуску, ніж приховати помилку надто широкою довірою.

Перемикання, відкликання та відкат

Після успішних перевірок pull і push ще раз перегляньте всі знайдені workflow та зовнішні завдання. Видаліть посилання на старий secret і переконайтеся, що звичайний запуск використовує тільки OIDC. Лише після цього відкличте PAT/OAT у Docker Hub та видаліть запис secret із GitHub.

Підготуйте відкат до відкликання: збережіть посилання на попередній commit, призначте відповідального й визначте умову зупинки міграції. Поки старий токен чинний, контрольований короткий відкат ще можливий.

Після відкликання не намагайтеся повернути старе значення. Якщо аварійна процедура дозволяє тимчасові статичні credentials, створіть новий окремо схвалений токен лише з необхідними правами та строком дії. Після відновлення OIDC його також потрібно відкликати.

Небезпечні скорочення

Не варто:

  • відкликати PAT/OAT до окремої перевірки нового входу;
  • залишати старий secret у тому самому тестовому job;
  • розширювати довіру на всю організацію через одну помилку sub;
  • друкувати JWT або отриманий Docker-токен у журналах;
  • вважати, що міграція автоматично охопила локальні клієнти чи інші CI-системи.

Де допоможе AI — і де ні

AI може переглянути знеособлений фрагмент YAML, знайти кроки автентифікації та вказати на потенційно зайві permissions. Передавайте конкретне завдання, тип запуску, потрібні операції та placeholder-и замість приватних назв. Не передавайте secrets, повний JWT або необроблені журнали.

Модель не бачить фактичне правило Docker Hub, приховані workflow чи результат обміну. Тому кожну пораду треба звірити з налаштуваннями Docker Org, реальним запуском, очікуваним sub, отриманим образом і документацією Docker.

Межі рішення та висновок

OIDC зменшує залежність GitHub Actions від довгоживучого секрету, але не робить витік короткоживучого токена нешкідливим. Рішення також не налаштовує автоматично локальний Docker, інші CI-системи або сторонні завдання. Кожен такий споживач потребує окремої перевірки й підтримуваного способу автентифікації.

Безпечний порядок простий: знайти всіх споживачів старого токена, створити вузьке правило довіри, додати id-token: write, ізольовано перевірити pull і тестовий push, а потім видалити та відкликати PAT/OAT. Не прискорюйте міграцію послабленням правила, яке має її захищати.

Джерела

Короткий чеклист

  • знайти всі посилання на старий secret
  • створити вузьке правило довіри
  • додати `id-token: write`
  • окремо перевірити push і pull
  • відкликати PAT/OAT лише після тесту

Перевірка плану міграції Docker Hub на OIDC

Допоможи перевірити міграцію GitHub Actions зі статичного токена Docker Hub на OIDC. Вхідні дані: - знеособлений фрагмент workflow YAML; - тип запуску: branch, tag або environment; - потрібні операції: push, pull; - очікувані repository і ref у вигляді placeholder; - поточний список permissions без значень secrets. Не проси токени, повний JWT, назви приватних репозиторіїв або журнали з обліковими даними. Поверни Markdown із розділами: Місця автентифікації, Мінімальні permissions, Перевірка правила довіри, План тесту, Ризики, Відкат, Що потрібно перевірити вручну. Не вигадуй фактичні налаштування Docker Hub.