Certificates on Apple Developer

Everything Monopam can do with an Apple Developer account, standard or Enterprise Program: hold the API key, manage App IDs, issue code-signing certificates (Monopam makes the key, Apple signs it), take the certificates and provisioning profiles the account already holds into the inventory, regenerate profiles when a certificate renews, warn before the membership itself lapses, and install the finished signing identity into a build Mac's keychain. All over Apple's own API and SSH. No agent, nothing installed on Apple's side.

How it connects

HTTPS from the Monopam server itself: api.appstoreconnect.apple.com for a standard account, api.enterprise.developer.apple.com for an Apple Developer Enterprise Program account

How it authenticates

A short-lived token signed with your API key (.p8). No Apple ID, no password

What it issues

Code-signing certificates: seventeen of Apple's eighteen types on a standard account, one type per issuer

What it manages

App IDs (bundle identifiers) and provisioning profiles on the account

What it watches

Every certificate type the account holds, the profiles, and the program membership itself

Where it deploys

A build Mac's keychain over SSH, or a CI agent that pulls the identity itself

Before you start

You need an API key from the program your team is in, and the two are not interchangeable:

Your account

Where the key is created

What Monopam talks to

Standard (App Store Connect)

App Store Connect → Users and Access → Integrations

api.appstoreconnect.apple.com

Apple Developer Enterprise Program

developer.apple.com → Users and Access → Integrations (the Account Holder requests API access first)

api.enterprise.developer.apple.com

Apple states that an Enterprise Developer API key "can't be used for other Apple services", and the reverse holds as well. A key sent to the wrong one of those two addresses is refused with a message that sounds like a broken key, so the issuer has a Program field and it has to match where the key was made. Enterprise accounts have a page of their own: Apple Developer Enterprise Program with Monopam.

From that screen keep three things: the Issuer ID (a UUID, shown once per team), the Key ID, and the .p8 file. Apple lets you download the .p8 once, so if it has been lost, create a new key rather than looking for the old file.

The network rule is one outbound HTTPS destination and it belongs to the Monopam application server, not to a gateway: see Apple code signing: network requirements. Apple judges the token against its own clock, so keep time synchronisation running on that server.

Two things about Apple decide how the rest of this page reads:

What Apple does

What it means here

Apple stores the certificate and never the private key

A certificate created on somebody's Mac has its key in that Mac's keychain. Monopam can track and renew such a certificate, but can only deploy it after its .p12 is imported

A certificate is created for one certificate type

Apple requires the type on every certificate it creates, so an issuer that issues names one. An issuer that only watches and renews does not: set its type to Any type

Which certificate types are covered

Every Apple certificate type can be imported and watched. Almost all of them can also be issued and renewed here, in two groups:

Group

Types

What the issuer needs

Issued from the signing request alone

Apple Distribution, Apple Development, iOS Distribution, iOS Development, Mac App Distribution, Mac App Development, Mac Installer Distribution, Developer ID Application (and G2), Developer ID Kernel Extension (and G2)

Nothing beyond the API key

Issued against an identifier

Pass Type ID, Pass Type ID with NFC

A pass type identifier chosen on the issuer

Issued against an identifier

Apple Pay, Apple Pay Merchant Identity, Apple Pay PSP Identity, Apple Pay (RSA)

A merchant identifier chosen on the issuer

The identifiers themselves are created in the Apple Developer portal; Monopam reads the list off your account and binds the certificate to the one you pick. Because the choice lives on the issuer, renewals of those certificates run unattended like any other.

The single exception is IDENTITY_ACCESS, which appears in Apple's list with no documented way to create it. Certificates of that type are imported and watched like everything else. On an Enterprise Program account the list is shorter, and the Enterprise page above says how.

1. Add the Apple issuer, and see your accounts

Go to Certificates → Issuers → Add Issuer → Apple Developer.

Field

What it means

Required

Name

What this issuer is called in Monopam. Name it after the type it issues, because you will likely have more than one.

Required

Program

App Store Connect (standard account) or Apple Developer Enterprise Program. It decides which Apple API the key is sent to, so it must match where the key was created.

Required

Issuer ID

From Users and Access → Integrations in that program. One per team, a UUID.

Required

Key ID

The API key's own identifier, next to the key in the same screen.

Required

Certificate type

What this issuer asks Apple for, and what a renewal through it produces. Any type is the choice for an account you only want to watch and renew: see below.

Required

Pass type identifier / Merchant identifier

Appears only for the types issued against one. Press Load from Apple to fill the list from the account, then pick the identifier this issuer signs for.

Required for those types

Membership expires on

When the Apple Developer Program membership itself runs out, from Apple Developer → Membership details. See below.

Recommended

API key (.p8)

Choose the file or paste its contents. It is stored encrypted and never shown again; on a later edit, leaving it blank keeps the stored key.

Required on the first save

Require approval

Makes every issuance through this issuer wait for an approver, like any other issuer.

Optional

Why the certificate type is asked for at all, and when it is not. Apple requires it on every certificate it creates, so an issuer that will issue has to name one, and that is also what its renewals produce. An account whose certificates were all created elsewhere needs none of that: set Certificate type to Any type and the issuer takes in every certificate the account holds, whatever the type, and renews each one as the type it already is. Such an issuer cannot create a new certificate, and says so plainly if asked to.

Why the membership date is typed in by hand. When an Apple Developer Program membership lapses, everything it issued stops being trusted at once and no new certificate can be created. Apple announces it in the portal and by mail to the account holder, and publishes it in no API at all, so Monopam cannot discover it. Fill the date in and Monopam warns on the same thresholds and channels as a certificate (webhook, the e-mail digest and the audit trail), once per threshold, starting over when you change the date.

Press Test connection before saving. It signs a token and lists the account's certificates, changing nothing:

Connected to App Store Connect: 7 certificate(s) visible.

On an Enterprise issuer the same check answers Connected to the Apple Developer Enterprise Program: 7 certificate(s) visible.

Where the accounts live. The Issuers page opens with an Apple accounts panel: one card per Apple account, naming the program it belongs to, the key it holds, how long its membership has left, and how much depends on it (certificates, how many of those carry a private key, profiles, App IDs, and how many certificates expire within thirty days). Check connection on a card asks Apple whether the stored key still works, which is the one test that separates a lapsed membership or a revoked key from a network problem. An account whose membership date is empty says so on its card: that date is the only part of an Apple account Monopam cannot discover for itself.

Three things about an account's life are worth knowing, and none of them need a new issuer:

  • Rotating the API key. Create a new key in Users and Access → Integrations, edit the issuer and paste the new .p8 with its Key ID (leaving the field blank keeps the stored key), press Check connection, and only then revoke the old key at Apple. Certificates, profiles and App IDs already tracked are unaffected.

  • An expired membership. The account holder renews in the Apple portal; the same key then works again and nothing has to be re-created here. What does have to be redone is re-signing and redistributing whatever Apple invalidated, and the account card plus the inventory's Issued through filter say what that is. Afterwards, set Membership expires on to the new date so the reminders start over.

  • Removing an account. Deleting the issuer changes nothing at Apple. The certificates it issued stay in the inventory, without a renewal path until an issuer for that account exists again.

2. Bring the certificates the account already holds into Monopam

An Apple account that has been signing releases for years holds certificates nobody created in Monopam. On the issuer's row, press Import from Apple.

The list is what Apple holds today, next to what Monopam already has:

Column reads

What it means

Not here yet

Monopam has never seen this certificate. Importing creates an inventory row for it

Here, not linked

The certificate is already in the inventory (imported as a file, or found by a scan) but has no issuer. Importing attaches it to this issuer so it can be renewed here

Tracked

Already imported through this issuer. Watched for expiry, renewable, no private key

Managed

Already here with its private key, so it can also be deployed

tracked only under the type

The certificate is not this issuer's type, so it is watched but not renewable through it. An issuer set to Any type takes them all

Confirm, and the result says exactly what happened, for example:

4 certificate(s) imported, 1 already here and now linked to this issuer. An imported certificate has no private key (Apple never holds one): it is tracked and can be renewed through this issuer, and to deploy it, import the .p12 from the Mac that holds the identity.

An imported certificate is watched, not deployable. That is Apple's doing, not a limitation of the import: the private key never left the Mac that made the CSR. Two ways forward, and they can be combined:

  • You need it deployable now. On the Mac that holds the identity, export it as a .p12 (Keychain Access → export, or security export), then use Certificates → Inventory → Import with its password. Monopam matches it to the row already there by thumbprint, so no second row appears and the existing row gains its key.

  • You can wait for the renewal. Let the certificate renew through the issuer when it comes due. The renewal makes the new key inside Monopam, so from that point on the certificate is fully managed without anyone touching a Mac.

Finding them again. In Certificates → Inventory, the Issued through filter lists the issuers Monopam holds, with counts, plus No issuer for everything nothing here can renew. The filter beside it lists the kind of certificate (the Apple certificate type). The older issuer filter answers a different question: the authority named inside the certificate, which for all of these is Apple.

3. Issue a new signing certificate

Go to Certificates → Requests → Request, choose the Apple issuer, and submit. Monopam generates the keypair and the certificate signing request, sends the request to Apple, and stores the certificate Apple returns together with its private key.

The certificate type comes from the issuer, not from the request, and so does the pass type or merchant identifier when the type needs one. If the issuer has Require approval on, the request waits for an approver and is sent to Apple the moment it is approved.

Mind Apple's limits. An account may hold only a small number of active distribution certificates at a time, and they are shared by everyone on the team. Check what exists (step 2 lists it) before issuing another one.

4. App IDs

Certificates → App IDs holds the bundle identifiers your Apple accounts use. Every provisioning profile is made against one, so this is where you look before creating a profile and before removing anything.

  • Import from Apple lists what the account holds next to what Monopam tracks, and takes the chosen ones in. An App ID already tracked is refreshed rather than duplicated.

  • Create App ID registers one at Apple and tracks it here in the same step: Identifier (what a build signs with, dev.monofor.monoauth, or a wildcard dev.monofor.*), Name (Apple refuses punctuation here) and Platform (Universal, iOS or macOS).

  • The trash icon removes it from the Apple account and from Monopam. Apple refuses while a provisioning profile still uses it, and that refusal is shown as Apple words it.

Each row answers the two questions an App ID raises:

Column

What it tells you

Capabilities

What Apple has switched on for it (push notifications, app groups and the rest). Read-only here: capabilities are changed in the Apple Developer portal, which is where their consequences are explained

Used by

The provisioning profiles Monopam tracks against that identifier, and the certificate each one signs with. This is what breaks if the App ID goes away

A profile is matched to an App ID by its bundle identifier, so a profile that has not been imported yet does not appear in Used by; the import list also shows Apple's own profile count per App ID, so the two can be compared.

5. Provisioning profiles

Certificates → Profiles tracks .mobileprovision profiles as objects of their own, with their bundle ID, type, bound certificate and expiry. There are three ways in:

  • Import from Apple lists the profiles the account already holds, with their bundle ID, type, expiry and the certificate each one carries, and takes the chosen ones in. This is the one to start with on an established account. A profile is recognised by its UUID, so importing the same one again refreshes the tracked row instead of creating a second one.

  • Upload profile takes a .mobileprovision file you already have. Monopam reads its name, UUID, bundle ID, type and expiry out of the file, and you can link it to the certificate it was built for.

  • Create via Apple creates one in the account: the Apple issuer, a name, an existing Bundle ID (step 4), the profile type (iOS App Store, iOS Ad Hoc, iOS Development, iOS In-House for Enterprise accounts, Mac App Store) and the certificate to bind. Development and ad-hoc profiles also take Device IDs: type the device UDIDs, and a device Apple does not know yet is registered automatically.

The binding is what matters. An imported profile is bound to the certificate it carries by matching Apple's serial number against the inventory. A profile whose certificate is not in Monopam is still imported and watched for expiry, and the result says so:

10 profile(s) imported. 2 of them carry a certificate that is not in the inventory, so they are watched for expiry but will not follow a renewal: import that certificate from the Apple issuer to bind them.

Import that certificate (step 2) and import the profiles again: they are matched by UUID, so nothing is duplicated and the binding is filled in.

Regenerate re-issues a profile whose devices or certificate changed. The device list is read from the live profile first, so it is carried over.

6. What a renewal does to the profiles

When a certificate renews, the profiles bound to it are regenerated automatically: Monopam re-points each one at the new certificate, deletes the old profile at Apple and creates a fresh one for the same bundle ID and the same devices, then refreshes the tracked row from the new file. Nobody has to open the Apple portal.

Two details to plan around:

  • The profile gets a new UUID, because Apple does not update a profile in place. Anything that pins the old UUID has to be updated, which is why the row shows it.

  • Only Apple-managed profiles can be regenerated, meaning the ones Monopam created or imported from Apple. A profile that was uploaded as a file has no object on Apple to recreate, so it stays as it is and the row marks it Certificate renewed: upload the profile built for the new certificate.

7. Put the signing identity on a build Mac

Open the certificate, go to its Deployment tab, Add Target, and set Server Type to macOS Keychain. The target needs the certificate's private key, so it is offered for certificates Monopam holds fully.

Field

What it means

Resource / credential

The Mac and the SSH credential to reach it. The connection goes out through a gateway

Keychain

Default ~/Library/Keychains/login.keychain-db. Use a dedicated keychain on a shared machine

Keychain password

The password that unlocks that keychain. A literal value, or a Vault reference such as {{Vault.<name>.Password}}

Set partition list

On by default. This is what stops codesign asking for permission, which on a headless build agent looks like a hang. It needs the keychain password

The deployment copies the identity to the Mac, runs security import into the chosen keychain, sets the partition list, and removes the file it copied.

Imported into the keychain on buildmac.example.com (partition list updated).

Verify on the Mac with security find-identity -v -p codesigning: the identity is listed.

The alternative: let the build agent pull it. When the Mac is a CI runner that Monopam should not log into, create a Vault access key, link it to that certificate, and have the runner fetch the identity itself:

curl -s -X POST https://pam.example.com/api/v1/vault/certificate/<certificate-id>/pfx \
  -H "MonoPam-Vault-Access-Key: <secret>" \
  -H "Content-Type: application/json" \
  -d '{"password":"<export password, at least 8 characters>"}' -o signing.p12

The key reaches only the certificates it is explicitly linked to, its IP allow-list applies, and every pull is audited. No administrator session is involved.

8. Renewals end to end

An Apple certificate renews like any other issuer-linked certificate: Monopam builds a fresh key and request, Apple issues the new certificate, the old row is archived with the lineage kept, targets with Automatically deploy when the certificate renews follow it, and bound provisioning profiles are regenerated as described above. An issuer set to Any type renews each certificate as the type it already is, and a Pass Type ID or Apple Pay certificate carries the issuer's identifier, so both renew unattended.

After a renewal, three things are worth a look: the build Mac actually received the new identity (or the CI runner pulled it), the regenerated profiles' new UUIDs are in whatever pins them, and the old certificate stays in place until every consumer has moved, since both are valid until the old one expires.

When something goes wrong

What you see

What it means

HTTP 401 Provide a properly configured and signed bearer token, and make sure that it has not expired.

Apple's one answer for every refused token. Four things cause it: the key belongs to the other program (Enterprise key against App Store Connect or the reverse), the Issuer ID and Key ID are not from the same key, the key was revoked or replaced, or this server's clock drifted. Monopam adds which of the last two it can tell. Start with the issuer's Program field

This server's clock is 200 seconds ahead of Apple's...

Time synchronisation on the Monopam server. Apple judges the token's timestamps against its own clock

Everything Apple stopped working at once, and the portal says the membership expired

The Apple Developer Program membership lapsed: certificates it issued are no longer trusted and no new one can be created. Renewal is the account holder's to do in the portal; the account card in Issuers says what depended on it

The account card says the membership expiry is not recorded

Nothing is wrong, but nothing will warn you either. Fill Membership expires on from Apple Developer → Membership details

Connected to App Store Connect: 0 certificate(s) visible.

The key works but sees nothing. Usually a key created in the wrong team, or one whose role may not read certificates

Could not sign the App Store Connect token; check the .p8 key.

The .p8 content is truncated, re-wrapped or is not the key file. Paste it whole, including the BEGIN PRIVATE KEY lines

HTTP 403 ...

The key is valid but its role may not create certificates or manage App IDs

Most imported certificates say tracked only

The issuer has one certificate type and the account holds several. Import again through an issuer set to Any type

This issuer has no certificate type, so it can renew certificates it already knows but cannot create a new one.

An Any type issuer was asked to issue a new certificate. Add an issuer with the type you want to issue

An App ID will not delete

Apple refuses while a provisioning profile still uses it. The App ID's Used by column names the profiles; remove them first

An App ID will not create

Apple refuses punctuation in the name, and an identifier already registered anywhere in Apple cannot be taken

An App ID shows no profile here although Apple lists profiles for it

Those profiles have not been imported yet. Import them in Certificates → Profiles, and the relationship appears

This Apple account has no pass type identifiers. Create one in the Apple Developer portal first.

The account has nothing of that kind yet

An imported certificate refuses every deploy

It has no private key, which Apple never hands out. Import its .p12 from the Mac that holds the identity

Imported profiles show no certificate

The certificate they carry is not in the inventory. Import it from the issuer, then import the profiles again

A profile still names the old certificate after a renewal

It is an uploaded profile, which has no Apple object to recreate. Build it again and upload it, or import it from Apple

security import failed on the build host.

Wrong keychain path, a locked keychain, or a keychain password that is not the login password

codesign still prompts on the build agent

The partition list was not set, because the target had no keychain password

Nothing reaches Apple at all

The firewall rule was written for a gateway. The call leaves the Monopam application server; from that host, curl -o /dev/null -w "%{http_code}" https://api.appstoreconnect.apple.com/v1/certificates answering 401 means the path is open (use the enterprise address for an Enterprise account)

What this integration does not do

  • It does not fetch private keys from Apple, because Apple does not have them.

  • It does not switch an App ID's capabilities on or off, and it does not create pass type or merchant identifiers. Those are done in the Apple Developer portal; Monopam reads them and works against them.

  • It does not revoke certificates at Apple. Revoke in the Apple Developer portal, then archive or delete the Monopam row.

  • It does not read the membership expiry from Apple, because no Apple API exposes it. The date is entered on the issuer and watched from there.

  • It does not renew the membership, add people to the Apple account or change their roles. Those live in the Apple portal with the account holder.

  • It does not notarize builds, upload releases or run xcodebuild.

  • It does not distribute provisioning profiles to devices. It tracks them, creates them and hands them over; installing them is the build system's job.

  • It never signs in with an Apple ID. Authentication is the API key alone, so no Apple ID and no two-factor prompt is involved.


Monopam Certificate Manager. Addresses, names and identifiers on this page are examples.

Related: Apple Developer Enterprise Program with Monopam · Apple code signing: network requirements

Device guides: F5 BIG-IP · FortiManager · NetScaler · Panorama · Apple Developer