
Security News
Another Round of TEA Protocol Spam Floods npm, But It’s Not a Worm
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.
A clean, simple API to enable macOS App Sandbox, Hardened Runtime entitlements, and TCC permissions for Go command-line applications.
macOS requires applications to be packaged as .app bundles to access protected resources like Camera, Microphone, Files, etc. This package automatically:
Default Behavior:
com.apple.security.app-sandbox)com.apple.security.files.user-selected.read-only)LSUIElement=true)flowchart TD
A[Go Program] --> B{Already in\n.app bundle?}
B -->|Yes| C[Continue execution\nwith TCC permissions]
B -->|No| D[Create .app bundle\nwith entitlements]
D --> E[Relaunch inside bundle]
E --> F[Copy stdin/stdout/stderr\nvia named pipes]
F --> C
subgraph "Original Process"
A
B
D
end
subgraph ".app Bundle"
E
F
C
end
go get github.com/tmc/misc/macgo
macgo offers multiple approaches to configure your app bundle, from simplest to most advanced:
package main
import (
"os"
// Just import the auto package with blank identifier
_ "github.com/tmc/misc/macgo/auto"
)
// Or use pre-configured packages:
// _ "github.com/tmc/misc/macgo/auto/sandbox" // App sandbox only
// _ "github.com/tmc/misc/macgo/auto/sandbox/readonly" // App sandbox with read-only file access
func main() {
// Your code will automatically run in an app bundle
files, _ := os.ReadDir("~/Desktop")
// ...
}
Pros: Minimal code, easy for quick scripts
Cons: Less control over initialization timing
package main
import (
"os"
"github.com/tmc/misc/macgo"
)
func init() {
// Request specific entitlements
macgo.RequestEntitlements(
macgo.EntCamera,
macgo.EntMicrophone,
macgo.EntAppSandbox,
)
// Configure app details
macgo.SetAppName("MyApp")
macgo.SetBundleID("com.example.myapp")
// Optionally show in dock (hidden by default)
// macgo.EnableDockIcon()
}
func main() {
// Start macgo - this creates the app bundle and relaunches if needed
macgo.Start()
// Your code will run with the specified entitlements
files, _ := os.ReadDir("~/Desktop")
// ...
}
Pros: Clear, explicit, readable API with configuration in Go code
Cons: Slightly more verbose than blank import
package main
import (
"os"
// Import the entitlements package directly or
// import specific entitlements with blank identifier
_ "github.com/tmc/misc/macgo/entitlements/camera"
_ "github.com/tmc/misc/macgo/entitlements/mic"
"github.com/tmc/misc/macgo/entitlements"
)
func init() {
// Use the entitlements package functions if needed
entitlements.SetPhotos()
// Request multiple entitlements at once
entitlements.RequestEntitlements(
entitlements.EntAppSandbox,
entitlements.EntNetworkClient
)
}
func main() {
// Your code will have the specified entitlements
files, _ := os.ReadDir("~/Desktop")
// ...
}
Pros: Modular organization by permission type
Cons: Less direct than the main package's API
package main
import (
"github.com/tmc/misc/macgo"
)
func init() {
// Disable auto-initialization to allow complete customization
macgo.DisableAutoInit()
// Create a custom configuration
cfg := macgo.NewConfig()
// Set application details
cfg.ApplicationName = "CustomApp"
cfg.BundleID = "com.example.customapp"
// Add entitlements
cfg.AddEntitlement(macgo.EntCamera)
cfg.AddEntitlement(macgo.EntMicrophone)
// Request multiple entitlements at once
cfg.RequestEntitlements(
macgo.EntAppSandbox,
macgo.EntNetworkClient
)
// Add custom Info.plist entries
cfg.AddPlistEntry("LSUIElement", false) // Show in dock
// Control app bundle behavior
cfg.Relaunch = true // Auto-relaunch (default)
cfg.AutoSign = true // Auto-sign the bundle
cfg.KeepTemp = false // Clean up temporary bundles
// Set custom destination path (optional)
// cfg.CustomDestinationAppPath = "/Applications/CustomApp.app"
// Apply configuration (must be called)
macgo.Configure(cfg)
// Explicitly initialize macgo now that configuration is complete
macgo.Initialize()
}
func main() {
// Your code will have maximum customization
// ...
}
Pros: Maximum flexibility and control
Cons: Most verbose API, steeper learning curve
Note: When using
go run, macgo first runs your program normally, sets up the app bundle, then relaunches it inside the bundle. Settings likeLSUIElement(dock visibility) only take effect during this second run in the bundle.
Configure macgo with environment variables:
# Configure the app name and bundle ID
MACGO_APP_NAME="MyApp" MACGO_BUNDLE_ID="com.example.myapp" ./myapp
# Enable specific permissions
MACGO_CAMERA=1 MACGO_MIC=1 MACGO_PHOTOS=1 ./myapp
# Customize app bundle location and behavior
MACGO_APP_PATH="/Applications/MyApp" MACGO_KEEP_TEMP=1 ./myapp
# Enable debugging and show in dock
MACGO_DEBUG=1 MACGO_SHOW_DOCK_ICON=1 ./myapp
| Entitlement | Function | Constant | Environment Var |
|---|---|---|---|
| Camera | SetCamera() | EntCamera | MACGO_CAMERA=1 |
| Microphone | SetMic() | EntMicrophone | MACGO_MIC=1 |
| Location | SetLocation() | EntLocation | MACGO_LOCATION=1 |
| Contacts | SetContacts() | EntAddressBook | MACGO_CONTACTS=1 |
| Photos | SetPhotos() | EntPhotos | MACGO_PHOTOS=1 |
| Calendar | SetCalendar() | EntCalendars | MACGO_CALENDAR=1 |
| Reminders | SetReminders() | EntReminders | MACGO_REMINDERS=1 |
| Entitlement | Function | Constant | Environment Var |
|---|---|---|---|
| App Sandbox | SetAppSandbox() | EntAppSandbox | MACGO_APP_SANDBOX=1 |
| Outgoing Network* | SetNetworkClient() | EntNetworkClient | MACGO_NETWORK_CLIENT=1 |
| Incoming Network* | SetNetworkServer() | EntNetworkServer | MACGO_NETWORK_SERVER=1 |
*NOTE: The network entitlements only affect Objective-C/Swift network APIs. Go's standard networking (net/http, etc.) bypasses these restrictions and will work regardless of these entitlements being present or not. To properly restrict network access in Go applications, additional measures are required. | Bluetooth |
SetBluetooth()|EntBluetooth|MACGO_BLUETOOTH=1| | USB |SetUSB()|EntUSB|MACGO_USB=1| | Audio Input |SetAudioInput()|EntAudioInput|MACGO_AUDIO_INPUT=1| | Printing |SetPrinting()|EntPrint|MACGO_PRINT=1|
| Entitlement | Constant | Environment Var |
|---|---|---|
| User-Selected Files (Read) | EntUserSelectedReadOnly | MACGO_USER_FILES_READ=1 |
| User-Selected Files (Write) | EntUserSelectedReadWrite | MACGO_USER_FILES_WRITE=1 |
| Downloads Folder (Read) | EntDownloadsReadOnly | MACGO_DOWNLOADS_READ=1 |
| Downloads Folder (Write) | EntDownloadsReadWrite | MACGO_DOWNLOADS_WRITE=1 |
| Pictures Folder (Read) | EntPicturesReadOnly | MACGO_PICTURES_READ=1 |
| Pictures Folder (Write) | EntPicturesReadWrite | MACGO_PICTURES_WRITE=1 |
| Music Folder (Read) | EntMusicReadOnly | MACGO_MUSIC_READ=1 |
| Music Folder (Write) | EntMusicReadWrite | MACGO_MUSIC_WRITE=1 |
| Movies Folder (Read) | EntMoviesReadOnly | MACGO_MOVIES_READ=1 |
| Movies Folder (Write) | EntMoviesReadWrite | MACGO_MOVIES_WRITE=1 |
| Entitlement | Function | Constant | Environment Var |
|---|---|---|---|
| Allow JIT | SetAllowJIT() | EntAllowJIT | MACGO_ALLOW_JIT=1 |
| Allow Unsigned Memory | SetAllowUnsignedMemory() | EntAllowUnsignedExecutableMemory | MACGO_ALLOW_UNSIGNED_MEMORY=1 |
| Allow DYLD Env Vars | SetAllowDyldEnvVars() | EntAllowDyldEnvVars | MACGO_ALLOW_DYLD_ENV=1 |
| Disable Library Validation | SetDisableLibraryValidation() | EntDisableLibraryValidation | MACGO_DISABLE_LIBRARY_VALIDATION=1 |
| Disable Exec Page Protection | SetDisableExecutablePageProtection() | EntDisableExecutablePageProtection | MACGO_DISABLE_EXEC_PAGE_PROTECTION=1 |
| Debugger | SetDebugger() | EntDebugger | MACGO_DEBUGGER=1 |
// Request entitlements
macgo.RequestEntitlements(macgo.EntCamera, macgo.EntMicrophone)
macgo.RequestEntitlement(macgo.EntAppSandbox)
// Configure app details
macgo.SetAppName("MyApp")
macgo.SetBundleID("com.example.myapp")
// UI behavior (by default, applications are hidden from dock)
macgo.EnableDockIcon() // Show app in dock (not recommended)
// or for manual control:
macgo.AddPlistEntry("LSUIElement", true) // Hide from dock (default in macgo)
// macgo.AddPlistEntry("LSUIElement", false) // Show in dock (causes bouncing icon)
// App bundle behavior
macgo.EnableKeepTemp() // Keep temporary bundles
macgo.DisableRelaunch() // Disable auto-relaunch
macgo.EnableDebug() // Enable debug output
macgo.EnableSigning() // Enable code signing
// Configuration from embedded resources
macgo.LoadEntitlementsFromJSON(jsonData)
macgo.SetCustomAppBundle(templateFS)
// Custom Info.plist entries
macgo.AddPlistEntry("LSMinimumSystemVersion", "10.15")
macgo.AddPlistEntry("NSHighResolutionCapable", true) // Retina support
// Set groups of permissions at once
macgo.SetAllTCCPermissions() // Set all TCC permissions
macgo.SetAllDeviceAccess() // Set all device permissions
macgo.SetAllNetworking() // Set all networking permissions
go runGOPATH/bin for persistent storageMACGO_APP_NAME: Set the app bundle nameMACGO_BUNDLE_ID: Set the bundle identifierMACGO_APP_PATH: Custom path for the app bundleMACGO_NO_RELAUNCH=1: Disable automatic relaunchingMACGO_KEEP_TEMP=1: Keep temporary bundles (don't clean up)MACGO_DEBUG=1: Enable debug loggingMACGO_SHOW_DOCK_ICON=1: Show app in dock and app switcher (default: hidden)See the tables above for all available permission variables.
See the examples directory for complete examples:
The library is organized as follows:
github.com/tmc/misc/macgo - Core functionality for app bundle creationgithub.com/tmc/misc/macgo/entitlements - Central package for entitlement management
github.com/tmc/misc/macgo/entitlements/cameragithub.com/tmc/misc/macgo/entitlements/micgithub.com/tmc/misc/macgo/entitlements/locationgithub.com/tmc/misc/macgo/entitlements/all.app/Contents/MacOS/[executable name]go run) get temporary bundles with cleanupGOPATH/binGOPATH/bin must be writableEntNetworkClient, EntNetworkServer) only affect Objective-C/Swift network APIs, not Go's standard networking libraries.FAQs
Unknown package
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.

Security News
PyPI adds Trusted Publishing support for GitLab Self-Managed as adoption reaches 25% of uploads

Research
/Security News
A malicious Chrome extension posing as an Ethereum wallet steals seed phrases by encoding them into Sui transactions, enabling full wallet takeover.