Code Signing Guide for VibeTunnel
This comprehensive guide covers all aspects of code signing for VibeTunnel, from local development setup to release distribution.Table of Contents
Development Setup
Initial Team Configuration
VibeTunnel uses xcconfig files to manage developer team settings, allowing multiple developers to work without code signing conflicts.-
Copy the template file to create your local configuration:
-
Edit
../apple/Local.xcconfig
and add your development team ID:Finding your team ID in Xcode:- Open Xcode → Settings (or Preferences)
- Go to Accounts tab
- Select your Apple ID
- Look for your Team ID in the team details
- Open the project in Xcode - it will now use your personal development team automatically.
How xcconfig Works
VibeTunnel/Shared.xcconfig
- Contains shared configuration and includes local settings../apple/Local.xcconfig
- Your personal settings (ignored by git)../apple/Local.xcconfig.template
- Template for new developers
Avoiding Keychain Dialogs During Development
VibeTunnel stores dashboard passwords in the keychain, which can trigger repeated authorization dialogs during development.Debug Mode Behavior
In DEBUG builds, the app automatically skips keychain reads to avoid dialogs:- Password Setting: You can set passwords during the current session
- Session Persistence: Passwords work normally until app restart
- No Persistence: Passwords are “forgotten” on restart (not read from keychain)
- No Dialogs: Prevents keychain authorization dialogs during development
Testing Password Persistence
To test actual password persistence:- Build in Release mode:
- Product → Scheme → Edit Scheme → Run → Build Configuration → Release
- Use Archive build:
- Product → Archive (always uses Release configuration)
Release Signing & Notarization
Prerequisites
- Apple Developer Program membership ($99/year)
- Developer ID Application certificate in your Keychain
- App Store Connect API key for notarization
Setting Up Developer ID Certificate
- Go to Apple Developer Portal
- Create a new certificate → Developer ID → Developer ID Application
- Download and install the certificate in your Keychain
Environment Variables
Create a.env
file in the project root (gitignored):
Creating App Store Connect API Key
- Go to App Store Connect
- Click “Generate API Key”
- Set role to “Developer”
- Download the
.p8
file - Note the Key ID and Issuer ID
Usage
Sign Only (for development)
Sign and Notarize (for distribution)
Individual Scripts
Script Options
CI/CD Setup (GitHub Actions)
Add these secrets to your GitHub repository:APP_STORE_CONNECT_API_KEY_P8
- The complete .p8 key contentAPP_STORE_CONNECT_KEY_ID
- The Key IDAPP_STORE_CONNECT_ISSUER_ID
- The Issuer ID
Troubleshooting
Development Issues
xcconfig Not Working
- Ensure
../apple/Local.xcconfig
exists - Check that the file isn’t committed to git
- Verify the DEVELOPMENT_TEAM value is correct
Keychain Dialogs Still Appearing
- Verify you’re running in Debug configuration
- Check
DashboardKeychain.swift
implementation - Ensure you’re not in Release mode
Code Signing Issues
”No signing identity found”
- Install Developer ID Application certificate
- Check with:
security find-identity -v -p codesigning
”User interaction is not allowed”
- Unlock keychain:
security unlock-keychain
- Or use:
security unlock-keychain -p <password> login.keychain
Notarization Issues
”Invalid API key”
- Verify API key content, ID, and Issuer ID
- Ensure .p8 key includes BEGIN/END lines
”App bundle not eligible for notarization”
- Ensure proper code signing with hardened runtime
- Check entitlements configuration
”Notarization failed”
- Script shows detailed error messages
- Common issues: unsigned binaries, invalid entitlements, prohibited code
Verification Commands
Reference
Build Configurations
- Debug builds: Use personal development certificate
- Release builds: Use Developer ID for distribution
- CI builds: Use ad-hoc signing
File Structure After Signing
Security Notes
- Never commit signing certificates or API keys
- Use environment variables or secure CI/CD secrets
- The
.env
file is gitignored for security - API keys should have minimal permissions (Developer role)
Implementation Details
Debug keychain behavior is inDashboardKeychain.swift
:
getPassword()
returnsnil
in DEBUG buildssetPassword()
saves but logs non-persistencehasPassword()
works normally