Sign apps with another certificate
The hub signs every package with its own Developer ID certificate. An entry can name another certificate instead. Use it for an app of another Apple team, such as one you publish for a client’s account. Or for an app that should carry a certificate of its own. Entries that name none keep the hub’s certificate.
1. Name it in the entry
Section titled “1. Name it in the entry”Give the certificate a label: up to 40 lowercase letters and digits, such as acme. The label id is reserved.
Several entries may share a label.
In tapster setup, open Optional extras → Certificates for single apps → Add a certificate. Choose a project, select Add an app-specific certificate and enter its label. Save certificate choice shows the entry change before proposing and merging it. Its upload form then opens here. Existing projects also have this selector under Projects → Configuration; choose Hub default to switch back later.
When adding a new project, choose its certificate in the add form. This also includes its macOS builds when the hub
has no default Apple credentials. Merge the hub entry, then upload the .p12 and any missing notarization key under
Optional extras before publishing. From a terminal, use tapster add --certificate acme for a new project.
You can also add certificate: <label> by editing each entry directly:
version: 1tap: you/tappackages: - name: mytool repo: you/mytool binaries: [mytool] assets: darwin-arm64: "mytool_{version}_darwin_arm64.tar.gz" - name: acmeapp repo: you/AcmeApp kind: app app: AcmeApp.app bundle_id: com.acme.AcmeApp assets: darwin-arm64: "AcmeApp-{version}.app.tar.gz" dmg: { name: "AcmeApp-{version}.dmg" } certificate: acmemytool signs with the hub’s certificate and acmeapp with the certificate acme. A certificate signs macOS code
only, so the entry needs a darwin-* asset. {team} in the app’s entitlements becomes the Team ID of its certificate.
For a manual edit, click Edit under Configuration and then Propose and merge. In a clone of the hub,
edit tapster.yml and commit it with the workflow change of step 2.
2. Store the certificate
Section titled “2. Store the certificate”Export it as a .p12 as in Get your Apple credentials. Store it before
the entry’s next release. Until then the hub publishes no release of that entry and says
<name> signs with the certificate <label>, which this hub has not stored.
In tapster setup, open Optional extras. Under Certificates for single apps, each label of the hub’s
tapster.yml on main has a card. Click Store this certificate, drop the .p12 and type its password. tapster
checks the file, stores it and passes the certificate to the hub workflow on main.
In a clone of the hub, with the label in its tapster.yml:
bunx @doguyilmaz/tapster init --certificate acmetapster names the entries that use the label, asks for the .p12 and its password and checks them. Then it adds the
certificate’s lines to the sign steps of .github/workflows/tapster.yml.
Review the workflow change, commit it with tapster.yml and push.
The hub workflow has to run a tapster that knows certificate:. An older one refuses the entries that name a
certificate. When init --certificate says the hub runs an older tapster, run tapster init --workflow too. In tapster
setup, update the workflow under Hub files when the certificates section asks for it.
3. The notarization key
Section titled “3. The notarization key”tapster notarizes a certificate’s code with an App Store Connect API key of the same team, so each team’s notarization history stays in its own account. Apple itself accepts a key of any team.
- A certificate of the hub’s team uses the hub’s notarization key. tapster asks for no other.
- A certificate of another team needs a key of that team. Create it in that team’s App Store Connect as in
Create an App Store Connect API key.
init --certificateasks for it right after the certificate. In tapster setup, its form opens on the certificate’s card.
To replace only that key:
bunx @doguyilmaz/tapster init --certificate acme --notaryWhen a label’s certificate moves to the hub’s team, tapster removes the key stored for that label if the hub has a
notarization key of its own. The hub’s key notarizes it from then on. When it moves to another team, tapster removes the
stored key too and asks for a key of the new team. Until you store it, that label’s releases fail with
the hub has no notary key for that team. A renewal within the same team keeps the label’s key.
What the hub stores
Section titled “What the hub stores”The names are the hub’s own with _<LABEL> at the end. For the label acme, the hub’s tapster environment holds:
| Name | Kind | What it holds |
|---|---|---|
MACOS_SIGN_P12_ACME |
secret | The .p12. |
MACOS_SIGN_PASSWORD_ACME |
secret | Its password. |
TAPSTER_TEAM_ID_ACME |
variable | The certificate’s Team ID. |
TAPSTER_CERT_EXPIRES_ACME |
variable | The day it expires. |
MACOS_NOTARY_KEY_ACME |
secret | The .p8 of another team’s key. |
MACOS_NOTARY_KEY_ID_ACME |
secret | Its Key ID. |
MACOS_NOTARY_ISSUER_ID_ACME |
secret | Its Issuer ID. |
The hub workflow passes the secrets to the steps that sign and notarize macOS code only. tapster doctor checks that
every label your entries name is stored, has a notarization key and reaches the workflow. In tapster setup, the
certificate’s card says Not in the workflow when the workflow on main does not pass it.
Renew it
Section titled “Renew it”Renew the certificate at developer.apple.com and export it again. In tapster setup, click Replace the certificate
on its card. In a clone of the hub, run init --certificate acme again. A key stored for the label stays when the
team stays the same. The hub’s issue and tapster doctor warn 30 days before a certificate expires.
Before you move an installed app
Section titled “Before you move an installed app”An app that users installed changes its code signature’s identity when it moves to a certificate of another team.
- macOS may ask users again for permissions they granted the app.
- An app that updates with Sparkle may change its team or its Sparkle key in one release, never both. Sparkle accepts a new team when the update carries the app’s Sparkle key. It accepts a new Sparkle key when the update carries the same Developer ID. See Rotate a Sparkle key.
