How to create an App Store Connect API key

Go to Users and Access → Integrations → App Store Connect API → Team Keys in App Store Connect, click , name the key, give it the App Manager role, then copy the Issuer ID, copy the Key ID from the new row, and click Download API Key. Those three things, Issuer ID, Key ID, .p8 file, are what every tool means when it asks for "App Store Connect API credentials".

You need to be the Account Holder or an Admin to create a team key. If you cannot see the Integrations tab, that is why.

What the three values actually are

They are not three passwords. They are three parts of one signature.

The .p8 file is a private key, an ECDSA P-256 key in PKCS#8 form, which is where the extension comes from. Nothing you send to Apple contains this file. Your tooling uses it to sign a short-lived JSON Web Token, and Apple verifies that signature against the public half it kept. It is roughly 250 bytes of base64 between -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----.

The Key ID is a 10-character code that tells Apple which public key to check the signature against. It goes in the JWT header as the kid claim. It is not secret; it is an index.

The Issuer ID is a UUID identifying your App Store Connect team, and it is the same for every team key you ever create. It goes in the JWT payload as iss, and it tells Apple whose account the request belongs to. Also not secret.

So the security boundary is entirely the .p8. The other two are labels.

One detail that catches people out: the token your tool signs is valid for at most 20 minutes. Apple rejects a token whose exp is further than that in the future. That is a property of the token, not of the key, App Store Connect API keys themselves have no expiry date and will keep working until you revoke them.

Which role to grant

The role you pick at creation decides what the key can do, and it is a real decision, not a formality.

App Manager is the right answer for almost every tool. It covers app metadata, screenshots, versions, builds, TestFlight, submitting for review and replying to reviews. It does not cover creating or removing users, changing team-level agreements, or the finance and sales reports.

Admin adds user management and account-level settings. Give it to a key only if the key genuinely needs to manage people, which almost nothing does.

Developer is the common mistake. A Developer key connects fine, authentication succeeds, the API answers, and then fails the first time it tries to write a listing or push screenshots. The failure looks like a broken integration but is a permissions wall.

Marketing, Finance, Sales, Customer Support and Access to Reports exist for people, and are rarely what you want for automation. A key that only pulls sales reports is a sensible least-privilege case for Finance or Access to Reports.

The important constraint: a key's role cannot be changed after you create it. If you picked Developer, you do not fix it by editing the key. You create a second key with App Manager and swap the credentials over. Then revoke the old one.

Team Keys vs Individual Keys

Team Keys act as the team, with the role you assigned. They are not tied to any person's account, which is what you want for CI and for tools: nobody leaving the company breaks the pipeline.

Individual Keys act as you, inheriting your own user permissions rather than carrying a role of their own. They are useful for a script you run on your own machine and nowhere else. They are a bad fit for shared automation, because the key dies with the account.

If you are wiring up a build server, a submission tool, or anything a second person will ever touch, use a Team Key.

The .p8 downloads exactly once

Click Download API Key and you get AuthKey_XXXXXXXXXX.p8. That is your only chance. Apple does not store the private half, so the download link stops working and there is no "resend" flow, no support ticket that recovers it, and no way to regenerate the same key.

If you have lost it, the sequence is short and there are no clever alternatives:

  1. Revoke the key you cannot use. Leaving a live key you do not hold is strictly worse than having no key.
  2. Create a new key with the same role and name.
  3. Download the new .p8 immediately, before you close the tab.
  4. Update the Key ID everywhere. The Issuer ID does not change. It is team-wide, so only the Key ID and the file need swapping.

Store the file the moment you get it. A password manager entry with the file attached, or a secrets manager, or your CI provider's secret store. Not your Downloads folder, and not the repo.

Rotating and revoking

Revoking is immediate and irreversible: the row gets a Revoke action, and every token signed with that key stops working from then on. There is no grace period and no undo, so revoke after the replacement is live, not before, unless the key is compromised, in which case revoke first and repair the pipeline second.

A sensible rotation is: create the new key, update the secret in CI, run one job to prove it works, then revoke the old key. Because keys never expire on their own, nothing forces this on a schedule, which is exactly why it is worth putting a reminder in the calendar.

Telling an expired token from a permissions problem

These fail differently, and the difference tells you which one you have.

Authentication failures come back as HTTP 401. Something is wrong with the token itself: the .p8 does not match the Key ID, the Issuer ID has a typo, the token's exp is more than 20 minutes out, or, surprisingly often, the machine's clock is skewed enough that Apple sees the token as issued in the future. A 401 that started at 3am for no reason is usually clock drift or a copy-paste mangling the key's newlines.

Permission failures come back as HTTP 403. The token was fine; the key's role is not allowed to do this. The tell is that read calls succeed and writes fail. You can list your apps but not push a listing.

A third case looks like a permissions problem but is not: agreements. If the Paid Applications agreement is unsigned, some endpoints refuse regardless of the key's role, and only the Account Holder can fix it under Business (formerly Agreements, Tax, and Banking).

What a leaked key exposes

This is the part worth being blunt about. App Store Connect API keys cannot be scoped to a single app. A team key with App Manager can read and write metadata, upload and manage builds, invite TestFlight testers, and submit versions for review across every app on the team. There is no per-app restriction to hide behind.

So treat it like a production database credential:

  • Base64-encode the .p8 into a single-line CI secret rather than committing the file. Write it to a temp path at the start of the job and delete it at the end.
  • Never echo it. Mask it in log output.
  • Give CI its own key, named after the pipeline, so revoking it does not break a human's workflow.
  • Prefer one key per system over one key shared by four systems, when you need to revoke, you want the blast radius to be one thing.

If a key does leak, revoke it first. Then check Users and Access for keys you did not create, and look at recent version and TestFlight activity for anything you did not do.

AppSubmit stores the .p8 encrypted and verifies all three values against Apple the moment you paste them, so a typo fails at the connection screen instead of halfway through a submission, but the key itself is yours, created in your account, and you can revoke it without asking anyone.

Last reviewed 2026-08-17. Apple and Google change their rules without notice, so check anything decision-critical against their live documentation.