App Store Connect API 密钥(.p8):创建与使用
作者:Mehdi Azizi
发布于 ,10分钟
App Store Connect API 密钥(.p8)只能下载一次。本文讲清角色、Issuer ID、Key ID、撤销,以及在 Expo、fastlane 和脚本中的用法。
App Store Connect API 密钥能让一个工具(比如 EAS、fastlane、RevenueCat 或你自己的脚本)操作你的账号,不需要你的密码,也不需要双重认证。Apple 保存密钥的公钥部分,私钥部分是一个 .p8 文件,你只能下载一次。 有了这个文件、Issuer ID 和 Key ID,你就能签发令牌,大多数请求的令牌有效期最多 20 分钟。
我用 Expo 发布自己的 iOS 应用,包括 TradaZen 和 Nolera。一把 App Manager 角色的团队密钥同时供 RevenueCat、我的 Expo 构建,以及一个编辑商店页面的命令行工具使用。本指南依据 2026 年 11 月 3 日重新核对过的 Apple、Expo 和 fastlane 页面。别把它和塞进应用代码里的各类服务密钥搞混:那些内容见 Expo 应用中的秘密 API 密钥。
App Store Connect API 密钥是做什么的
根据 Apple 的文档,App Store Connect API 的每个请求都需要一个 JWT 令牌。令牌由你生成,并用你的私钥签名。这把密钥只能用于这个 API,不能用于 Apple 的其他服务。
它的价值一句话就能说清:不需要任何人来确认登录。 用 Apple ID 登录会卡在双重认证上,自动化就无从谈起。EAS Submit iOS 指南展示了它对 Expo 应用提交带来的改变。
第一步:申请 API 访问权限
第一把密钥不能直接创建。App Store Connect 帮助文档写得很明白:Account Holder 必须先申请 API 访问权限。 打开 Users and Access,点击 Integrations,再点 Request Access。Apple 会逐个审核申请。
Account Holder 就是注册这个账号的人。如果你是新手,那就是你自己:注册流程见 Apple 开发者账号指南。
团队密钥还是个人密钥
Apple 提供两种密钥。下面是它们的区别,整理自文档和 App Store Connect 帮助:
| 对比项 | 团队密钥 | 个人密钥 |
|---|---|---|
| 谁可以生成 | 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 的文档也证实:凡是涉及预配的访问,都需要团队密钥。
给密钥分配什么角色
团队密钥无论什么角色,都能访问账号下的所有应用。角色决定它能做什么。Apple 提醒,Admin 角色的密钥可以创建和删除用户:请分配能满足用途的最小角色。下面的权限来自 Apple 的角色表。
| 密钥用途 | 允许的角色 |
|---|---|
| 上传构建 | Admin、App Manager、Developer |
| 管理 TestFlight 构建 | Admin、App Manager |
| 创建证书和描述文件 | Admin、App Manager |
| 提交应用审核 | Admin、App Manager |
| 导入产品和价格(RevenueCat) | 至少 App Manager |
| 生成其他团队密钥 | Admin |
RevenueCat 那一行来自它的文档。而 Expo 的指南给密钥分配的是 Admin 角色。在我的应用上,App Manager 就够了:EAS 用它创建分发描述文件,RevenueCat 用它导入产品。
密钥生成后,名称和角色都不能再修改。想改,只能撤销后重新生成一把。
一步步创建团队密钥
你需要 Admin 或 Account Holder 账号。根据 Apple:
- 打开 Users and Access,然后进入 Integrations 标签页。
- 在左栏选择 App Store Connect API,然后进入 Team Keys 标签页。
- 点击 Generate API Key,或者点 + 按钮。
- 给密钥起个名字。 名字只给你自己看,不属于密钥本身。按使用它的工具来命名。
- 在 Access 下选择角色,然后点击 Generate。
- 通过 Download API Key 链接下载私钥。
文件一下载完,下载链接就会消失,Apple 也不保留任何副本。关闭页面前先把
.p8存好。
然后记下两个标识。根据 Apple 关于令牌的页面,Issuer ID 显示在 Integrations 页面顶部,旁边有 Copy 按钮。Key ID 在有效密钥列表里:鼠标悬停就会出现 Copy Key ID。账号下所有团队密钥的 Issuer ID 都相同,Key ID 则每把密钥各不相同。
个人密钥更简单:打开你的用户资料,往下滚到 Individual API Key,点击 Generate API Key。同样只能下载一次。
保管 .p8 文件
Apple 要求像对待密码一样对待这把密钥:不要分享,不要放进代码仓库,绝不要写进应用代码。 我的做法:
- 放在项目之外的文件夹,或者放进持续集成工具的密钥管理器。
- 把密钥文件夹加进
.gitignore,如果提交期间文件必须暂时放在项目里。 - 严格的文件权限。 有个 App Store Connect 命令行工具,只要我的
.p8还能被其他账户读取,就拒绝使用它。一条chmod 600解决了问题。 - 一个工具一把密钥。 Apple 允许生成多把密钥,角色随你选。
最后这一条,我一开始没做到。我那把 App Manager 密钥同时给 RevenueCat、构建和商店页面工具用。要是得撤销它,三个工具会一起挂掉。如果重来,我会一个工具建一把密钥,这样能单独停掉一把而不影响其他的。
在 Expo 中使用
把密钥交给 EAS 有三种方式:
- 交给 EAS 管理。
eas credentials --platform ios可以创建密钥并保存在 Expo 的服务器上。这是最简单的路。 - 在
eas.json中声明。submit配置接受ascApiKeyPath、ascApiKeyIssuerId和ascApiKeyId。根据 eas.json 参考文档,这些字段支持环境变量,比如$ASC_API_KEY_PATH。 - 通过环境变量传入。 EAS CLI 仓库记录了
EXPO_ASC_API_KEY_PATH、EXPO_ASC_KEY_ID和EXPO_ASC_ISSUER_ID。个人密钥省略 Issuer ID 即可。
构建时有个限制要知道:Expo 说明官方 API 无法关联 App Group、Merchant ID 或 CloudKit 容器。这时需要在本地用你的 Apple ID 登录。我在 Nolera 的小组件 App Group 上就遇到过:密钥启用了这项能力,却没关联上分组。我是在 Apple 开发者网站里手动关联的。如果能力同步卡住,EXPO_NO_CAPABILITY_SYNC=1 可以关闭它,然后你自己在 App ID 上启用这项能力。构建签名的细节见 iOS 证书与描述文件。
在 fastlane 中使用
fastlane 从一个 JSON 文件读取密钥。key_id、issuer_id 和 key(即 .p8 的内容)是必填字段,duration 和 in_house 可选。示例值:
{
"key_id": "XXXXXXXXXX",
"issuer_id": "your-issuer-id",
"key": "-----BEGIN PRIVATE KEY-----\nMIGT...\n-----END PRIVATE KEY-----",
"duration": 1200,
"in_house": false
}
然后把这个文件传给某个 action,例如 fastlane pilot distribute --api_key_path fastlane/cle.json。在 Fastfile 中,app_store_connect_api_key action 接受 key_id、issuer_id 和 key_filepath。会话时长不超过 1200 秒,也就是 20 分钟。并非所有 action 都支持:比如 fastlane 指出 produce 和 pem 无法使用 API 密钥。
在你自己的脚本中使用
不借助工具的话,令牌得自己生成。Apple 规定了做法:
- 头部:
alg为ES256,kid为你的 Key ID,typ为JWT。 - 载荷(团队密钥):
iss为你的 Issuer ID;iat为创建时间;exp为过期时间;aud为appstoreconnect-v1。 - 载荷(个人密钥):用
sub取代iss,值为user。 - 时长:超过 20 分钟,大多数请求的令牌会被 Apple 拒绝。
用 Python 的话,需要 PyJWT 库及其加密依赖,按它的文档用 pip install pyjwt[crypto] 安装。在 Mac 终端里要加引号:pip install "pyjwt[crypto]",否则 zsh 不认方括号。
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)
然后像 Apple 的示例那样,把它放进 Authorization 请求头发送:
curl -H "Authorization: Bearer $TOKEN" "https://api.appstoreconnect.apple.com/v1/apps"
2026 年 11 月 3 日,我用本机生成的一次性密钥运行了这个脚本:令牌的头部和载荷与 Apple 页面一致,ES256 签名也能验证通过。我没有用这把测试密钥去请求 Apple 的 API,因为 Apple 那边并不存在这把密钥。令牌有效期内请重复使用同一个令牌:Apple 建议这样做以获得更好的性能。
撤销密钥
密钥一旦丢失、泄露,或者某个工具不再使用它,就立刻撤销。根据 App Store Connect 帮助,使用 Account Holder 或 Admin 账号:
- 打开 Users and Access,然后进入 Integrations。
- 选择 Team Keys 或 Individual Keys,然后点击 Edit。
- 勾选要撤销的密钥,然后点 Revoke Key。
- 点 Revoke 确认。
被撤销的密钥永远无法重新启用。 Apple 会在 Revoked 下显示它 30 天。之后所有用它的工具都会认证失败。在 Expo 中,报错信息是“App Store Connect rejected the API authentication credentials”。这条信息和其他提交失败的原因,见 EAS 提交错误及其解决方法。如果密钥没有泄露,先准备好新密钥再停用旧的。如果已经泄露,Apple 要求立即撤销。
撤销你自己的个人密钥:你的用户资料,Individual API Key,然后 Revoke。
我的 .p8 密钥检查清单
- Account Holder 已申请 API 访问权限。
- 用于构建或描述文件的,是团队密钥。
- 角色是满足用途的最小角色,名字标明了使用它的工具。
.p8存放在仓库之外,权限严格,并有一份加密备份。- Issuer ID 和 Key ID 另外记录,不和文件放在一起。
- 每个工具各用一把密钥,可以单独撤销。
自动化发布,又不暴露密钥
密钥只是整个流程中的一环。iOS & Android Kit 以我自己应用的起步代码为基础(包括订阅),分四个阶段带你走到 App Store,节奏由你掌握。如果你要用这把密钥接入 RevenueCat,完整配置见 RevenueCat 与 iOS 应用内订阅。
如果你正在准备第一次上架,做一下免费诊断:它会告诉你真正卡住你的是什么,并把我的防 Apple 拒审清单发给你。在 App Store 上发布应用页面梳理了每一步,从商店页面到审核通过。
常见问题
如何创建 App Store Connect API 密钥?
先由 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 不允许修改名称或角色。撤销它,再用正确的角色生成一把新的。
App Store Connect API 密钥会过期吗?
Apple 的页面没有提到密钥会过期,只提到撤销。会过期的是用它签发的令牌,大多数请求的令牌最长 20 分钟后过期。

