Create certificates via App Store Connect API

Hello,


I am trying to create a certificate via App Store Connect API.


First, I created csr by the following command. I confirmed that the generated csr can be successfuly registered to developer.apple.com manually.


openssl genrsa 2048 > private.key
openssl req -new -key private.key -out private.csr -subj "/emailAddress=<my email address>/O=<my name>/C=JP"


Then, I tried to create a certificate using certificates API. The token is generated using an API key with Developer role (I tried also Admin and AppManager role and all are same).


curl -i \
  -H'Authorization: Bearer <token>' \
  -H'Content-Type: application/json' \
  -d '{"data":{"attributes":{"certificateType":"IOS_DISTRIBUTION","csrContent":"'$(cat private.csr | base64)'"},"type":"certificates"}}' \
  https://api.appstoreconnect.apple.com/v1/certificates


The response was:


HTTP/1.1 401 Unauthorized
Server: daiquiri/3.0.0
Date: Tue, 29 Oct 2019 03:31:38 GMT
Content-Type: application/json
Content-Length: 350
Connection: keep-alive
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Request-ID: QUKNKFNK2BDNPUUDIDEHJY7W
X-Rate-Limit: user-hour-lim:3600;user-hour-rem:3592;
x-daiquiri-instance: daiquiri:18493001:mr85p00it-hyhk03154801:7987:19N28

{
        "errors": [{
                "status": "401",
                "code": "NOT_AUTHORIZED",
                "title": "Authentication credentials are missing or invalid.",
                "detail": "Provide a properly configured and signed bearer token, and make sure that it has not expired. Learn more about Generating Tokens for API Requests https://developer.apple.com/go/?id=api-generating-tokens"
        }]
}


This error message says that my token is wrong or missing. Next, so I checked if the token is valid or not by invoking other API.


curl -i \
   -H'Authorization: Bearer <token>' \
   https://api.appstoreconnect.apple.com/v1/certificates


This API call succeeded and showed the list of my certificates.


Are there something wrong in my commands?

(I wonder that the api is not available currently...)



Appendix: my ruby script to generate jwt


require 'jwt'
require 'base64'
require 'optparse'

params = {}

opt = OptionParser.new
opt.on('-i val', '--iss') { |v| params[:iss] = v }
opt.on('-k val', '--kid') { |v| params[:kid] = v }
opt.parse!

private_key = STDIN.readlines.join
key = OpenSSL::PKey::EC.new(private_key)

payload = {
  iss: params[:iss],
  exp: Time.now.utc.to_i + 10 * 60,
  aud: 'appstoreconnect-v1'
}

header_fields = {
  "kid": params[:kid],
  "typ": 'JWT'
}

token = JWT.encode(payload, key, 'ES256', header_fields=header_fields)

puts token


Thank you.

Replies

Hey krtx,

I'm not sure if you've figured it out yet, but "csrContent" doesn't need to be encoded in base64. Doing just 'cat private.csr' should work.

Best,
  • -K

  • Does not work because it does not understand what is "----END" :)

Add a Comment

I was getting that error too initially - but realized it was my JWT creation/signing. Are you sure you're creating your JWT correctly? Either that or one of the values that go along with it (like issuerID or the keyid for example) is incorrect.