A local macOS project for re-signing iOS .ipa files.
The UI is a separate React + MUI frontend (frontend/) and FastAPI serves only the compiled frontend assets from frontend/dist.
The web app itself could run almost anywhere, but the actual signing step depends on Apple's signing stack. Apple says to use Xcode on all platforms or the codesign tool on macOS only, and code signing is described as a macOS security technology. Fastlane also provides an official resign action for re-signing an existing IPA. citeturn465841search13turn465841search1turn465841search0
So the practical setup is:
- run this project directly on a Mac
- use the browser UI locally at
http://127.0.0.1:8000(compiled React frontend) - let the backend call
fastlane resign,security, andcodesign
- Upload
.ipa,.mobileprovision, and.p12 - Enter P12 password and signing identity
- Optional bundle ID and display name override
- Job page with live polling
- Retry failed jobs from the job page (re-enter P12 password)
- Download the re-signed IPA when the job completes
- Temporary keychain used per job
- FastAPI serves only built frontend assets (no server-side templates)
- macOS
- Python 3.10+
- Ruby /
gem fastlane- Node.js +
npm(to build the frontend) - Apple signing identity exported as
.p12 - Matching provisioning profile
cd ios-resign-local
./bin/setup.shsetup.sh now installs Python dependencies, installs frontend dependencies, and builds the frontend.
If fastlane is not installed:
sudo gem install fastlanecd ios-resign-local
source .venv/bin/activate
uvicorn app.main:app --reloadThen open:
http://127.0.0.1:8000
cd ios-resign-local/frontend
npm install
npm run devBefore running FastAPI for local integration, build the frontend:
cd ios-resign-local/frontend
npm run buildGET /api/jobs- latest jobsPOST /api/jobs- create a job (multipart form)GET /api/jobs/{job_id}- job status/detailsPOST /api/jobs/{job_id}/retry- retry failed job (form withp12_password)GET /api/jobs/{job_id}/download- download completed artifactGET /healthz- health check
- Signing identity input accepts the full identity name, Team ID (10 chars), or SHA-1 fingerprint from the imported
.p12. - The provisioning profile must be compatible with the certificate, team, app ID, and entitlements you want to use.
- Uploaded files are stored under
data/jobs/<job-id>/and finished IPAs underdata/artifacts/<job-id>/. - Temporary keychains are created per job with the standard password
ios-resign-temp, then completely deleted after signing (files, keychain list entries, and all related artifacts). - The sample app keeps job state in SQLite for simplicity.
- If
frontend/distis missing, the backend returns503at/with a build hint.