портфолио / кейс 002 · бесплатно · открытый код

Вход через
Apple

автообновление секрета · GitHub Action · Supabase

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

[x] ключ прочитан
[x] секрет подписан
[x] Supabase обновлён
[ ] следующий запуск — через 5 месяцев
6
месяцев живёт секрет Apple — это его предел
0
зависимостей: только то, что уже есть в Node
1
файл с логикой — открывается и читается целиком

Как это ломается

▍через 6 месяцев после запуска
день 1 — вход через Apple работает
день 90 — работает
[~] день 180 — секрет истёк
[x] вход отвечает invalid_client
письма от Apple: нет
▍а узнаёте вы так
Пользователь: Не могу войти через Apple. Кнопка ничего не делает.
Вы: Всё работало полгода. Ничего не меняли, ничего не выкатывали.
Официальная рекомендация на этот случай — поставить напоминание в календаре на полгода.
[x] расписание
Обновляется само, раз в 5 месяцев

Не в 6, а в 5 — специально. Предел Apple около шести месяцев, и лишний месяц остаётся запасом на случай, если запуск не состоялся.

[x] supabase
Прописывает новый секрет за вас

Проект Supabase обновляется через его же API. Руками в панель заходить не нужно — ни сейчас, ни через полгода.

[~] любой другой стек
Firebase, Auth0, свой сервер

Не на Supabase — уберите два поля, и действие просто отдаст готовый секрет наружу. Дальше подставляйте его туда, куда нужно вашему проекту.

Вся установка

Один файл в репозиторий и четыре секрета в настройки. Дальше запускаете вручную один раз — и больше к этому не возвращаетесь.

▍.github/workflows/rotate-apple-secret.yml
on:
  schedule:
    - cron: "0 6 1 */5 *"   # раз в 5 месяцев, с запасом
  workflow_dispatch: {}      # первый запуск — вручную

jobs:
  rotate:
    runs-on: ubuntu-latest
    steps:
      - uses: oskar-makarov/apple-client-secret-rotator@v1
        with:
          apple_team_id: ${{ secrets.APPLE_TEAM_ID }}
          apple_key_id: ${{ secrets.APPLE_KEY_ID }}
          apple_services_id: com.example.app.web
          apple_p8: ${{ secrets.APPLE_P8 }}
          supabase_project_ref: your-project-ref
          supabase_access_token: ${{ secrets.SUPABASE_ACCESS_TOKEN }}

Почему этому можно доверить ключ

Действию отдаётся приватный ключ Apple — так что проверяемость здесь важнее любых обещаний.

01
Ключ не покидает ваш репозиторий

Он лежит в секретах вашего же GitHub и используется внутри вашего запуска. Мне он не отправляется и отправляться некуда — сервера у этого действия нет.

02
Ноль зависимостей

Ни одной сторонней библиотеки: только то, что уже встроено в Node. Нечему обновиться и подменить содержимое за вашей спиной.

03
Вся логика — один файл

rotate.js читается целиком за несколько минут. Не верьте описанию — откройте и посмотрите, что он делает, до установки.

04
Лицензия MIT

Берите, меняйте, используйте в коммерческих проектах. Форкните и запускайте со своей копии, если так спокойнее.

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

Почему раз в 5 месяцев, а не в 6?

Предел Apple — около шести месяцев. Запуск раз в пять оставляет месяц запаса: если один прогон не состоится, вход не успеет сломаться.

Мой ключ .p8 в безопасности?

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

На вход в приложении на iPhone это влияет?

Нет. Родной вход в приложении секрет не использует — протухание касается только входа через сайт.

А если у меня не Supabase?

Тогда действие просто выдаёт готовый секрет, а вы подставляете его в свой сервис. Работает с Firebase, Auth0, своим сервером — с чем угодно.

Oskar Makarov

Автор

Оскар Макаров. Это не теория: я сам ловил этот отказ и написал обновление, чтобы не ловить его снова. Верить на слово не нужно — код открыт целиком, а листинг в Marketplace проверяется в один клик.

Бесплатно и навсегда. Если пригодится — загляните в Pipeline.md: он про такие же грабли, которые вылезают уже после запуска.

MIT · открытый код Pipeline.md →
финал

Поставьте
один раз —
и забудьте.

Взять в GitHub Marketplace → бесплатно · MIT · ноль зависимостей · настройка один раз
© 2026 Oskar Makarov ▍apple-client-secret-rotator · MIT