{"registry_version":"2026.1025.387","generated_at":"2026-10-25T06:27:00Z","content_sha256":"089d16f627d9365e3d0663cc8069203706d7cb23a76c332226e29686968811a5","signed":true,"signature":{"key_id":"ed25519:74ca19268e364242","algorithm":"ed25519","expires_at":"2026-11-24T06:27:09Z","expired":false,"manifest":"/registry/manifest.json"},"entry_sha256":"788f3b7fb108c27c563cde4fb69e306d3c2f246f473ff98e96893b40ae08997c","entry":{"id":"apple/apns-keys","name":"Apple Push Notification service (APNs) auth key","vendor":"Apple","summary":"Create a token signing key (.p8) in your Apple Developer account so your server can send push notifications to your iOS, macOS, watchOS or tvOS apps over APNs using short-lived JSON Web Tokens instead of certificates.","aliases":["APNs","Apple push key","AuthKey p8","push notification key"],"category":"messaging","group":"B","homepage":"https://developer.apple.com/documentation/usernotifications/establishing-a-token-based-connection-to-apns","docs":["https://developer.apple.com/documentation/usernotifications/establishing-a-token-based-connection-to-apns","https://developer.apple.com/help/account/keys/create-a-private-key/","https://developer.apple.com/help/account/keys/revoke-edit-and-download-keys/"],"status":"researched","last_verified":null,"last_researched":"2026-10-25","sources":[{"id":"apns-token","url":"https://developer.apple.com/documentation/usernotifications/establishing-a-token-based-connection-to-apns","title":"Establishing a token-based connection to APNs","accessed":"2026-10-25","supports":"Team-scoped keys limited to Sandbox or Production, max two per environment; topic-specific keys max 200 per environment with up to 400 topics each; 10-character Key ID and Team ID; ES256 only; refresh tokens no more than once every 20 minutes and at least every 60 minutes; tokens older than one hour rejected (ExpiredProviderToken); one team per connection; revoke compromised keys; transferred apps need new connections.","kind":"official"},{"id":"create-key","url":"https://developer.apple.com/help/account/keys/create-a-private-key/","title":"Create a private key - Keys - Account - Help - Apple Developer","accessed":"2026-10-25","supports":"Steps to create a key with APNs enabled and choose environment and key type; saved as .p8; cannot be downloaded again; required role Account Holder or Admin.","kind":"official"},{"id":"manage-keys","url":"https://developer.apple.com/help/account/keys/revoke-edit-and-download-keys/","title":"Revoke, edit, and download keys - Keys - Account - Help - Apple Developer","accessed":"2026-10-25","supports":"A key can be downloaded only once; revoking makes it invalid and affects every service using it; required role Account Holder or Admin.","kind":"official"},{"id":"renewal","url":"https://developer.apple.com/help/account/membership/renewal/","title":"Renewal - Membership - Account - Help - Apple Developer","accessed":"2026-10-25","supports":"Expired membership loses access to Certificates, Identifiers & Profiles.","kind":"official"},{"id":"adpla","url":"https://developer.apple.com/support/terms/apple-developer-program-license-agreement/","title":"Apple Developer Program License Agreement","accessed":"2026-10-25","supports":"You must safeguard authentication credentials (keys, tokens) associated with your developer account and use them only as authorised.","kind":"official"}],"allowed_domains":["developer.apple.com"],"account_model":{"summary":"APNs keys live under the organisation's (or individual's) Apple Developer Program membership, in Certificates, Identifiers & Profiles. Only the Account Holder or an Admin can create, download or revoke them. A key signs tokens for the whole team (team-scoped) or for chosen topics (topic-specific).","accounts":[{"name":"Apple Developer Program membership","kind":"developer","owned_by":"the company (or individual developer)","required":true},{"name":"Account Holder or Admin user","kind":"personal","parent":"Apple Developer Program membership","required":true,"note":"Needed to create and download keys."}],"notes":["One APNs connection cannot serve several teams; open separate connection pools per developer account."]},"prerequisites":[{"entry":"apple/developer-program-org","note":"An active paid membership (an individual membership also works)."}],"have_ready":[{"kind":"other","description":"Account Holder or Admin access to the Apple Developer account.","why":"Required role for creating and downloading keys.","needed_for":["create-key","download-key"],"auto_check":"none","source":"create-key"},{"kind":"other","description":"A secure place to store the .p8 file (secret manager or vault) before you click Download.","why":"Apple keeps no copy; it can be downloaded only once.","needed_for":["download-key"],"auto_check":"none","source":"manage-keys"}],"steps":[{"id":"sign-in","title":"Sign in to Certificates, Identifiers & Profiles","summary":"Sign in to the Apple Developer account as Account Holder or Admin and open Keys.","route":"guided","depends_on":[],"gate":"2fa","url":"https://developer.apple.com/account/resources"},{"id":"create-key","title":"Create a key with APNs enabled","summary":"Click + under Keys, name the key, tick Apple Push Notification service and click Configure. Choose the environment (Sandbox or Production) and key type: team-scoped (any topic in the team, max two per environment) or topic-specific (chosen topics, max 200 per environment). Review and confirm.","route":"guided","depends_on":["sign-in"],"gate":"human_submit","url":"https://developer.apple.com/account/resources","recovery":[{"hiccup":"You cannot create another team-scoped key.","fix":"Each environment allows at most two team-scoped keys. Revoke an unused one (check nothing depends on it first) or use a topic-specific key.","source":"apns-token"}],"sources":["create-key","apns-token"]},{"id":"download-key","title":"Download the .p8 key once and store it safely","summary":"Click Download. The file AuthKey_<KEY_ID>.p8 lands in Downloads. Move it straight into your secret store; it cannot be downloaded again.","route":"guided","depends_on":["create-key"],"gate":"none","recovery":[{"hiccup":"The Download button is greyed out.","fix":"The key was already downloaded. If you no longer have the file, create a new key, switch your server to it, then revoke the old one.","source":"manage-keys"}],"capture":{"env":"APNS_PRIVATE_KEY","kind":"secret"},"sources":["create-key","manage-keys"]},{"id":"record-ids","title":"Record the Key ID and Team ID","summary":"Copy the 10-character Key ID shown for the key and your 10-character Team ID; the JWT header and claims need both.","route":"guided","depends_on":["create-key"],"gate":"none","sources":["apns-token"]},{"id":"wire-server","title":"Sign provider tokens on your server","summary":"Sign an ES256 JWT with kid = Key ID, iss = Team ID and iat = now. Reuse each token for 20-60 minutes; APNs rejects tokens older than one hour and errors if you change tokens more often than every 20 minutes on one connection. Use the sandbox endpoint for development builds and production for released apps.","route":"guided","depends_on":["download-key","record-ids"],"gate":"none","recovery":[{"hiccup":"APNs returns ExpiredProviderToken.","fix":"The token's iat is over an hour old; generate a fresh token and refresh at least every 60 minutes.","source":"apns-token"},{"hiccup":"APNs rejects pushes after you refresh tokens frequently.","fix":"Refresh no more than once every 20 minutes on the same connection; cache the token.","source":"apns-token"},{"hiccup":"Pushes to a newly added bundle ID or another team fail on an existing connection.","fix":"Add the topic to your team, then open new connections; a connection is bound to one team and its bundle IDs at first push.","source":"apns-token"},{"hiccup":"Pushes stop after an app transfer.","fix":"Close and recreate connections from your push server to APNs so they bind to the new team.","source":"apns-token"}],"sources":["apns-token"]}],"outputs":[{"name":"APNS_KEY_ID","description":"10-character Key ID of the APNs auth key (JWT kid header).","secret":false,"example_format":"ABC123DEFG","from_step":"record-ids"},{"name":"APNS_TEAM_ID","description":"10-character Apple Developer Team ID (JWT iss claim). Same value as APPLE_TEAM_ID.","secret":false,"example_format":"ABCDE12345","from_step":"record-ids"},{"name":"APNS_PRIVATE_KEY","description":"The .p8 token signing key (PEM text). Secret; never commit or send to clients.","secret":true,"example_format":"contents of AuthKey_<KEY_ID>.p8","from_step":"download-key"}],"terms_notes":[{"kind":"rules_say","severity":"red","title":"Guard the key","text":"You are fully responsible for safeguarding authentication credentials (keys, tokens) tied to your developer account. If you suspect a signing key is compromised, revoke it and create a new one; revoking breaks every service that uses it, so switch servers first.","source":"adpla"},{"kind":"rules_say","severity":"amber","title":"Membership lapse","text":"If your membership expires you lose access to Certificates, Identifiers & Profiles, so you cannot create or replace keys until you renew.","source":"renewal"}],"renewals":[{"what":"Provider authentication token (JWT) signed with the key; regenerate between 20 and 60 minutes","every":"60 minutes","source":"apns-token"}],"pricing_notes":{"notes":"Requires an Apple Developer Program membership to create keys. [to verify] Apple states no separate APNs charge on the pages read.","source":"create-key"},"api_provisioning":{"available":"no","notes":"Keys are created in Certificates, Identifiers & Profiles on the web. \"[to verify] whether the App Store Connect API exposes APNs key creation; not found in the pages read.\"","source":"create-key"},"notes":["[to verify] Whether APNs .p8 keys expire; Apple's pages read on 2026-10-25 describe revocation but no expiry.","Older team-scoped keys that work in both Sandbox and Production keep working, but Apple recommends environment-specific keys."]}}