I'm the Team Agent for our company's Apple App Store Development account. Our company is large enough that I do not have any interactions with most of the people with Apple accounts. After running the account for a few years, I needed a way to remove employees who had left the company from the App Store Development account account.
Unfortunately Apple does not provide any means of doing a federated login. When an employee leaves our company, their email account is deactivated. But they can still login into AppConnect.com. For security reasons, it makes sense to remove their access to that account when they leave the company.
When an employee leaves the company, our HR department contacts our IT department as part of the off-boarding process. I'm not in IT or HR, I don't have any exposure to when an employee leaves the company.
But I can make it easier for our IT people by giving them a way to see if an employee needs to be removed. They can run "python IsUserInApple.py some.email@company.com" and it will tell them if that employee has in our Apple App Store Development account (or not).
Apple has a REST API for App Store Connect. You call the correct endpoint and pass in a signed JWT and Apple will send back a JSON result set. For this tool, we use the List Users web service endpoint to get the list of users in the account.
By default, Apple limits the number of objects returned via the App Connect API to 100 objects. You can increase that to 200 by appending "&limit=200" to the API call. What they don't appear to document anywhere is that there is a simple way of getting all of the records. In the JSON result set returned by the API, there is a "links" object. It will a "self" field that contains the URL that was used to make the call. It can have an optional "next" field will contain a URL that will return the next set of objects. When you call the API, you will need to check the "next" field and call that URL until you no longer receive another "next" field in the JSON result set.
This is written in Python 3. It was written and tested on Windows, but it should run on MacOS and Linux. There are also C# and Go versions of this code. It requires a configuration file named IsUserinApple.config located in the same folder as the .py file. This file should look like this:
[settings]
private_key = path/to.your/privatekey.p8
KEY_ID = ABCDEF1234
ISSUER_ID = d88b7c23-4c26-48fb-9d62-5649f27a25a2
The values are
Field | Value |
---|---|
PrivateKeyFile | The full path and filename to the private key file |
KeyID | Your private key ID from App Store Connect |
IssuerID | Your issuer ID from the API Keys page in App Store Connect |
You'll need to create an API key to sign the the JWT and authorize the API requests. To create a new key, follow these steps:
- Log in to App Store Connect.
- Select Users and Access, and then select the Keys tab. Copy the Issuer ID, you'll need it later.
- Click the "+" button to add a new key. Fill in the Name field and set the Access to "Admin".
- Download the private key file. You'll want to make a secure copy of the private key file, this will be the only time that you can download it.
After you create a new API key, the KeyID value will be in the column labeled "KEY ID" for the key that you just created.
This script uses the requests HTTP library and authlib authentication library. You can install them via pip
pip install requests authlib
You would run the IsUserInApple with a single command line parameter, the email to look for. If you leave it out, you will get an error message telling you what is needed. Remember that the IsUserInApple.config file needs to be in the same folder as the .py file.
You would run it as
python IsUserInApple.py some.email@company.com