Trouble Generating Client Secret for Apple Sign-In Migration

We're preparing to migrate our Apple Sign-In users for an upcoming app transfer. Following this guide, we're currently stuck on the first curl command:

curl -v POST "https://appleid.apple.com/auth/token" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'scope=user.migration' \
-d 'client_id=CLIENT_ID' \
-d 'client_secret=CLIENT_SECRET_ISSUED_BY_TEAM_A'

Specifically, we're having issues generating the client secret, specified here.

We're using a Node.js script to generate the script; initially I realized that the private key I was signing the JWT with was wrong (I was using the App Store Connect API team key instead of a private key for use with Account & Organization Data Sharing).

Every time we try entering this curl command:

curl -v POST "https://appleid.apple.com/auth/token" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'scope=user.migration' \
-d 'client_id=com.jumbofungames.platMaker' \
-d 'client_secret=$(node clientsecret_jwt2.js)'

Where $(node clientsecret_jwt2.js) is the command to generate the client secret; we get this error:

< HTTP/1.1 400 Bad Request
< Server: Apple
< Date: Mon, 19 Aug 2024 15:41:31 GMT
< Content-Type: application/json;charset=UTF-8
< Content-Length: 49
< Connection: keep-alive
< Pragma: no-cache
< Cache-Control: no-store
<
* Connection #1 to host appleid.apple.com left intact
{"error":"invalid_client","email_verified":false}%

Here is the script we are using to generate the Client Secret (JWT), with some variables using placeholders for privacy:

const fs   = require('fs');
const jwt  = require('jsonwebtoken'); // npm i jsonwebtoken

// You get privateKey, keyId, and teamId from your Apple Developer account
const privateKey = fs.readFileSync("./AuthKey_ABCDEFG123.p8") // ENTER THE PATH TO THE TEAM KEY HERE (private key file)
const keyId = "API_KEY"; // ENTER YOUR API KEY ID HERE
const teamId = "TEAM_ID"; // ENTER YOUR TEAM ID HERE
const clientId = "com.companyname.appname"; // ENTER YOUR APP ID OR SERVICES ID HERE (This is the client_id)

// Time settings (in seconds)
let now = Math.round((new Date()).getTime() / 1000); // Current time (seconds since epoch)
let nowPlus6Months = now + 15776999; // 6 months from now (maximum expiration time)

let payload = {
    "iss": teamId, // The Team ID associated with your developer account
    "iat": now, // Issued at time
    "exp": nowPlus6Months, // Expiration time (up to 6 months)
    "aud": "https://appleid.apple.com", // Audience
    "sub": clientId // The App ID or Services ID
}

let signOptions = {
    "algorithm": "ES256", // Algorithm for signing (ECDSA with P-256 curve and SHA-256 hash algorithm)
    header : {
        "alg": "ES256", // Algorithm in the header
        "kid": keyId,   // Key ID in the header
        "typ": "JWT"    // JWT type
    }
};

// Generate the JWT (client_secret)
let clientSecret = jwt.sign(payload, privateKey, signOptions);
console.log(clientSecret);
module.exports = clientSecret;

If anyone has run into similar issues using this API or could shed some light on what could be going wrong, please let us know — we're at a bit of a loss here.

Answered by virusys in 800623022

The issue I was having with my client secret was that I was accessing it incorrectly with my curl command —

I had to change single quotes (``) to double quotes("") to get my client secret script to execute within the curl command properly:

curl -v POST "https://appleid.apple.com/auth/token"
-H 'Content-Type: application/x-www-form-urlencoded'
-d 'grant_type=client_credentials'
-d 'scope=user.migration'
-d 'client_id=com.jumbofungames.platMaker'
-d "client_secret=$(node clientsecret_jwt2.js)"

Accepted Answer

The issue I was having with my client secret was that I was accessing it incorrectly with my curl command —

I had to change single quotes (``) to double quotes("") to get my client secret script to execute within the curl command properly:

curl -v POST "https://appleid.apple.com/auth/token"
-H 'Content-Type: application/x-www-form-urlencoded'
-d 'grant_type=client_credentials'
-d 'scope=user.migration'
-d 'client_id=com.jumbofungames.platMaker'
-d "client_secret=$(node clientsecret_jwt2.js)"

Trouble Generating Client Secret for Apple Sign-In Migration
 
 
Q