Apple Code Signing, In Depth --- A Series
Where you are: the front door of an 8-part series on how Apple's developer program, signing certificates, and provisioning profiles fit together.
What you'll know after this file: the whole map, the reading order, and the one story (PawPal) that ties every article together.
Most developers meet Apple code signing as a wall of red errors in Xcode: "No profiles for 'com.x.y' were found" , "Provisioning profile doesn't include signing certificate" , "errSecInternalComponent" . They click Automatically manage signing, it works, and the system stays a black box until it breaks on CI at 2 a.m.
This series opens the box. It doesn't start from menus. It starts from the security problem Apple had to solve and works forward from there, so each piece looks like something you would have had to invent yourself.
The series
| # | Article | Question it answers |
|---|---|---|
| 1 | Why code signing exists | What breaks without it? |
| 2 | What Apple code signing is (and isn't) | What exactly is this system, and where are its edges? |
| 3 | The concept map | What are the pieces, and who does what? |
| 4 | The running example: shipping PawPal | What does one real app's journey look like? |
| 5.1 | The Developer Account & Team | Who is the root of identity? |
| 5.2 | Signing Certificates & Private Keys | How does Apple vouch for you? |
| 5.3 | App IDs, Capabilities & Entitlements | How does Apple vouch for what your app may do? |
| 5.4 | Registered Devices | How does Apple limit where a non-store build may run? |
| 5.5 | Provisioning Profiles | How are who / what / where bound into one signed permission slip? |
| 5.6 | codesign & the Signature Inside Your App | What does a signature physically look like inside the binary? |
| 5.7 | On-Device Verification (installd, AMFI, the kernel) | How does the iPhone decide to run your code? |
| 5.8 | Distribution & Apple Re-signing | What changes for TestFlight, App Store, Ad Hoc, Enterprise, and macOS? |
| 6 | Full walkthrough: PawPal end to end | Every step again, at full depth |
| 7 | Troubleshooting, CI & next steps | How do I fix it when it breaks? |
Reading order: go 1 → 6 straight through the first time. Each deep dive (5.x) also works on its own, because it recaps its role and ties back to the PawPal example.
The whole territory, in one picture
What are all the concepts and components, and how do they group?
#mermaid-svg-Ge7m4Ut9GLIS7hvD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .error-icon{fill:#552222;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .marker.cross{stroke:#333333;}#mermaid-svg-Ge7m4Ut9GLIS7hvD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ge7m4Ut9GLIS7hvD p{margin:0;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge{stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 text{fill:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth--1{stroke-width:17;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-0{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-0{stroke-width:14;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-1{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-1{stroke-width:11;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 text{fill:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-2{stroke-width:8;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-3{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-3{stroke-width:5;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-4{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-4{stroke-width:2;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-5{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-5{stroke-width:-1;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-6{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-6{stroke-width:-4;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-7{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-7{stroke-width:-7;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-8{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-8{stroke-width:-10;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-9{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-9{stroke-width:-13;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-10{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-10{stroke-width:-16;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root text{fill:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root span{color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 span{color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge{fill:none;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-Ge7m4Ut9GLIS7hvD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Apple Code Signing
Problem it solves
Who wrote this code?
Was it modified?
What is it allowed to do?
Where may it run?
Can Apple revoke it?
Core concepts
Team & Team ID
Key pair & Certificate
Certificate chain to Apple Root CA
App ID / Bundle ID
Entitlements & Capabilities
Device UDID
Provisioning Profile
Code Signature & cdhash
Key players
Apple Developer Portal
issues certs, App IDs, profiles
Developer Mac Keychain
holds private key
Xcode / codesign
seals the bundle
iOS installd
checks profile at install
AMFI + kernel
checks every page at runtime
App Store Connect
reviews & re-signs
Running example
Mia ships PawPal with push notifications
Debug on own iPhone
Ad Hoc to a tester
TestFlight then App Store
Key flows
Happy path: CSR to cert to profile to sign to install to run
Failure: device not in profile
Failure: entitlement mismatch
Failure: expired or revoked cert
The core idea in one paragraph
A signed iOS app makes three claims and has one permission slip that backs them. The claims: "I was built by this Team" (certificate), "I have not been changed since" (code signature hashes), and "I may use these powers" (entitlements). The permission slip is the provisioning profile , a plist that Apple signs and that says "this Team's certificates may sign this App ID, with these entitlements, to run on these devices, until this date." The device trusts Apple's root key and nothing else. So every claim has to trace back to something Apple signed.