Documentation
¶
Overview ¶
Package macgo provides seamless macOS application bundle creation with permissions and entitlements.
macgo enables Go programs to integrate with macOS security features by automatically creating app bundles with proper structure, Info.plist, entitlements, and code signing. This allows Go applications to request system permissions (camera, microphone, files, etc.) just like native macOS applications.
Quick Start ¶
The simplest way to use macgo is with the Request function:
err := macgo.Request(macgo.Camera)
if err != nil {
log.Fatal(err)
}
// Camera permission granted, proceed with camera access
Request multiple permissions at once:
err := macgo.Request(macgo.Camera, macgo.Microphone, macgo.Files)
if err != nil {
log.Fatal(err)
}
Configuration ¶
For more control, use the Config struct with builder methods:
cfg := macgo.NewConfig().
WithAppName("MyApp").
WithBundleID("com.example.myapp").
WithPermissions(macgo.Camera, macgo.Microphone).
WithAdHocSign().
WithDebug()
err := macgo.Start(cfg)
if err != nil {
log.Fatal(err)
}
Available Permissions ¶
- Camera: access to camera
- Microphone: access to microphone
- Location: access to location services
- ScreenRecording: access to screen recording
- Accessibility: access to Accessibility features (e.g. input simulation)
- Files: access to user-selected files
- Network: network client/server access
- Sandbox: enable app sandbox with restricted file access
Launch Modes ¶
macgo supports three launch strategies:
Bundle mode (default): creates a .app bundle, relaunches via LaunchServices, and forwards I/O. Required for TCC-dialog permissions (Camera, Microphone, Location).
Single-process mode: codesigns the binary in-place, re-execs for the kernel to pick up new entitlements, then calls setActivationPolicy. No bundle, no child process, no I/O forwarding. Only works for entitlement-only permissions (Accessibility, Virtualization, Network). Enable via Config.WithSingleProcess or MACGO_SINGLE_PROCESS=1.
The internal/launchservices package provides a standalone pure Go replacement for /usr/bin/open (available as cmd/lsopen), but is not used by the default bundle launch path due to run loop constraints in library contexts.
Code Signing ¶
macgo supports multiple signing approaches:
Ad-hoc signing for development:
cfg := macgo.NewConfig().WithAdHocSign()
Automatic Developer ID detection:
cfg := macgo.NewConfig().WithAutoSign()
Specific signing identity:
cfg := macgo.NewConfig().WithCodeSigning("Developer ID Application: Your Name")
Environment Variables ¶
All configuration can be driven by environment variables, which are read by Config.FromEnv. Variables are grouped by category below.
Application identity:
MACGO_APP_NAME Application display name MACGO_APP_NAME_PREFIX Prefix prepended to app names (e.g. "Dev-") MACGO_BUNDLE_ID Bundle identifier (e.g. "com.example.myapp") MACGO_BUNDLE_ID_PREFIX Prefix prepended to bundle IDs (e.g. "test.")
Permissions (set to "1" to enable):
MACGO_CAMERA Request camera access MACGO_MICROPHONE Request microphone access MACGO_LOCATION Request location services access MACGO_SCREEN_RECORDING Request screen recording access MACGO_FILES Request user-selected file access MACGO_NETWORK Request network client access MACGO_SANDBOX Enable app sandbox
Code signing:
MACGO_AD_HOC_SIGN Ad-hoc sign the bundle (set to "1") MACGO_AUTO_SIGN Auto-detect Developer ID certificate (set to "1") MACGO_CODE_SIGN_IDENTITY Specific signing identity string
Launch behavior (set to "1" unless noted):
MACGO_SINGLE_PROCESS Single-process mode: codesign + re-exec, no bundle MACGO_FORCE_DIRECT Force direct binary execution (skip LaunchServices) MACGO_FORCE_LAUNCH_SERVICES Force LaunchServices even when not needed MACGO_NO_RELAUNCH Disable automatic relaunch entirely MACGO_OPEN_NEW_INSTANCE Set to "0" to disable -n flag for open command
Bundle and debugging:
MACGO_DEBUG Enable debug logging to stderr (set to "1") MACGO_KEEP_BUNDLE Preserve temporary bundle after execution (set to "1") MACGO_ICON Path to .icns file for the app icon MACGO_PROVISIONING_PROFILE Path to provisioning profile to embed MACGO_RESET_PERMISSIONS Reset TCC permissions before requesting (set to "1")
Development:
MACGO_DEV_MODE Dev mode: signed wrapper exec's the source binary (set to "1") MACGO_TTY_PASSTHROUGH Pass TTY device to child process (experimental, set to "1")
Internal (set by macgo, not typically set by users):
MACGO_STDIN_PIPE Path to stdin named pipe (child reads from parent) MACGO_STDOUT_PIPE Path to stdout named pipe (child writes to parent) MACGO_STDERR_PIPE Path to stderr named pipe (child writes to parent) MACGO_CONTROL_PIPE Path to control FIFO (child writes PID for signal forwarding) MACGO_CWD Original working directory to restore in child MACGO_BUNDLE_PATH Path to the .app bundle MACGO_ORIGINAL_EXECUTABLE Path to the original binary before bundle copy MACGO_SINGLE_PROCESS_ACTIVE Sentinel: set to "1" after single-process re-exec
Bundle Structure ¶
macgo creates a standard macOS app bundle:
MyApp.app/ ├── Contents/ │ ├── Info.plist │ ├── MacOS/ │ │ └── MyApp │ ├── Resources/ │ └── _CodeSignature/
Bundle ID Generation ¶
macgo generates bundle IDs from your Go module path:
github.com/user/project → com.github.user.project.appname gitlab.com/org/tool → com.gitlab.org.tool.appname example.com/app → com.example.app.appname Private/custom modules → io.username.appname
Auto Packages ¶
Import auto packages for pre-configured setups:
import (
_ "github.com/tmc/macgo/auto/media" // Camera + Microphone
_ "github.com/tmc/macgo/auto/files" // File access
_ "github.com/tmc/macgo/auto/adhoc" // Ad-hoc signing
"github.com/tmc/macgo"
)
func main() {
macgo.Request()
}
Cleanup ¶
Cleanup is no longer required. FIFO-based I/O forwarding uses pipe EOF as the exit signal, so no explicit cleanup call is needed. The function is retained as a no-op for backward compatibility.
TCC Integration ¶
macgo integrates with macOS TCC (Transparency, Consent, and Control) to:
- Generate proper entitlements for requested permissions
- Handle permission prompts automatically
- Reset permissions for testing (when requested)
- Support both sandboxed and non-sandboxed applications
Package macgo provides simple macOS app bundle creation and TCC permission management.
macgo enables Go applications to request macOS system permissions (camera, microphone, files, etc.) by automatically creating app bundles with proper entitlements and handling the relaunch process when necessary.
Usage ¶
To correctly use macgo, you must call macgo.Start() or macgo.Request() at the very beginning of your main() function, before any other logic or background goroutines are started.
1. Basic Usage (One-Liner)
func main() {
// Request permissions immediately.
// If the app is not in a bundle, this will create one and relaunch the app.
if err := macgo.Request(macgo.Camera, macgo.Microphone); err != nil {
log.Fatal(err)
}
// Your application logic starts here...
}
2. Advanced Usage (Configuration)
func main() {
cfg := &macgo.Config{
AppName: "MyApp",
Permissions: []macgo.Permission{macgo.Camera, macgo.Files},
Debug: true, // Enable debug logging to stderr
}
// Initialize macgo. This logic handles the process lifecycle.
// If a relaunch is needed, Start will exit the current process.
if err := macgo.Start(cfg); err != nil {
log.Fatal(err)
}
// Your application logic starts here...
}
How it Works ¶
When macgo.Start() is called:
- It checks if the program is running inside a valid macOS App Bundle.
- If NOT, it creates a temporary App Bundle in /tmp with the requested entitlements.
- It relaunches the current executable *inside* that bundle using `open`.
- It transparently forwards stdin/stdout/stderr from the bundled process to your terminal.
- The original process exits.
- If ALREADY inside a bundle (the relaunched process), Start() simply returns nil, allowing your main() function to proceed with the requested permissions.
Important Notes ¶
- macgo.Start() MUST be called early in main().
- Do not rely on init() functions for logic that depends on permissions, as they run before main.
- macgo preserves exit codes and terminal I/O.
Example (BundleIDGeneration) ¶
Example showing automatic bundle ID generation
package main
import (
"github.com/tmc/macgo"
)
func main() {
// macgo automatically generates meaningful bundle IDs based on your Go module
// Examples of automatic bundle ID generation:
//
// Module: github.com/user/myproject -> Bundle ID: com.github.user.myproject.appname
// Module: gitlab.com/company/tool -> Bundle ID: com.gitlab.company.tool.appname
// Module: example.com/service -> Bundle ID: com.example.service.appname
// No module info available -> Bundle ID: dev.username.appname (or local.app.appname)
//
// This replaces the old generic "com.macgo.*" format with meaningful,
// unique identifiers that reflect your actual project.
cfg := &macgo.Config{
AppName: "MyTool",
// BundleID is automatically inferred from Go module if not specified
Permissions: []macgo.Permission{macgo.Files},
}
err := macgo.Start(cfg)
if err != nil {
// Handle error
return
}
// Bundle ID automatically generated based on module path
}
Example (EnvironmentVariables) ¶
Example showing environment variables
package main
import (
"os"
"github.com/tmc/macgo"
)
func main() {
// Environment variables that control macgo behavior:
// MACGO_NO_RELAUNCH=1 - Skip bundle creation and relaunch
// MACGO_DEBUG=1 - Enable debug logging
// MACGO_RESET_PERMISSIONS=1 - Reset TCC permissions using tccutil
// MACGO_APP_NAME=MyApp - Set application name
// MACGO_APP_NAME_PREFIX=Dev- - Add prefix to all app names
// MACGO_BUNDLE_ID=com.example - Set bundle identifier
// MACGO_BUNDLE_ID_PREFIX=dev - Add prefix to all bundle IDs
// MACGO_KEEP_BUNDLE=1 - Preserve bundle after execution
// MACGO_CODE_SIGN_IDENTITY=xyz - Set code signing identity
// MACGO_AUTO_SIGN=1 - Enable automatic code signing
// MACGO_AD_HOC_SIGN=1 - Use ad-hoc code signing
// MACGO_CAMERA=1 - Request camera permissions
// MACGO_MICROPHONE=1 - Request microphone permissions
// MACGO_LOCATION=1 - Request location permissions
// MACGO_FILES=1 - Request file access permissions
// MACGO_NETWORK=1 - Request network permissions
// MACGO_SANDBOX=1 - Enable app sandbox
// Example: Reset permissions before requesting new ones
_ = os.Setenv("MACGO_RESET_PERMISSIONS", "1")
_ = os.Setenv("MACGO_DEBUG", "1")
defer func() {
_ = os.Unsetenv("MACGO_RESET_PERMISSIONS")
_ = os.Unsetenv("MACGO_DEBUG")
}()
err := macgo.Request(macgo.Camera)
if err != nil {
// Handle error
return
}
// Permissions reset and then requested
}
Index ¶
- Constants
- func Auto() error
- func Cleanup()deprecated
- func LaunchAppBundle(bundlePath string) error
- func Request(perms ...Permission) error
- func SetUIMode(mode UIMode) error
- func Start(cfg *Config) error
- func StartContext(ctx context.Context, cfg *Config) error
- type Config
- func (c *Config) FromEnv() *Config
- func (c *Config) Validate() error
- func (c *Config) WithAdHocSign() *Config
- func (c *Config) WithAppGroups(groups ...string) *Config
- func (c *Config) WithAppName(name string) *Config
- func (c *Config) WithAutoSign() *Config
- func (c *Config) WithCodeSigning(identity string) *Config
- func (c *Config) WithCustom(entitlements ...string) *Config
- func (c *Config) WithCustomArray(key string, values ...string) *Config
- func (c *Config) WithCustomString(key, value string) *Config
- func (c *Config) WithDebug() *Config
- func (c *Config) WithDevMode() *Config
- func (c *Config) WithIcon(path string) *Config
- func (c *Config) WithInfo(key string, value interface{}) *Config
- func (c *Config) WithPermissions(perms ...Permission) *Config
- func (c *Config) WithPostCreateHook(fn func(bundlePath string, cfg *Config) error) *Config
- func (c *Config) WithProvisioningProfile(path string) *Config
- func (c *Config) WithSingleProcess() *Config
- func (c *Config) WithUIMode(mode UIMode) *Config
- func (c *Config) WithUsageDescription(key, description string) *Config
- type Error
- type Permission
- type UIMode
Examples ¶
Constants ¶
const ( Camera = permissions.Camera Microphone = permissions.Microphone Location = permissions.Location ScreenRecording = permissions.ScreenRecording Accessibility = permissions.Accessibility Files = permissions.Files Network = permissions.Network Sandbox = permissions.Sandbox )
Core permissions covering 95% of use cases. Re-exported from the permissions package for convenience.
const ( // UIModeBackground sets LSBackgroundOnly=true. No UI at all. // Use for CLI tools, MCP servers, daemons. Prevents -1712 timeout. // This is the default. UIModeBackground = bundle.UIModeBackground // UIModeAccessory sets LSUIElement=true. Can show windows/menu bar but no Dock icon. // Use for menu bar apps, floating utilities. UIModeAccessory = bundle.UIModeAccessory // UIModeRegular is a normal app with Dock icon and full UI. // Use for standard GUI applications. UIModeRegular = bundle.UIModeRegular )
Variables ¶
This section is empty.
Functions ¶
func Auto ¶
func Auto() error
Auto loads configuration from environment variables and starts macgo. Useful for external configuration without code changes. Equivalent to Start(NewConfig().FromEnv()).
func Cleanup
deprecated
func Cleanup()
Cleanup should be called when the macgo-wrapped application exits. Cleanup is a no-op retained for backward compatibility. Previously it wrote a sentinel file to signal the parent that the child had exited. With FIFO-based I/O forwarding, pipe EOF serves as the exit signal and no sentinel is needed.
Deprecated: No longer required. Safe to remove from callers.
func LaunchAppBundle ¶
LaunchAppBundle launches an app bundle using the open command. This ensures proper registration with TCC for permission dialogs.
func Request ¶
func Request(perms ...Permission) error
Request is a convenience function for requesting specific permissions. Creates a minimal config and starts macgo immediately. Respects MACGO_DEBUG environment variable for debug output.
Example (Basic) ¶
package main
import (
"github.com/tmc/macgo"
)
func main() {
// Simple permission request
err := macgo.Request(macgo.Camera, macgo.Microphone)
if err != nil {
// Handle error
return
}
// App now has camera and microphone permissions
}
Example (Files) ¶
package main
import (
"github.com/tmc/macgo"
)
func main() {
// Request file access permissions
err := macgo.Request(macgo.Files)
if err != nil {
// Handle error
return
}
// App now has file access permissions
}
func Start ¶
Start initializes macgo with the given configuration. Creates an app bundle if needed and handles permission requests. On non-macOS platforms, this is a no-op that returns a no-op function and nil error.
Example (Basic) ¶
package main
import (
"github.com/tmc/macgo"
)
func main() {
// Using Start with configuration
cfg := &macgo.Config{
AppName: "MyApp",
Permissions: []macgo.Permission{macgo.Camera},
Debug: false,
}
err := macgo.Start(cfg)
if err != nil {
// Handle error
return
}
// App now running with configuration
}
Example (Comprehensive) ¶
package main
import (
"github.com/tmc/macgo"
)
func main() {
// Comprehensive configuration example
cfg := &macgo.Config{
AppName: "ComprehensiveApp",
BundleID: "com.example.comprehensive",
Version: "1.0.0",
Permissions: []macgo.Permission{
macgo.Camera,
macgo.Microphone,
macgo.Files,
macgo.Network,
},
Custom: []string{
"com.apple.security.device.capture",
"com.apple.security.automation.apple-events",
},
Debug: true,
AutoSign: true,
CleanupBundle: false,
}
err := macgo.Start(cfg)
if err != nil {
// Handle error
return
}
// App running with full configuration
}
Types ¶
type Config ¶
type Config struct {
// AppName is the application name. Defaults to executable name.
AppName string
// BundleID is the bundle identifier. Defaults to module-based ID (e.g., com.github.user.repo.appname).
BundleID string
// Version is the application version. Defaults to "1.0.0".
Version string
// Permissions are the requested macOS permissions.
Permissions []Permission
// Custom allows specifying custom entitlements not covered by Permission constants.
Custom []string
// CustomStrings allows specifying custom entitlements with string values.
// Use WithCustomString to add entries (e.g. com.apple.application-identifier).
CustomStrings map[string]string
// CustomArrays allows specifying custom entitlements with string array values.
// Use WithCustomArray to add entries.
CustomArrays map[string][]string
// AppGroups specifies app group identifiers for sharing data between apps.
// Requires sandbox permission and com.apple.security.application-groups entitlement.
AppGroups []string
// Debug enables debug logging.
Debug bool
// CleanupBundle enables cleanup of the app bundle after execution.
// Defaults to false (bundle is kept for reuse).
CleanupBundle bool
// CodeSignIdentity is the signing identity to use for code signing.
// If empty and AutoSign is false, the app bundle will not be signed.
// Use "Developer ID Application" for automatic identity selection.
CodeSignIdentity string
// AutoSign enables automatic detection of Developer ID certificates.
// If true and CodeSignIdentity is empty, macgo will try to find and use
// a Developer ID Application certificate automatically.
AutoSign bool
// AdHocSign enables ad-hoc code signing using the "-" identity.
// Ad-hoc signing provides basic code signing without requiring certificates.
// This is useful for development and testing.
AdHocSign bool
// CodeSigningIdentifier is the identifier to use for code signing.
// If empty, defaults to the bundle identifier.
CodeSigningIdentifier string
// ForceDirectExecution forces direct execution instead of LaunchServices.
// This preserves terminal I/O (stdin/stdout/stderr) but may not trigger
// proper TCC dialogs. Use this for CLI commands that need terminal output.
// Note: LaunchServices is used by default to ensure TCC compatibility.
ForceDirectExecution bool
// Info allows specifying custom Info.plist keys.
// This is useful for UsageDescriptions (e.g. NSAccessibilityUsageDescription).
Info map[string]interface{}
// UIMode controls how the app appears in the UI.
// Default (UIModeBackground): LSBackgroundOnly=true for CLI tools.
UIMode UIMode
// DevMode creates a stable wrapper bundle that exec's the original binary.
// This preserves TCC permissions across rebuilds since only the wrapper is signed.
// Enable via MACGO_DEV_MODE=1 for development workflows where you rebuild frequently.
DevMode bool
// ProvisioningProfile is the path to a provisioning profile (.provisionprofile or .mobileprovision).
// When specified, the profile is embedded in the bundle as Contents/embedded.provisionprofile.
// Required for entitlements like keychain-access-groups.
ProvisioningProfile string
// IconPath is the path to an .icns file to use as the app icon.
// When specified, the icon is copied to Contents/Resources/ and
// CFBundleIconFile is set in the Info.plist.
IconPath string
// SingleProcess enables single-process mode: codesign in-place, re-exec,
// and call setActivationPolicy instead of creating an app bundle.
// This eliminates the two-process architecture entirely.
// Enable via MACGO_SINGLE_PROCESS=1 or WithSingleProcess().
SingleProcess bool
// PostCreateHook is called after the bundle structure is created but
// before code signing. Use this to inject additional files (helper
// binaries, LaunchDaemon plists) into Contents/. The bundlePath
// argument is the .app directory path.
PostCreateHook func(bundlePath string, cfg *Config) error
}
Config holds macgo configuration options. The zero value is valid and uses sensible defaults. Use NewConfig() and builder methods for fluent configuration.
Example (AppGroups) ¶
Example showing app groups for sharing data between sandboxed apps
package main
import (
"github.com/tmc/macgo"
)
func main() {
// App groups allow sandboxed apps to share data
cfg := &macgo.Config{
AppName: "AppGroupsExample",
BundleID: "com.example.appgroups.demo",
Permissions: []macgo.Permission{
macgo.Sandbox, // Required for app groups
},
AppGroups: []string{
"TEAMID.shared-data", // TEAMID placeholder gets automatically substituted
},
Debug: true,
AutoSign: true,
}
err := macgo.Start(cfg)
if err != nil {
// Handle error
return
}
// App now has access to shared app group container
}
Example (AppGroupsBuilder) ¶
Example using builder pattern for app groups
package main
import (
"github.com/tmc/macgo"
)
func main() {
// Using builder pattern with app groups
cfg := macgo.NewConfig().
WithAppName("AppGroupBuilder").
WithPermissions(macgo.Sandbox).
WithAppGroups("TEAMID.shared-data"). // TEAMID placeholder gets automatically substituted
WithDebug()
err := macgo.Start(cfg)
if err != nil {
// Handle error
return
}
// App configured with app groups using builder pattern
}
Example (Builder) ¶
package main
import (
"github.com/tmc/macgo"
)
func main() {
// Using builder pattern with Config
cfg := macgo.NewConfig().
WithAppName("BuilderApp").
WithPermissions(macgo.Camera, macgo.Microphone).
WithCustom("com.apple.security.device.capture").
WithDebug()
err := macgo.Start(cfg)
if err != nil {
// Handle error
return
}
// App configured using builder pattern
}
Example (FromEnv) ¶
package main
import (
"github.com/tmc/macgo"
)
func main() {
// Environment-based configuration
// Set MACGO_CAMERA=1, MACGO_DEBUG=1, etc.
cfg := macgo.NewConfig().FromEnv()
err := macgo.Start(cfg)
if err != nil {
// Handle error
return
}
// App configured from environment variables
}
func NewConfig ¶
func NewConfig() *Config
NewConfig creates a new Config with sensible defaults. The zero value is valid, so this is equivalent to &Config{}.
func (*Config) FromEnv ¶
FromEnv loads configuration from environment variables. This provides explicit configuration without magic init() functions.
Supported environment variables:
MACGO_APP_NAME - Application name MACGO_APP_NAME_PREFIX - Prefix to add to all app names MACGO_BUNDLE_ID - Bundle identifier MACGO_BUNDLE_ID_PREFIX - Prefix to add to all bundle IDs MACGO_DEBUG=1 - Enable debug logging MACGO_KEEP_BUNDLE=1 - Preserve bundle after execution MACGO_CODE_SIGN_IDENTITY - Code signing identity MACGO_AUTO_SIGN=1 - Enable automatic code signing MACGO_AD_HOC_SIGN=1 - Enable ad-hoc code signing MACGO_CAMERA=1 - Request camera permission MACGO_MICROPHONE=1 - Request microphone permission MACGO_LOCATION=1 - Request location permission MACGO_SCREEN_RECORDING=1 - Request screen recording permission MACGO_FILES=1 - Request file access permission MACGO_NETWORK=1 - Request network permission MACGO_SANDBOX=1 - Enable app sandbox MACGO_FORCE_LAUNCH_SERVICES=1 - Force use of LaunchServices MACGO_FORCE_DIRECT=1 - Force direct execution MACGO_TTY_PASSTHROUGH=1 - Pass TTY device to child (experimental; default: pipe-based I/O) MACGO_OPEN_NEW_INSTANCE=0 - Disable -n flag (new instance) for open command (enabled by default) MACGO_DEV_MODE=1 - Dev mode: wrapper exec's original binary, preserves TCC across rebuilds MACGO_PROVISIONING_PROFILE - Path to provisioning profile to embed in bundle MACGO_ICON - Path to app icon (.icns) to embed in bundle MACGO_SINGLE_PROCESS=1 - Single-process mode: codesign + re-exec, no app bundle
func (*Config) Validate ¶
Validate checks the configuration for common issues and dependency requirements. Returns an error if the configuration is invalid.
func (*Config) WithAdHocSign ¶
WithAdHocSign enables ad-hoc code signing using the "-" identity. Ad-hoc signing provides basic code integrity without requiring certificates. Useful for development and testing.
func (*Config) WithAppGroups ¶
WithAppGroups adds app group identifiers for sharing data between sandboxed apps. Requires Sandbox permission. Use reverse-DNS format (e.g. "group.com.example.shared").
func (*Config) WithAppName ¶
WithAppName sets the application name for the bundle. If empty, defaults to the executable name.
func (*Config) WithAutoSign ¶
WithAutoSign enables automatic detection and use of Developer ID certificates. macgo will search for and use an available Developer ID Application certificate.
func (*Config) WithCodeSigning ¶
WithCodeSigning enables code signing with the specified identity. Use "Developer ID Application" for automatic identity selection.
func (*Config) WithCustom ¶
WithCustom adds custom entitlements not covered by Permission constants. Use full entitlement identifiers (e.g. "com.apple.security.device.capture").
func (*Config) WithCustomArray ¶
WithCustomArray adds a custom entitlement with a string array value. Use for entitlements that require an array instead of a boolean (e.g. "com.apple.developer.applesignin" with values ["Default"]).
func (*Config) WithCustomString ¶
WithCustomString adds a custom entitlement with a string value. Use for entitlements that require a string instead of a boolean (e.g. "com.apple.application-identifier" or "com.apple.developer.team-identifier").
func (*Config) WithDevMode ¶
WithDevMode enables development mode where a stable wrapper exec's the original binary. This preserves TCC permissions across rebuilds since the wrapper's signature stays stable. Use this when actively developing and rebuilding frequently.
func (*Config) WithIcon ¶
WithIcon sets the path to an .icns file to use as the app icon. The icon is copied into the bundle's Resources directory.
func (*Config) WithPermissions ¶
func (c *Config) WithPermissions(perms ...Permission) *Config
WithPermissions adds macOS system permissions to request. Permissions are additive - multiple calls append to the list.
func (*Config) WithPostCreateHook ¶
WithPostCreateHook sets a function to run after the bundle is created but before code signing. This allows injecting additional files (helper binaries, LaunchDaemon plists) into the bundle's Contents/ directory.
func (*Config) WithProvisioningProfile ¶
WithProvisioningProfile sets the path to a provisioning profile to embed in the bundle. The profile will be copied to Contents/embedded.provisionprofile. Required for entitlements like keychain-access-groups.
When present, com.apple.application-identifier and com.apple.developer.team-identifier are automatically extracted from the profile and injected as string entitlements. Values set explicitly via WithCustomString take precedence over auto-derived values.
func (*Config) WithSingleProcess ¶
WithSingleProcess enables single-process mode: codesign in-place, re-exec, and call setActivationPolicy. No app bundle is created. Only works for entitlement-only permissions (Accessibility, Virtualization, Network); TCC-dialog permissions (Camera, Microphone, Location) require app bundles.
func (*Config) WithUIMode ¶
WithUIMode sets how the app appears in the macOS UI. Options: UIModeBackground (default), UIModeAccessory, UIModeRegular
func (*Config) WithUsageDescription ¶
WithUsageDescription sets a usage description string for a specific permission. This is required for permissions like Accessibility, Camera, etc. to trigger prompts. Example: WithUsageDescription("NSAccessibilityUsageDescription", "Needed to inspect UI")
type Error ¶
type Error struct {
Op string // Operation that failed (e.g., "create bundle", "code sign")
Err error // Underlying error
Help string // Actionable guidance for the user
}
Error represents a macgo error with additional context and actionable guidance.
type Permission ¶
type Permission = permissions.Permission
Permission represents a macOS system permission that can be requested. These correspond to TCC (Transparency, Consent, Control) permission types. This is an alias for permissions.Permission for convenience.
Example (Constants) ¶
package main
import (
"github.com/tmc/macgo"
)
func main() {
// All available permission constants
permissions := []macgo.Permission{
macgo.Camera, // Camera access
macgo.Microphone, // Microphone access
macgo.Location, // Location services
macgo.Files, // File access
macgo.Network, // Network access
macgo.Sandbox, // App sandbox
}
err := macgo.Request(permissions...)
if err != nil {
// Handle error
return
}
// App has all permissions
}
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
lsopen
command
Command lsopen is a pure Go replacement for /usr/bin/open on macOS.
|
Command lsopen is a pure Go replacement for /usr/bin/open on macOS. |
|
macgo
command
Command macgo provides signing diagnostics, bundle inspection, and code signing for macOS app bundles.
|
Command macgo provides signing diagnostics, bundle inspection, and code signing for macOS app bundles. |
|
macgo-cleanup
command
Package main provides a utility to find and kill orphaned xpcproxy processes.
|
Package main provides a utility to find and kill orphaned xpcproxy processes. |
|
examples
|
|
|
env-dump
command
env-dump: Simple test app that writes environment variables to a file Used to verify whether `open --env` passes env vars to .app bundles
|
env-dump: Simple test app that writes environment variables to a file Used to verify whether `open --env` passes env vars to .app bundles |
|
mouse-click
command
mouse-click: Perform a mouse click at absolute screen coordinates using CGEvent APIs By default, smoothly moves to the target, clicks, and returns to original position
|
mouse-click: Perform a mouse click at absolute screen coordinates using CGEvent APIs By default, smoothly moves to the target, clicks, and returns to original position |
|
mouse-move
command
mouse-move: Move mouse cursor with natural human-like movement using CGEvent APIs
|
mouse-move: Move mouse cursor with natural human-like movement using CGEvent APIs |
|
sigquit-test
command
sigquit-test is a simple program to test SIGQUIT stack dumps with macgo.
|
sigquit-test is a simple program to test SIGQUIT stack dumps with macgo. |
|
sysprefs-manager
command
|
|
|
internal
|
|
|
bundle
Package bundle provides macOS app bundle creation and management functionality.
|
Package bundle provides macOS app bundle creation and management functionality. |
|
launch
Package launch provides application launching strategies for macOS app bundles.
|
Package launch provides application launching strategies for macOS app bundles. |
|
launchservices
Package launchservices provides pure Go bindings for the macOS LaunchServices private SPI _LSOpenURLsWithCompletionHandler, the same function that /usr/bin/open uses internally.
|
Package launchservices provides pure Go bindings for the macOS LaunchServices private SPI _LSOpenURLsWithCompletionHandler, the same function that /usr/bin/open uses internally. |
|
plist
Package plist provides utilities for generating macOS property list files.
|
Package plist provides utilities for generating macOS property list files. |
|
system
Package system provides internal system-level utilities for macgo.
|
Package system provides internal system-level utilities for macgo. |
|
tcc
Package tcc provides TCC (Transparency, Consent, Control) permission utilities.
|
Package tcc provides TCC (Transparency, Consent, Control) permission utilities. |
|
Package sysprefpane provides functions to open macOS System Settings panes.
|
Package sysprefpane provides functions to open macOS System Settings panes. |
|
Package teamid provides Apple Developer Team ID detection and validation.
|
Package teamid provides Apple Developer Team ID detection and validation. |