# Ключ API App Store Connect (.p8): как создать и использовать

> Ключ API App Store Connect (.p8) скачивается только один раз. Роль, Issuer ID, Key ID, отзыв ключа и работа с ним в Expo, fastlane или своём скрипте.

Оригинальная страница: [Ключ API App Store Connect (.p8): как создать и использовать](https://devoria.fr/ru/blog/app-store-connect-api-key-p8)
Автор: [Mehdi Azizi](https://devoria.fr/ru/mehdi-azizi)
Опубликовано: 2026-11-04
Последняя правка контента: 2026-11-04


Ключ API App Store Connect позволяет инструменту вроде EAS, fastlane, RevenueCat или твоего собственного скрипта работать с аккаунтом без твоего пароля и двухфакторной аутентификации. **Apple хранит публичную половину ключа, а приватную половину, файл `.p8`, ты скачиваешь только один раз.** С этим файлом, Issuer ID и Key ID ты подписываешь токены, которые для большинства запросов действуют не дольше 20 минут.

Я публикую свои iOS-приложения, среди них TradaZen и Nolera, через Expo. Командный ключ с ролью App Manager у меня используется RevenueCat, моими сборками Expo и консольной утилитой, которая редактирует страницы приложений. Этот гайд опирается на страницы Apple, Expo и fastlane, которые я перечитал 3 ноября 2026 года. Не путай его с ключами сервисов, которые зашивают в код приложения: о них я писал в статье [секретный ключ API в приложении Expo](https://devoria.fr/ru/blog/sekretnyj-api-klyuch-expo-prilozhenie).

## Что делает ключ API App Store Connect

Согласно [документации Apple](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api), API App Store Connect требует JWT-токен для каждого запроса. Ты генерируешь его и подписываешь своим приватным ключом. Ключ работает только с этим API: для других сервисов Apple его использовать нельзя.

Главная польза умещается в одну фразу: **никому не нужно подтверждать вход.** Твой Apple ID упирается в двухфакторную аутентификацию, и это блокирует любую автоматизацию. В гайде [EAS Submit для iOS](https://devoria.fr/ru/blog/eas-submit-ios-publish-expo-app-store) видно, что это меняет при отправке приложения Expo.

## Сначала: запроси доступ к API

Первый ключ сразу не создать. [Справка App Store Connect](https://developer.apple.com/help/app-store-connect/get-started/app-store-connect-api) говорит прямо: **сначала Account Holder должен запросить доступ к API.** Он открывает Users and Access, нажимает Integrations, затем Request Access. Apple рассматривает каждый запрос отдельно.

Account Holder: это человек, который зарегистрировал аккаунт. Если ты новичок, то это ты. Регистрация подробно описана в гайде [аккаунт разработчика Apple](https://devoria.fr/ru/blog/akkaunt-razrabotchika-apple-cena).

## Командный ключ или индивидуальный

Apple предлагает два типа ключей. Вот их различия по [документации](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api) и [справке App Store Connect](https://developer.apple.com/help/app-store-connect/get-started/app-store-connect-api):

| Критерий                     | Командный ключ            | Индивидуальный ключ       |
| ---------------------------- | ------------------------- | ------------------------- |
| Кто может создать            | Account Holder или Admin  | Почти любой пользователь  |
| Доступные приложения         | Все, без исключения       | Приложения пользователя   |
| Права                        | Выбранная роль            | Права пользователя        |
| Количество ключей            | Несколько                 | Один активный на человека |
| Сертификаты и профили        | Да, в зависимости от роли | Нет                       |
| Продажи, финансы, notaryTool | В зависимости от роли     | Нет                       |
| Поле токена                  | `iss` = Issuer ID         | `sub` = `user`            |

«Почти любой пользователь», по словам Apple, означает: Account Holder, Admin, App Manager, Customer Support, Developer и Marketing, если только Admin или Account Holder не отнял у них право создавать индивидуальный ключ.

**Для Expo или fastlane выбирай командный ключ.** Индивидуальный ключ не имеет доступа к эндпоинтам provisioning, тем, что создают сертификаты и профили. [Документация fastlane](https://docs.fastlane.tools/app-store-connect-api/) это подтверждает: для всего, что связано с provisioning, нужны командные ключи.

## Какую роль дать ключу

Командный ключ видит все приложения аккаунта, какой бы ни была его роль. Роль определяет, что он может делать. **Apple предупреждает, что ключ с ролью Admin может создавать и удалять пользователей**: давай минимальную роль, которой хватает для твоей задачи. Права ниже взяты из [таблицы ролей Apple](https://developer.apple.com/help/account/access/roles/).

| Задача ключа                               | Подходящие роли               |
| ------------------------------------------ | ----------------------------- |
| Отправлять сборки                          | Admin, App Manager, Developer |
| Управлять сборками TestFlight              | Admin, App Manager            |
| Создавать сертификаты и профили            | Admin, App Manager            |
| Отправлять приложение на ревью             | Admin, App Manager            |
| Импортировать продукты и цены (RevenueCat) | Минимум App Manager           |
| Создавать другие командные ключи           | Admin                         |

Строка про RevenueCat взята из [его документации](https://www.revenuecat.com/docs/service-credentials/itunesconnect-app-specific-shared-secret/app-store-connect-api-key-configuration). А гайд Expo [даёт ключу роль Admin](https://github.com/expo/fyi/blob/main/creating-asc-api-key.md). В моих приложениях хватает роли App Manager: EAS создаёт с ней профили дистрибуции, а RevenueCat импортирует продукты.

После создания ключа [поменять его имя или роль уже нельзя](https://developer.apple.com/help/app-store-connect/get-started/app-store-connect-api). Чтобы что-то изменить, придётся отозвать ключ и создать новый.

## Создаём командный ключ по шагам

Нужен аккаунт Admin или Account Holder. Согласно [Apple](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api):

1. **Открой Users and Access**, затем вкладку Integrations.
2. **Выбери App Store Connect API** в левой колонке, затем вкладку Team Keys.
3. **Нажми Generate API Key** или кнопку +.
4. **Дай ключу имя.** Оно нужно только тебе и не входит в сам ключ. Называй ключ по инструменту, который будет его использовать.
5. **Выбери роль** в разделе Access, затем нажми Generate.
6. **Скачай приватный ключ** по ссылке Download API Key.

> Ссылка на скачивание исчезает сразу после того, как ты скачал файл, и Apple не хранит его копию. Убери `.p8` в надёжное место, прежде чем закрывать страницу.

Потом запиши два идентификатора. Согласно [странице Apple о токенах](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests), **Issuer ID показан вверху страницы Integrations**, рядом с кнопкой Copy. Key ID виден в списке активных ключей: наведи на него курсор, чтобы появилась кнопка Copy Key ID. Issuer ID один для всех командных ключей аккаунта. Key ID у каждого ключа свой.

С индивидуальным ключом всё короче: открой свой профиль пользователя, прокрути до Individual API Key и нажми Generate API Key. Скачать его тоже можно только один раз.

## Где хранить файл .p8

Apple просит обращаться с ключом как с паролем: **не делись им, не клади его в репозиторий и никогда не встраивай в код приложения.** Мои правила:

- **Папка вне проекта** или менеджер секретов твоего CI.
- **Папка с ключами в `.gitignore`**, если файлу нужно полежать в проекте на время отправки.
- **Строгие права доступа.** Одна консольная утилита для App Store Connect отказывалась принимать мой `.p8`, пока файл был доступен на чтение другим учётным записям. `chmod 600` решил проблему.
- **Отдельный ключ на каждый инструмент.** Apple позволяет [создавать несколько ключей](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api) с любыми ролями.

Последний пункт я поначалу не соблюдал. Мой ключ App Manager используется сразу RevenueCat, моими сборками и утилитой для страниц приложений. Если придётся его отозвать, упадут все три инструмента разом. **Если бы начинал заново, сделал бы по ключу на инструмент**, чтобы отключать один, не задевая остальные.

## Как использовать с Expo

Есть три способа передать ключ в EAS:

- **Доверить его EAS.** `eas credentials --platform ios` может создать ключ и хранить его на серверах Expo. Это самый простой путь.
- **Прописать его в `eas.json`.** Профиль `submit` принимает `ascApiKeyPath`, `ascApiKeyIssuerId` и `ascApiKeyId`. Согласно [справочнику по eas.json](https://docs.expo.dev/eas/json/), эти поля принимают переменные окружения, например `$ASC_API_KEY_PATH`.
- **Передать через окружение.** [Репозиторий EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/README.md) описывает `EXPO_ASC_API_KEY_PATH`, `EXPO_ASC_KEY_ID` и `EXPO_ASC_ISSUER_ID`. Для индивидуального ключа Issuer ID не указывают.

Одно ограничение для сборок: [Expo уточняет](https://docs.expo.dev/build-reference/ios-capabilities/), что официальный API не умеет привязывать App Group, Merchant ID или контейнер CloudKit. Тогда нужен вход с твоим Apple ID, локально. Я столкнулся с этим в Nolera с группой приложений для виджета: ключ включил capability, но группу не привязал. Привязку я сделал на портале разработчика Apple. **Если синхронизация capabilities мешает, `EXPO_NO_CAPABILITY_SYNC=1` её отключает**, и ты включаешь capability сам в идентификаторе приложения. Подпись сборок подробно разобрана в статье [сертификат и provisioning profile iOS](https://devoria.fr/ru/blog/ios-developer-certificate-provisioning-profile-expo).

## Как использовать с fastlane

[fastlane](https://docs.fastlane.tools/app-store-connect-api/) читает ключ из JSON-файла. Поля `key_id`, `issuer_id` и `key` (содержимое `.p8`) обязательны. `duration` и `in_house` необязательны. Значения условные:

```json
{
  "key_id": "XXXXXXXXXX",
  "issuer_id": "your-issuer-id",
  "key": "-----BEGIN PRIVATE KEY-----\nMIGT...\n-----END PRIVATE KEY-----",
  "duration": 1200,
  "in_house": false
}
```

Потом передаёшь этот файл действию, например `fastlane pilot distribute --api_key_path fastlane/cle.json`. В Fastfile действие `app_store_connect_api_key` принимает `key_id`, `issuer_id` и `key_filepath`. Сессия длится не больше 1200 секунд, то есть 20 минут. Не все действия поддерживают ключ: fastlane, например, указывает, что `produce` и `pem` с ключом API не работают.

## Как использовать в своём скрипте

Без инструментов токен собираешь сам. [Apple задаёт рецепт](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests):

- **Заголовок**: `alg` равен `ES256`, `kid` равен твоему Key ID, `typ` равен `JWT`.
- **Содержимое, командный ключ**: `iss`, твой Issuer ID; `iat`, время создания; `exp`, время истечения; `aud`, равный `appstoreconnect-v1`.
- **Содержимое, индивидуальный ключ**: `sub` равен `user` вместо `iss`.
- **Срок**: если больше 20 минут, Apple отклоняет токен для большинства запросов.

На Python, с библиотекой PyJWT и её криптографической зависимостью, которая ставится через `pip install pyjwt[crypto]` по [её документации](https://pyjwt.readthedocs.io/en/stable/installation.html). В терминале Mac ставь кавычки: `pip install "pyjwt[crypto]"`, иначе zsh не примет квадратные скобки.

```python
import time
import jwt

KEY_ID = "XXXXXXXXXX"
ISSUER_ID = "your-issuer-id"

with open("AuthKey_XXXXXXXXXX.p8") as f:
    private_key = f.read()

now = int(time.time())
token = jwt.encode(
    {"iss": ISSUER_ID, "iat": now, "exp": now + 20 * 60, "aud": "appstoreconnect-v1"},
    private_key,
    algorithm="ES256",
    headers={"kid": KEY_ID, "typ": "JWT"},
)
print(token)
```

Затем отправляешь его в заголовке `Authorization`, как в примере Apple:

```bash
curl -H "Authorization: Bearer $TOKEN" "https://api.appstoreconnect.apple.com/v1/apps"
```

Я запустил этот скрипт 3 ноября 2026 года с одноразовым ключом, созданным на моей машине: заголовок и содержимое токена совпадают со страницей Apple, а подпись ES256 проходит проверку. В API Apple я его с этим тестовым ключом не отправлял, ведь у Apple такого ключа нет. **Используй один и тот же токен, пока он действует**: Apple советует так делать ради производительности.

## Как отозвать ключ

Отзывай ключ сразу, если он потерян, скомпрометирован или больше не нужен ни одному инструменту. Согласно [справке App Store Connect](https://developer.apple.com/help/app-store-connect/get-started/app-store-connect-api), с аккаунтом Account Holder или Admin:

1. Открой Users and Access, затем Integrations.
2. Выбери Team Keys или Individual Keys, затем нажми Edit.
3. Отметь ключи для отзыва, затем Revoke Key.
4. Подтверди кнопкой Revoke.

**Отозванный ключ уже никогда не включить снова.** [Apple показывает его](https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys) 30 дней в разделе Revoked. Каждый инструмент, который его использовал, после этого не проходит аутентификацию. В Expo сообщение будет таким: «[App Store Connect rejected the API authentication credentials](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts)». Это сообщение и другие сбои отправки разобраны в статье [ошибки отправки через EAS и как их исправить](https://devoria.fr/ru/blog/eas-submit-ios-errors-fix). Если ключ не скомпрометирован, подготовь новый, прежде чем отключать старый. Если скомпрометирован, Apple просит отозвать его немедленно.

Для своего индивидуального ключа: профиль, Individual API Key, затем Revoke.

## Мой чек-лист по ключу .p8

- Account Holder запросил доступ к API.
- Ключ командный, если он нужен для сборок или профилей.
- Его роль минимальная для задачи, а имя говорит, какой инструмент его использует.
- `.p8` лежит вне репозитория, со строгими правами и зашифрованной резервной копией.
- Issuer ID и Key ID записаны отдельно, без файла.
- У каждого инструмента свой ключ, чтобы можно было отозвать только один.

## Автоматизируй публикацию и не потеряй ключ

Ключ: лишь одна деталь всего пути. [iOS & Android Kit](https://devoria.fr/ru/kits/ios) начинается со Starter Code моих приложений, подписки включены, и ведёт тебя через четыре этапа до App Store в твоём темпе. Если подключаешь RevenueCat с этим ключом, полная настройка описана в статье [RevenueCat и подписка in-app в iOS](https://devoria.fr/ru/blog/revenuecat-podpiska-ios-prilozhenie).

Если готовишь свой первый релиз, [пройди бесплатную диагностику](https://devoria.fr/ru/diagnostic): она покажет, что тебе реально мешает, и пришлёт мой чек-лист против отказов Apple. На странице [публикация приложения в App Store](https://devoria.fr/ru/expertise/publish-app-on-app-store) разобран каждый этап, от страницы приложения до одобрения.

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

### Как создать ключ API App Store Connect?

Сначала Account Holder запрашивает доступ к API. Затем Admin открывает Users and Access, вкладку Integrations, App Store Connect API, Team Keys. Он нажимает Generate API Key, выбирает имя и роль, создаёт ключ и скачивает файл `.p8`.

### Можно ли заново скачать потерянный ключ .p8?

Нет. Файл скачивается только один раз, и Apple не хранит его копию. Отзови потерянный ключ, создай новый и обнови каждый инструмент, который им пользовался.

### Где найти Issuer ID и Key ID?

В App Store Connect, в меню Users and Access, вкладка Integrations. Issuer ID показан вверху страницы. Key ID есть в списке активных ключей. Индивидуальный ключ Issuer ID не использует.

### Какую роль дать ключу для Expo?

Гайд Expo даёт роль Admin. По таблице ролей Apple, App Manager хватает, чтобы отправлять сборки и создавать сертификаты и профили. Именно такая роль у моего ключа, который работает с моими сборками Expo.

### Можно ли поменять роль ключа API?

Нет. Apple не позволяет менять ни имя, ни роль ключа после создания. Отзови его и создай новый с нужной ролью.

### Истекает ли срок действия ключа API App Store Connect?

На страницах Apple не говорится об истечении срока ключа, только об отзыве. Истекают токены, подписанные им: для большинства запросов не позже чем через 20 минут.


## Твой проект

[Review Kit](https://devoria.fr/ru/kits/app-review): Мой чек-лист для ревью в App Store, исправленные отказы Apple, чек-лист для Google Play и три скилла для Claude Code. 55 $.

[iOS & Android Kit](https://devoria.fr/ru/kits/ios): Создай своё приложение для iPhone и Android с Claude Code: стартовый код моих приложений, путь до публикации в сторах и все киты. 109 $.

[Диагностика: что отделяет тебя от твоего iPhone-приложения](https://devoria.fr/ru/diagnostic): 7 вопросов, 60 секунд: ты узнаешь, что на самом деле мешает тебе опубликовать iPhone-приложение, получишь путь из 4 этапов и подходящий тебе кит.
