| Crates.io | kodegen_bundler_sign |
| lib.rs | kodegen_bundler_sign |
| version | 0.10.10 |
| created_at | 2025-11-03 11:47:13.597462+00 |
| updated_at | 2026-01-02 15:01:49.126426+00 |
| description | KODEGEN.ᴀɪ: Database query and schema exploration MCP tools for AI agents. |
| homepage | https://kodegen.ai |
| repository | https://github.com/cyrup-ai/kodegen-bundler-sign |
| max_upload_size | |
| id | 1914533 |
| size | 308,364 |
Automated code signing and certificate provisioning for Kodegen daemon
kodegen_bundler_sign is a comprehensive tool for managing code signing workflows across macOS, Linux, and Windows platforms. Its primary focus is macOS, where it provides automated certificate provisioning through Apple's App Store Connect API, builds and signs privileged helper applications, and manages deployment to GitHub releases.
The package serves three main purposes:
KodegenHelper.app) that enables the Kodegen daemon to execute administrative taskscargo run --package kodegen_bundler_sign -- --interactive
This will guide you through:
cargo run --package kodegen_bundler_sign -- --build-helper
export GITHUB_TOKEN="your_token"
cargo run --package kodegen_bundler_sign -- --build-helper --upload
export APPLE_API_KEY="your_key_id"
export APPLE_API_ISSUER="your_issuer_id"
export APPLE_API_KEY_PATH="/path/to/AuthKey_XXXXXXXXXX.p8"
cargo run --package kodegen_bundler_sign -- --notarize /path/to/YourApp.app
cargo run --package kodegen_bundler_sign -- --sign /path/to/binary \
--identity "Developer ID Application: Your Name (TEAM_ID)" \
--entitlements entitlements.plist
cargo run --package kodegen_bundler_sign -- --show
Displays:
~/.config/kodegen/signing.toml)cargo run --package kodegen_bundler_sign -- --interactive
Guided setup with prompts for:
cargo run --package kodegen_bundler_sign -- --build-helper [OPTIONS]
Options:
--upload: Upload to GitHub releases--github-token <TOKEN>: GitHub API token (or use GITHUB_TOKEN env var)--output-dir <DIR>: Output directory (default: target/helper)cargo run --package kodegen_bundler_sign -- --notarize <PATH> [OPTIONS]
Options:
--wait <BOOL>: Wait for notarization to complete (default: true)Diagnose notarization setup:
cargo run --package kodegen_bundler_sign -- --diagnose-notarization
Environment Variables:
APPLE_API_KEY: App Store Connect API Key ID (recommended)APPLE_API_ISSUER: App Store Connect Issuer IDAPPLE_API_KEY_PATH: Path to .p8 file (optional, auto-searches standard locations)APPLE_ID: Apple ID email (legacy method)APPLE_PASSWORD: App-specific password (legacy method)APPLE_TEAM_ID: Team ID (legacy method)cargo run --package kodegen_bundler_sign -- --sign <BINARY> [OPTIONS]
Options:
--identity <IDENTITY>: Signing identity (required)--entitlements <PATH>: Path to entitlements.plist (optional)--hardened-runtime <BOOL>: Enable hardened runtime (default: true)cargo run --package kodegen_bundler_sign -- --config signing.toml
Example signing.toml:
platform = "macos"
dry_run = false
verbose = true
issuer_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
key_id = "XXXXXXXXXX"
private_key_path = "~/.keys/AuthKey_XXXXXXXXXX.p8"
certificate_type = "developer_id"
common_name = "Kodegen Helper"
keychain = "login.keychain-db"
lib.rs: Library interface with platform-conditional exports and shared utilitiesmain.rs: CLI application with six operational modes (show, interactive, build-helper, notarize, sign, config)config.rs: Configuration structures for all platformserror.rs: Custom error types using thiserrorsrc/macos/)setup.rs: Certificate provisioning workflowkeychain.rs: Keychain operations with file lockingnotarization.rs: Apple notarization workflow (submit, poll, staple)validation.rs: Certificate and setup validationprompts.rs: Interactive user promptsmod.rs: Module exports and platform entry pointbuild_helper.rs: macOS helper app creation and C code compilationsign_helper.rs: Code signing operations with codesignpackage_helper.rs: ZIP packaging and integrity hashingapple_api.rs: App Store Connect API clientwindows.rs: Cross-platform Authenticode signing using osslsigncode (available on all platforms, not just Windows)linux.rs: GPG-based signing guidanceThe apple_api.rs module implements JWT-based authentication with Apple's certificate provisioning API.
kid (Key ID), alg: "ES256"iss (Issuer ID), aud: "appstoreconnect-v1", iat, exp (20 minutes)jsonwebtoken crateEndpoint: https://api.appstoreconnect.apple.com/v1/certificates
Request:
{
"data": {
"type": "certificates",
"attributes": {
"certificateType": "DEVELOPER_ID_APPLICATION",
"csrContent": "<PEM-encoded CSR>"
}
}
}
Response:
{
"data": {
"attributes": {
"certificateContent": "<base64-encoded DER certificate>"
}
}
}
.p8 file (one-time download only)rcgen~/.config/kodegen/signing.tomlKodegenHelper.app is a macOS privileged helper that enables the Kodegen daemon to execute administrative tasks without running the entire daemon as root. It follows macOS best practices for privilege separation using the Service Management framework.
Authorization Requirements:
admin group membershipSMAuthorizedClients in Info.plistSMPrivilegedExecutables in daemon's Info.plistRuntime Security:
proc_pidpath to verify parent is kodegendSIGALRMmkstemp for secure random filenamesThe helper is implemented in C and compiled with cc. Key features:
Main Function Flow:
1. Validate parent process name contains "kodegen" (macOS: proc_pidpath)
2. Accept script content as argv[1]
3. Validate script size <= 1MB
4. Set up SIGALRM timeout handler (300 seconds)
5. Create temporary file with mkstemp: /tmp/kodegend_helper_XXXXXX
6. Write script content (0600 permissions preserved for security)
7. Fork child process
8. Child: execl("/bin/sh", "sh", temp_path, NULL)
9. Parent: waitpid for completion
10. Clean up temporary file
11. Return child exit status
Error Handling:
KodegenHelper.app/
├── Contents/
│ ├── Info.plist # Bundle metadata
│ └── MacOS/
│ └── KodegenHelper # Compiled C executable
Key Settings:
ai.kodegen.kodegend.helpertrue (background agent, no dock icon)Authorization Settings:
<key>SMPrivilegedExecutables</key>
<dict>
<key>ai.kodegen.kodegend.helper</key>
<string>identifier "ai.kodegen.kodegend.helper" and anchor apple generic</string>
</dict>
<key>SMAuthorizedClients</key>
<array>
<string>identifier "ai.kodegen.kodegend" and anchor apple generic</string>
</array>
The sign_helper.rs module implements a multi-step signing process:
security find-identity -v -p codesigning
-) for development if no Developer ID foundhelper.entitlements with admin authorization requirementscodesign --force --sign <identity> --options runtime --entitlements helper.entitlements Contents/MacOS/KodegenHelpercodesign --force --deep --sign <identity> --options runtime KodegenHelper.appcodesign --verify --deep --strict KodegenHelper.appProduction:
Development:
export KODEGEN_SIGNING_IDENTITY="-"All production builds use --options runtime flag, enabling:
Apple notarization is a security process where Apple scans your app for malware and signs it with a notarization ticket.
Submit for notarization:
cargo run --package kodegen_bundler_sign -- --notarize /path/to/App.app
Non-blocking submission:
cargo run --package kodegen_bundler_sign -- --notarize /path/to/App.app --wait false
Diagnose setup issues:
cargo run --package kodegen_bundler_sign -- --diagnose-notarization
Modern (Recommended): App Store Connect API Key
export APPLE_API_KEY="XXXXXXXXXX"
export APPLE_API_ISSUER="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export APPLE_API_KEY_PATH="/path/to/AuthKey_XXXXXXXXXX.p8"
Legacy: Apple ID with app-specific password
export APPLE_ID="your@email.com"
export APPLE_PASSWORD="xxxx-xxxx-xxxx-xxxx"
export APPLE_TEAM_ID="XXXXXXXXXX"
xcrun notarytool submitxcrun stapler stapleThe package_helper.rs module creates compressed packages:
Features:
Output Files:
KodegenHelper.app.zip: Compressed app bundleKodegenHelper.app.zip.sha256: SHA-256 integrity hash (hex-encoded)app_zip_data.rs: Generated Rust code with include_bytes! macroHash Generation:
SHA256(KodegenHelper.app.zip) = <64-character hex string>
Verification Process:
Generated Rust Code:
const APP_ZIP_DATA: &[u8] = include_bytes!("/path/to/KodegenHelper.app.zip");
Cargo Environment Variables:
HELPER_ZIP_PATH: Path to ZIP fileHELPER_ZIP_INCLUDE_FILE: Path to generated Rust fileMACOS_HELPER_ZIP_HASH: SHA-256 hashAll build operations are atomic:
Rollback on Failure: All temporary files removed if any step fails.
Target Repository: cyrup-ai/kodegen
Workflow:
aarch64, x86_64)KodegenHelper.app-macos-{arch}.zipAuthentication:
--github-token flagGITHUB_TOKEN environment variablerepo scope for releasesUpload Command:
cargo run --package kodegen_bundler_sign -- \
--build-helper \
--upload \
--github-token "ghp_xxxxxxxxxxxxxxxxxxxx"
Format: KodegenHelper.app-macos-{arch}.zip
Examples:
KodegenHelper.app-macos-aarch64.zip (Apple Silicon)KodegenHelper.app-macos-x86_64.zip (Intel)The windows module provides cross-platform Authenticode signing using osslsigncode, available on all platforms (not just Windows). This enables macOS and Linux developers to sign Windows binaries.
use kodegen_bundler_sign::windows::{SignConfig, sign_binary_with_fallback};
let config = SignConfig {
cert_path: "path/to/cert.pfx".into(),
key_path: None, // Not needed for PKCS#12
password: Some("password".to_string()),
timestamp_url: Some("http://timestamp.digicert.com".to_string()),
app_name: Some("MyApp".to_string()),
app_url: Some("https://example.com".to_string()),
};
sign_binary_with_fallback(Path::new("myapp.exe"), &config).await?;
osslsigncode for non-Windows platformsBuilt-in fallback list includes:
| Package | Version | Purpose |
|---|---|---|
clap |
4 | Command-line argument parsing with derive macros |
anyhow |
1 | Error handling with context |
serde |
1 | Serialization framework |
serde_json |
1 | JSON parsing |
toml |
0.9 | TOML configuration parsing |
thiserror |
2 | Custom error types |
tokio |
1 | Async runtime (full feature set) |
tempfile |
3 | Secure temporary file creation |
| Package | Version | Purpose |
|---|---|---|
rcgen |
0.14 | CSR and key pair generation |
jsonwebtoken |
9 | JWT creation with ES256 |
base64 |
0.22 | Base64 encoding/decoding |
reqwest |
0.12 | HTTP client for Apple API |
dirs |
6 | Platform-specific paths |
shellexpand |
3 | Tilde expansion |
| Package | Version | Purpose |
|---|---|---|
cc |
1 | C code compilation |
zip |
6 | ZIP archive creation |
sha2 |
0.10 | SHA-256 hashing |
hex |
0.4 | Hexadecimal encoding |
bytes |
1 | Byte buffers for uploads |
| Package | Version | Purpose |
|---|---|---|
fs4 |
0.13 | File locking with async support |
rand |
0.9 | Random password generation |
zeroize |
1 | Secure memory clearing |
chrono |
0.4 | Certificate expiry handling |
| Package | Version | Purpose |
|---|---|---|
kodegen_tools_github |
local | GitHub API client |
octocrab |
0.47 | GitHub API library |
cyrup_termcolor |
2 | Terminal colors (required) |
which |
8 | Binary path finding for osslsigncode |
openssl command)security command)codesign command)cc command)xcrun notarytool)xcrun stapler)Features:
Requirements:
Current Implementation:
osslsigncodeRecommendations for Native Windows:
# Import certificate
certutil -user -importpfx code_signing_cert.pfx
# View certificates
certmgr.msc
Current Implementation:
Recommendations:
# Generate GPG key
gpg --full-generate-key
# List keys
gpg --list-secret-keys --keyid-format LONG
Private Key Protection
.p8 files securely with restricted permissions: chmod 600Keychain Security
/usr/bin/codesignJWT Token Security
Code Signing Verification
Authorization Model
Execution Limits
Input Validation
Token Permissions
repo scopeAsset Verification
Issue: Certificate request failed: Unauthorized
Solutions:
.p8 file is not corruptedIssue: Failed to import to keychain
Solutions:
# Unlock keychain
security unlock-keychain login.keychain-db
# List keychains
security list-keychains
# Verify OpenSSL installation
which openssl
openssl version
Issue: No Developer ID certificate found
Solutions:
cargo run --package kodegen_bundler_sign -- --interactiveexport KODEGEN_SIGNING_IDENTITY="-"Issue: Failed to compile helper: cc not found
Solutions:
# Install Xcode Command Line Tools
xcode-select --install
# Verify installation
cc --version
xcode-select -p
Issue: Failed to sign executable: code object is not signed at all
Solution: This is a warning in development mode, not an error. The build continues with ad-hoc signing.
Issue: Helper validation failed: Helper executable not executable
Solutions:
# Check permissions
ls -l target/helper/KodegenHelper.app/Contents/MacOS/KodegenHelper
# Fix permissions
chmod +x target/helper/KodegenHelper.app/Contents/MacOS/KodegenHelper
Issue: No notarization credentials found in environment
Solutions:
# Set API key credentials (recommended)
export APPLE_API_KEY="XXXXXXXXXX"
export APPLE_API_ISSUER="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export APPLE_API_KEY_PATH="/path/to/AuthKey_XXXXXXXXXX.p8"
# Or use Apple ID (legacy)
export APPLE_ID="your@email.com"
export APPLE_PASSWORD="xxxx-xxxx-xxxx-xxxx"
export APPLE_TEAM_ID="XXXXXXXXXX"
Issue: Notarization failed
Solutions:
cargo run --package kodegen_bundler_sign -- --diagnose-notarizationIssue: GitHub token required for upload
Solutions:
# Set environment variable
export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx"
# Or use CLI flag
cargo run --package kodegen_bundler_sign -- --build-helper --upload --github-token "ghp_xxx"
Issue: Failed to get latest release
Solutions:
cyrup-ai/kodegenrepo scope# 1. Clone repository (adjust path for your setup)
cd kodegen-bundler-sign
# 2. Provision certificate (one-time)
cargo run --package kodegen_bundler_sign -- --interactive
# 3. Build helper app
cargo run --package kodegen_bundler_sign -- --build-helper
# 4. Verify output
ls -lh target/helper/
# Run with verbose output (via config file with verbose = true)
cargo run --package kodegen_bundler_sign -- --config signing.toml
# Dry-run mode (via config file with dry_run = true)
cargo run --package kodegen_bundler_sign -- --config signing.toml
# Show current configuration
cargo run --package kodegen_bundler_sign -- --show
# Diagnose notarization setup
cargo run --package kodegen_bundler_sign -- --diagnose-notarization
GitHub Actions Example:
name: Build Helper
on:
push:
branches: [main]
release:
types: [created]
jobs:
build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt, clippy
- name: Provision Certificate
env:
ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
PRIVATE_KEY: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY }}
run: |
echo "$PRIVATE_KEY" > AuthKey.p8
chmod 600 AuthKey.p8
cargo run --package kodegen_bundler_sign -- \
--issuer-id "$ISSUER_ID" \
--key-id "$KEY_ID" \
--private-key AuthKey.p8
- name: Build Helper
run: |
cargo run --package kodegen_bundler_sign -- --build-helper
- name: Upload to Release
if: github.event_name == 'release'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cargo run --package kodegen_bundler_sign -- \
--build-helper \
--upload
See LICENSE.md in the repository root.