Skip to content

Commit a0f6912

Browse files
authored
feat: add support for individual API keys (Xcode 26 supported feature) (#246)
1 parent 5af3ec0 commit a0f6912

File tree

4 files changed

+21
-15
lines changed

4 files changed

+21
-15
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ await notarize({
8282
Alternatively, you can also authenticate via JSON Web Token (JWT) with App Store Connect.
8383

8484
You can obtain an API key from [App Store Connect](https://appstoreconnect.apple.com/access/integrations/api).
85-
Create a **Team Key** (not an _Individual Key_) with **App Manager** access.
85+
Create a **Team Key** with **App Manager** access.
8686

8787
Note down the Issuer ID (UUID format) and Key ID (10-character alphanumeric string),
8888
and download the `.p8` API key file (`AuthKey_<appleApiKeyId>.p8`).
@@ -100,6 +100,8 @@ await notarize({
100100
});
101101
```
102102

103+
You can alternatively use an [individual API key](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api#Generate-an-Individual-Key) if (and only if) you are using Xcode 26+. When using an individual API key, it is imperative that you omit `appleApiIssuer` (issuer ID); otherwise you will receive a "401 Unauthorized" response from the server.
104+
103105
### Usage with Keychain credentials
104106

105107
As an alternative to passing authentication options, you can also store your authentication

src/notarytool.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,18 @@ function authorizationArgs(rawOpts: NotaryToolCredentials): string[] {
3030
makeSecret(opts.teamId),
3131
];
3232
} else if (isNotaryToolApiKeyCredentials(opts)) {
33-
return [
34-
'--key',
35-
makeSecret(opts.appleApiKey),
36-
'--key-id',
37-
makeSecret(opts.appleApiKeyId),
38-
'--issuer',
39-
makeSecret(opts.appleApiIssuer),
40-
];
33+
// --issuer is an optional argument as it must not be provided if using an Individual key; Individual keys can only be used with Xcode 26+
34+
if (opts.appleApiIssuer) {
35+
return [
36+
'--key',
37+
makeSecret(opts.appleApiKey),
38+
'--key-id',
39+
makeSecret(opts.appleApiKeyId),
40+
'--issuer',
41+
makeSecret(opts.appleApiIssuer),
42+
];
43+
}
44+
return ['--key', makeSecret(opts.appleApiKey), '--key-id', makeSecret(opts.appleApiKeyId)];
4145
} else {
4246
// --keychain is optional -- when not specified, the iCloud keychain is used by notarytool
4347
if (opts.keychain) {

src/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ export interface NotaryToolApiKeyCredentials {
4444
appleApiKeyId: string;
4545
/**
4646
* App Store Connect API Issuer ID. The issuer ID is a UUID format string
47-
* (e.g. `c055ca8c-e5a8-4836-b61d-aa5794eeb3f4`).
47+
* (e.g. `c055ca8c-e5a8-4836-b61d-aa5794eeb3f4`). Required for Team keys.
48+
* Do not provide for Individual keys, this will result in a "401 Unauthorized"
49+
* response from the server.
50+
*
51+
* Individual keys can only be used with Xcode 26+.
4852
*/
49-
appleApiIssuer: string;
53+
appleApiIssuer?: string;
5054
}
5155

5256
/**

src/validate-args.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ export function validateNotaryToolAuthorizationArgs(
6969
throw new Error(
7070
'The appleApiKey property is required when using notarization with ASC credentials',
7171
);
72-
} else if (!apiKeyCreds.appleApiIssuer) {
73-
throw new Error(
74-
'The appleApiIssuer property is required when using notarization with ASC credentials',
75-
);
7672
} else if (!apiKeyCreds.appleApiKeyId) {
7773
throw new Error(
7874
'The appleApiKeyId property is required when using notarization with ASC credentials',

0 commit comments

Comments
 (0)