Fair
A CLI tool (fairtool for macOS & Linux) and runtime library (swift iOS & macOS) to manage Federated App Index Repositories (FAIRgrounds)
Install / Use
/learn @appfair/FairREADME
The fairtool is a cross-platform (Linux & macOS)
command-line utility and set of Swift modules
for managing an ecosystem of apps.
It is powered by the Fair package, which is a
cross-platform (Linux, macOS) executable and set of Swift modules.
The Fair package is used to create and maintain app distribution networks such as The App Fair.
fairtool
The functionality of the Fair module can best be illustrated by the
capabilities of the fairtool, which is a command-line utility for
macOS (15+) and Linux.
Installation
You can install Fairtool locally by running:
curl -fsSL https://appfair.net/install-fairtool.sh | sh
Running from Source
The run the fairtool from a local build on a machine with Swift 5.10 or higher:
git clone https://github.com/appfair/Fair
cd Fair
swift run fairtool --help
Usage
Interfacing with App Store Connect
https://developer.apple.com/documentation/appstoreconnectapi
Setup
In order to be able to connect to the App Store Connect API, follow the instructions at Creating API Keys for App Store Connect API.
Once you have the key information and the .p8 file downloaded, put all the information
into a single configuration JSON file, which follows the format used by the
Fastlane API Key JSON file.
Your apple-appstore-apikey.json file will look something like this:
{
"key_id": "D383SF239",
"issuer_id": "6053b7fe-68a8-1acb-89be-165aa6465141",
"key": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM19AgEGCCqGSM49AwEABHknlhdlYdLu\n-----END PRIVATE KEY-----"
}
[!WARNING] Keep this API key secure! It contains all the credentials that anyone would need to manage your apps and other sensitive account information through App Store Connect. Do not leave the key in a publicly accessible location, and do not check it into source control!
The path to the key will be searched for in one of the following places:
- The path specified by the
--keystoreargument - The path specified in the
FAIRTOOL_ASC_API_KEY_FILEenvironment variable - The default location at
$HOME/.config/fairtool/apple-appstore-apikey.json
Issuing commands
A freeform request to any documented endpoint can be made with the
fairtool asc request command. This can be useful for testing whether
the API key works, and for exploring the API directly.
For example, to list all your organization's apps in JSON format, you might call the List Apps endpoint:
fairtool asc request https://api.appstoreconnect.apple.com/v1/apps
which would result in something like:
{
"data" : [
{
"attributes" : {
"accessibilityUrl" : null,
"bundleId" : "org.appfair.app.Tune-Out",
"contentRightsDeclaration" : "USES_THIRD_PARTY_CONTENT",
"isOrEverWasMadeForKids" : false,
"name" : "Tune-Out",
"primaryLocale" : "en-US",
"sku" : "3432232323"
},
"id" : "1639901758",
"links" : {
"self" : "https://api.appstoreconnect.apple.com/v1/apps/1639901758"
},
"relationships" : {
"accessibilityDeclarations" : {
"links" : {
"related" : "https://api.appstoreconnect.apple.com/v1/apps/1639901758/accessibilityDeclarations",
"self" : "https://api.appstoreconnect.apple.com/v1/apps/1639901758/relationships/accessibilityDeclarations"
}
},
"alternativeDistributionKey" : {
"links" : {
"related" : "https://api.appstoreconnect.apple.com/v1/apps/1639901758/alternativeDistributionKey",
"self" : "https://api.appstoreconnect.apple.com/v1/apps/1639901758/relationships/alternativeDistributionKey"
}
}
},
"type" : "apps"
}
],
"links" : {
"self" : "https://api.appstoreconnect.apple.com/v1/apps"
},
"meta" : {
"paging" : {
"limit" : 50,
"total" : 16
}
}
}
Assembling Alternative Distribution Packages (ADP)
https://developer.apple.com/documentation/marketplacekit/ingesting-an-alternative-distribution-package
Analying apps
fairtool can analyze Mach-O app packages, both for macOS and iOS apps. This can be used to extract metadata examine entitlements, and perform security analysis on the app package.
fairtool artifact info file.app
The "app info" command will examine a macOS .app folder
or an unencrypted .ipa file or url
and output a JSON representation of the contents of the app's
Info.plist along with the entitlements embedded within the
app's primary executable.
// fairtool artifact info /System/Applications/Calculator.app
[
{
"entitlements" : [
{
"com.apple.security.app-sandbox" : true,
"com.apple.security.files.user-selected.read-write" : true,
"com.apple.security.network.client" : true,
"com.apple.security.print" : true
},
{
"com.apple.security.app-sandbox" : true,
"com.apple.security.files.user-selected.read-write" : true,
"com.apple.security.network.client" : true,
"com.apple.security.print" : true
}
],
"info" : {
"BuildMachineOSBuild" : "20A241133",
"CFBundleDevelopmentRegion" : "English",
"CFBundleExecutable" : "Calculator",
"CFBundleHelpBookFolder" : "Calculator.help",
"CFBundleHelpBookName" : "com.apple.Calculator.help",
"CFBundleIconFile" : "AppIcon",
"CFBundleIconName" : "AppIcon",
"CFBundleIdentifier" : "com.apple.calculator",
"CFBundleInfoDictionaryVersion" : "6.0",
"CFBundleName" : "Calculator",
"CFBundlePackageType" : "APPL",
"CFBundleShortVersionString" : "10.16",
"CFBundleSignature" : "????",
"CFBundleSupportedPlatforms" : [
"MacOSX"
],
"CFBundleVersion" : "223",
"CTIgnoreUserFonts" : true,
"DTCompiler" : "com.apple.compilers.llvm.clang.1_0",
"DTPlatformBuild" : "13E6049a",
"DTPlatformName" : "macosx",
"DTPlatformVersion" : "12.4",
"DTSDKBuild" : "21F64",
"DTSDKName" : "macosx12.4.internal",
"DTXcode" : "1330",
"DTXcodeBuild" : "13E6049a",
"LSApplicationCategoryType" : "public.app-category.utilities",
"LSApplicationSecondaryCategoryType" : "public.app-category.productivity",
"LSHasLocalizedDisplayName" : true,
"LSMinimumSystemVersion" : "12.4",
"NSMainNibFile" : "Calculator",
"NSPrincipalClass" : "NSApplication",
"NSSupportsSuddenTermination" : true
},
"url" : "file:///System/Applications/Calculator.app/"
}
]
The info property contains a JSON-ized form of the contents
if the Info.plist.
The entitlements array contains the entitlements extracted from
the binary. Note that in the case of multi-architecture binaries
(such as a "universal binary"), one set of entitlements will be
output for each processor architectures in the Mach-O binary.
fairtool artifact info url.ipa
The fairtool can also output the same information for an unencrypted iOS .ipa file, either a local file or a remote URL:
// fairtool artifact info https://github.com/Cloud-Cuckoo/App/releases/latest/download/Cloud-Cuckoo-iOS.ipa
[
{
"entitlements": [],
"info": {
"CFBundleName": "Cloud Cuckoo",
"CFBundleIdentifier": "app.Cloud-Cuckoo",
"CFBundleVersion": "469",
"CFBundleShortVersionString": "0.9.108",
"CFBundleExecutable": "Cloud Cuckoo",
"CFBundleIcons": {
"CFBundlePrimaryIcon": {
"CFBundleIconFiles": [
"AppIcon60x60"
],
"CFBundleIconName": "AppIcon"
}
},
"AppSource": {
"developerName": "Fair Apps <fairapps@appfair.net>",
"fundingLinks": [
{
"localizedDescription": "Help fund upcoming challenges and new additions to the whimsical and award-winning “Cloud Cuckoo” game. Fun for all ages!",
"localizedTitle": "Support the development of “Cloud Cuckoo”",
"platform": "GITHUB",
"url": "https://github.com/Cloud-Cuckoo"
}
],
"localizedDescription": "Chase on the Cuckoo around the screen! This is a silly little game for the App Fair.",
"subtitle": "A whimsical game of excitement and delight",
"versionDescription": "Bug fixes and performance improvements."
},
"BuildMachineOSBuild": "21F79",
"CFBundleSupportedPlatforms": [
"iPhoneOS"
],
"DTCompiler": "com.apple.compilers.llvm.clang.1_0",
"DTPlatformBuild": "19C51",
"DTPlatformName": "iphoneos",
"DTPlatformVersion": "15.2",
"DTSDKBuild": "19C51",
"DTSDKName": "iphoneos15.2",
"DTXcode": "1321",
"DTXcodeBuild": "13C100",
"ITSAppUsesNonExemptEncryption": false,
"LSApplicationQueriesSchemes": [
"appfair"
],
"LSSupportsOpeningDocumentsInPlace": true,
"NSAppleEventsUsageDescription": "AppleScript can be used by this app.",
"NSAppleScriptEnabled": true,
"NSAppTransportSecurity": {
"NSAllowsArbitraryLoads": true
},
"NSHumanReadableCopyright": "GNU Affero General Public License"
},
"url": "https://github.com/Cloud-Cuckoo/App/releases/latest/download/Cloud-Cuckoo-iOS.ipa"
}
]
General fairtool Usage Info
fairtool JSON output
Most of the fairtool's informational operations will output well-formed JSON. This is so it can be used in conjunction with other tools.
One such tools is the popular jq utility, which can be used to format,
filter, and re-structure JSON. For example, to examine an app's
"*UsageDescription" properties (which wil
Related Skills
node-connect
352.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
111.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
352.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
352.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
