Skip to content

Automating Safari Configuration on macOS: Complete Scripting Guide

Published: at 12:49 AM

Automating Safari Configuration on macOS

Automating Safari configuration on macOS is essential for system administrators, IT departments, and developers who need to deploy standardized browser settings across multiple systems. This guide provides comprehensive scripts and techniques for managing Safari preferences programmatically.

Table of Contents

Open Table of Contents

Why Automate Safari Configuration?

Common Use Cases

Benefits of Automation

Basic Safari Configuration Script

Shell Script Approach

Here’s a comprehensive shell script for automating Safari configuration:

#!/bin/bash

# Quit Safari to ensure changes take effect
osascript -e 'tell application "Safari" to quit'
sleep 2

# Set homepage and window behavior using defaults
defaults write com.apple.Safari HomePage -string "https://infopercept.com"
defaults write com.apple.Safari NewWindowBehavior -int 0
defaults write com.apple.Safari NewTabBehavior -int 0

# Force preferences to reload
killall cfprefsd

# Reopen Safari
sleep 2
open -a Safari
sleep 3

# Use AppleScript to configure homepage in Safari Preferences
osascript <<EOF
tell application "System Events"
    tell process "Safari"
        delay 2
        keystroke "," using command down -- Open Preferences
        delay 2
        -- Navigate to Homepage field
        keystroke tab
        keystroke tab
        keystroke tab
        keystroke tab
        delay 1
        -- Select existing text and replace with homepage URL
        keystroke "a" using command down
        delay 0.5
        keystroke "https://infopercept.com"
        delay 0.5
        keystroke return
        -- Close Preferences
        keystroke "w" using command down
    end tell
end tell
EOF

echo "βœ… Safari homepage successfully set to https://infopercept.com"

AppleScript-Only Approach

For a cleaner AppleScript-only implementation:

#!/usr/bin/osascript

-- Quit Safari to ensure preferences apply
tell application "Safari" to quit
delay 2

-- Set homepage and open behavior using shell commands
do shell script "defaults write com.apple.Safari HomePage -string 'https://infopercept.com'"
do shell script "defaults write com.apple.Safari NewWindowBehavior -int 0"
do shell script "defaults write com.apple.Safari NewTabBehavior -int 0"
do shell script "killall cfprefsd"

-- Open Safari
delay 2
tell application "Safari" to activate

return "Safari homepage successfully set to https://infopercept.com"

Advanced Configuration Options

Comprehensive Safari Settings

#!/bin/bash

# Safari Configuration Script
# Configures multiple Safari preferences for enterprise deployment

HOMEPAGE_URL="https://your-company.com"
COMPANY_NAME="Your Company"

echo "πŸ”§ Configuring Safari for $COMPANY_NAME..."

# Quit Safari
osascript -e 'tell application "Safari" to quit' 2>/dev/null
sleep 3

# Homepage and New Window/Tab Behavior
defaults write com.apple.Safari HomePage -string "$HOMEPAGE_URL"
defaults write com.apple.Safari NewWindowBehavior -int 0  # Homepage
defaults write com.apple.Safari NewTabBehavior -int 0     # Homepage

# Security Settings
defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaEnabled -bool false
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaEnabledForLocalFiles -bool false

# Privacy Settings
defaults write com.apple.Safari SendDoNotTrackHTTPHeader -bool true
defaults write com.apple.Safari WebKitStorageBlockingPolicy -int 1
defaults write com.apple.Safari BlockStoragePolicy -int 1

# Developer Settings (Optional)
defaults write com.apple.Safari IncludeDevelopMenu -bool true
defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled -bool true

# Search Engine Settings
defaults write com.apple.Safari SearchProviderIdentifier -string "com.google.www"

# Appearance Settings
defaults write com.apple.Safari ShowFavoritesBar -bool true
defaults write com.apple.Safari ShowSidebar -bool false

# Tab Settings
defaults write com.apple.Safari TabCreationPolicy -int 1
defaults write com.apple.Safari OpenNewTabsInFront -bool false

# Download Settings
defaults write com.apple.Safari DownloadsClearingPolicy -int 1

# Force preferences daemon to reload
killall cfprefsd

echo "βœ… Safari configuration completed for $COMPANY_NAME"

# Optionally restart Safari
read -p "Would you like to restart Safari now? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    open -a Safari
    echo "πŸš€ Safari restarted with new configuration"
fi

Security-Focused Configuration

#!/bin/bash

# High-Security Safari Configuration
# Suitable for corporate environments with strict security requirements

echo "πŸ”’ Applying high-security Safari configuration..."

# Quit Safari
osascript -e 'tell application "Safari" to quit' 2>/dev/null
sleep 2

# Security Settings
defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
defaults write com.apple.Safari AutoFillFromAddressBook -bool false
defaults write com.apple.Safari AutoFillPasswords -bool false
defaults write com.apple.Safari AutoFillCreditCardData -bool false
defaults write com.apple.Safari AutoFillMiscellaneousForms -bool false

# Disable plugins and Java
defaults write com.apple.Safari WebKitPluginsEnabled -bool false
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2PluginsEnabled -bool false
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaEnabled -bool false
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaEnabledForLocalFiles -bool false

# Enable Do Not Track
defaults write com.apple.Safari SendDoNotTrackHTTPHeader -bool true

# Block pop-ups
defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically -bool false
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaScriptCanOpenWindowsAutomatically -bool false

# Prevent cross-site tracking
defaults write com.apple.Safari WebKitStorageBlockingPolicy -int 1
defaults write com.apple.Safari BlockStoragePolicy -int 1

# Disable location services
defaults write com.apple.Safari SafariGeolocationPermissionPolicy -int 0

# Clear downloads list when Safari quits
defaults write com.apple.Safari DownloadsClearingPolicy -int 1

# Force HTTPS where possible (if available)
defaults write com.apple.Safari ForceHTTPS -bool true

killall cfprefsd

echo "βœ… High-security Safari configuration applied"

Enterprise Deployment Strategies

Mass Deployment Script

#!/bin/bash

# Enterprise Safari Deployment Script
# Supports multiple users and system-wide configuration

SCRIPT_NAME="Safari Enterprise Configuration"
LOG_FILE="/var/log/safari_config.log"
CONFIG_VERSION="1.0"

# Logging function
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Check if running as admin
check_admin() {
    if [[ $EUID -ne 0 ]]; then
        echo "This script must be run as administrator (sudo)"
        exit 1
    fi
}

# Configure Safari for specific user
configure_user_safari() {
    local username=$1
    local user_home="/Users/$username"

    if [[ ! -d "$user_home" ]]; then
        log_message "ERROR: User home directory not found for $username"
        return 1
    fi

    log_message "Configuring Safari for user: $username"

    # Run configuration as the specific user
    sudo -u "$username" defaults write com.apple.Safari HomePage -string "https://company-portal.com"
    sudo -u "$username" defaults write com.apple.Safari NewWindowBehavior -int 0
    sudo -u "$username" defaults write com.apple.Safari NewTabBehavior -int 0
    sudo -u "$username" defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
    sudo -u "$username" defaults write com.apple.Safari SendDoNotTrackHTTPHeader -bool true

    log_message "Safari configuration completed for user: $username"
}

# Main execution
main() {
    log_message "Starting $SCRIPT_NAME v$CONFIG_VERSION"

    check_admin

    # Get all user accounts (excluding system accounts)
    users=$(dscl . list /Users | grep -v "^_" | grep -v "daemon\|nobody\|root")

    for user in $users; do
        # Skip if user UID is less than 500 (system accounts)
        user_id=$(id -u "$user" 2>/dev/null)
        if [[ $user_id -ge 500 ]] 2>/dev/null; then
            configure_user_safari "$user"
        fi
    done

    # System-wide configuration using Configuration Profiles (if needed)
    create_configuration_profile

    log_message "$SCRIPT_NAME completed successfully"
}

# Create Configuration Profile for MDM deployment
create_configuration_profile() {
    local profile_path="/tmp/safari_config.mobileconfig"

    cat > "$profile_path" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadDisplayName</key>
            <string>Safari Settings</string>
            <key>PayloadIdentifier</key>
            <string>com.company.safari.settings</string>
            <key>PayloadType</key>
            <string>com.apple.Safari</string>
            <key>PayloadUUID</key>
            <string>$(uuidgen)</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>HomePage</key>
            <string>https://company-portal.com</string>
            <key>NewWindowBehavior</key>
            <integer>0</integer>
            <key>NewTabBehavior</key>
            <integer>0</integer>
            <key>AutoOpenSafeDownloads</key>
            <false/>
            <key>SendDoNotTrackHTTPHeader</key>
            <true/>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>Safari Configuration</string>
    <key>PayloadIdentifier</key>
    <string>com.company.safari</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>$(uuidgen)</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>
EOF

    log_message "Configuration profile created at: $profile_path"
}

# Run main function
main "$@"

Remote Deployment via SSH

#!/bin/bash

# Remote Safari Configuration Deployment
# Deploy Safari settings to multiple macOS systems via SSH

TARGETS_FILE="macos_targets.txt"
CONFIG_SCRIPT="safari_config.sh"
SSH_USER="admin"
SSH_KEY="~/.ssh/id_rsa"

# Read target systems from file
if [[ ! -f "$TARGETS_FILE" ]]; then
    echo "Error: Target systems file '$TARGETS_FILE' not found"
    echo "Create a file with one hostname/IP per line"
    exit 1
fi

# Deploy to each target
while IFS= read -r target; do
    [[ -z "$target" ]] && continue

    echo "πŸ”„ Deploying to: $target"

    # Copy script to target system
    scp -i "$SSH_KEY" "$CONFIG_SCRIPT" "$SSH_USER@$target:/tmp/"

    # Execute script on target system
    ssh -i "$SSH_KEY" "$SSH_USER@$target" "chmod +x /tmp/$CONFIG_SCRIPT && sudo /tmp/$CONFIG_SCRIPT"

    if [[ $? -eq 0 ]]; then
        echo "βœ… Successfully configured: $target"
    else
        echo "❌ Failed to configure: $target"
    fi

    # Clean up
    ssh -i "$SSH_KEY" "$SSH_USER@$target" "rm -f /tmp/$CONFIG_SCRIPT"

    echo "---"
done < "$TARGETS_FILE"

echo "πŸŽ‰ Remote deployment completed"

Troubleshooting and Validation

Validation Script

#!/bin/bash

# Safari Configuration Validation Script
# Verifies that Safari settings have been applied correctly

echo "πŸ” Validating Safari configuration..."

# Function to check a setting
check_setting() {
    local key=$1
    local expected=$2
    local domain=${3:-com.apple.Safari}

    current=$(defaults read "$domain" "$key" 2>/dev/null)

    if [[ "$current" == "$expected" ]]; then
        echo "βœ… $key: $current (correct)"
        return 0
    else
        echo "❌ $key: $current (expected: $expected)"
        return 1
    fi
}

# Check critical settings
echo "Checking Safari preferences..."

check_setting "HomePage" "https://infopercept.com"
check_setting "NewWindowBehavior" "0"
check_setting "NewTabBehavior" "0"
check_setting "AutoOpenSafeDownloads" "0"
check_setting "SendDoNotTrackHTTPHeader" "1"

# Check if Safari is configured to show the homepage
echo ""
echo "🏠 Homepage configuration:"
homepage=$(defaults read com.apple.Safari HomePage 2>/dev/null)
echo "Current homepage: $homepage"

# Check Safari version
echo ""
echo "ℹ️ Safari information:"
safari_version=$(osascript -e 'tell application "Safari" to version' 2>/dev/null)
echo "Safari version: $safari_version"

# Check if configuration profiles are installed
echo ""
echo "πŸ“‹ Configuration profiles:"
profiles -P 2>/dev/null | grep -i safari || echo "No Safari configuration profiles found"

echo ""
echo "🎯 Validation completed"

Common Issues and Solutions

Issue: Settings Don’t Persist

# Force preferences to reload and persist
killall cfprefsd
defaults synchronize

Issue: AppleScript UI Automation Fails

# Enable accessibility permissions for Terminal/script
# Check System Preferences > Security & Privacy > Privacy > Accessibility

Issue: Preferences Revert After User Login

# Use Configuration Profiles for persistent settings
sudo profiles install -path safari_config.mobileconfig

Debugging Script

#!/bin/bash

# Safari Configuration Debug Script
# Helps diagnose configuration issues

echo "πŸ”§ Safari Configuration Debug Information"
echo "========================================"

# Check Safari installation
if [[ -d "/Applications/Safari.app" ]]; then
    echo "βœ… Safari is installed"
    safari_version=$(defaults read /Applications/Safari.app/Contents/Info.plist CFBundleShortVersionString)
    echo "   Version: $safari_version"
else
    echo "❌ Safari is not installed"
    exit 1
fi

# Check current user
echo ""
echo "πŸ‘€ Current user: $(whoami)"
echo "   User ID: $(id -u)"

# Check Safari preferences
echo ""
echo "βš™οΈ Current Safari preferences:"
defaults read com.apple.Safari 2>/dev/null | head -20

# Check running processes
echo ""
echo "πŸ”„ Safari-related processes:"
ps aux | grep -i safari | grep -v grep

# Check system integrity
echo ""
echo "πŸ›‘οΈ System integrity:"
if command -v csrutil &> /dev/null; then
    csrutil status
else
    echo "System Integrity Protection status unknown"
fi

# Check accessibility permissions
echo ""
echo "β™Ώ Accessibility permissions:"
sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" \
    "SELECT client, auth_value FROM access WHERE service='kTCCServiceAccessibility';" 2>/dev/null || \
    echo "Cannot check accessibility permissions (may require admin privileges)"

echo ""
echo "🎯 Debug information collection completed"

Best Practices

Security Considerations

  1. Validate Scripts: Always test scripts in a controlled environment before deployment
  2. User Permissions: Run with appropriate privileges (avoid unnecessary root access)
  3. Input Validation: Validate all user inputs and file paths
  4. Secure Distribution: Use secure channels for script distribution
  5. Audit Logging: Maintain logs of configuration changes

Error Handling

#!/bin/bash

# Robust Safari Configuration with Error Handling

set -euo pipefail  # Exit on error, undefined vars, pipe failures

LOGFILE="/var/log/safari_config.log"
HOMEPAGE_URL="https://company.com"

# Logging function
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $*" | tee -a "$LOGFILE"
}

# Error handler
error_exit() {
    log "ERROR: $1"
    exit 1
}

# Validation function
validate_url() {
    local url=$1
    if [[ ! "$url" =~ ^https?:// ]]; then
        error_exit "Invalid URL format: $url"
    fi
}

# Main configuration function
configure_safari() {
    log "Starting Safari configuration"

    validate_url "$HOMEPAGE_URL"

    # Quit Safari with error handling
    if ! osascript -e 'tell application "Safari" to quit' 2>/dev/null; then
        log "Safari was not running or failed to quit"
    fi

    sleep 2

    # Apply settings with error checking
    if ! defaults write com.apple.Safari HomePage -string "$HOMEPAGE_URL"; then
        error_exit "Failed to set homepage"
    fi

    if ! defaults write com.apple.Safari NewWindowBehavior -int 0; then
        error_exit "Failed to set new window behavior"
    fi

    # Force preferences reload
    killall cfprefsd || log "Warning: Failed to reload preferences daemon"

    log "Safari configuration completed successfully"
}

# Run main function
configure_safari

Testing Framework

#!/bin/bash

# Safari Configuration Test Suite

TEST_RESULTS=()

# Test function
run_test() {
    local test_name=$1
    local test_command=$2

    echo "Running test: $test_name"

    if eval "$test_command"; then
        echo "βœ… PASS: $test_name"
        TEST_RESULTS+=("PASS: $test_name")
    else
        echo "❌ FAIL: $test_name"
        TEST_RESULTS+=("FAIL: $test_name")
    fi
}

# Test suite
echo "πŸ§ͺ Safari Configuration Test Suite"
echo "================================="

run_test "Safari Installation" "[[ -d '/Applications/Safari.app' ]]"
run_test "Homepage Setting" "[[ \$(defaults read com.apple.Safari HomePage 2>/dev/null) == 'https://company.com' ]]"
run_test "New Window Behavior" "[[ \$(defaults read com.apple.Safari NewWindowBehavior 2>/dev/null) == '0' ]]"
run_test "Security Settings" "[[ \$(defaults read com.apple.Safari AutoOpenSafeDownloads 2>/dev/null) == '0' ]]"

# Results summary
echo ""
echo "πŸ“Š Test Results Summary:"
echo "======================="
for result in "${TEST_RESULTS[@]}"; do
    echo "$result"
done

# Count results
pass_count=$(printf '%s\n' "${TEST_RESULTS[@]}" | grep -c "PASS" || true)
fail_count=$(printf '%s\n' "${TEST_RESULTS[@]}" | grep -c "FAIL" || true)

echo ""
echo "Passed: $pass_count"
echo "Failed: $fail_count"

if [[ $fail_count -eq 0 ]]; then
    echo "πŸŽ‰ All tests passed!"
    exit 0
else
    echo "⚠️ Some tests failed"
    exit 1
fi

Conclusion

Automating Safari configuration on macOS provides significant benefits for system administrators and IT departments. By using the scripts and techniques outlined in this guide, you can:

Key Takeaways

  1. Use defaults command for persistent preference settings
  2. Combine shell scripts and AppleScript for comprehensive automation
  3. Implement proper error handling and validation
  4. Test thoroughly before enterprise deployment
  5. Document configurations for maintenance and troubleshooting

Whether you’re managing a small team or deploying across hundreds of systems, these automation techniques will help you maintain consistent, secure Safari configurations efficiently.


Remember to always test automation scripts in a controlled environment before deploying to production systems.