Tutorial

New updates and improvements to Macfleet.

Secure Token Management on macOS

Manage secure tokens across your MacFleet devices to enable FileVault encryption, secure boot operations, and cryptographic authentication. This tutorial covers secure token verification, granting, removal, and enterprise-scale token management for enhanced security compliance.

Understanding Secure Tokens

Secure tokens are cryptographic credentials that enable users to perform security-sensitive operations on macOS, particularly essential for FileVault disk encryption:

What are Secure Tokens?

  • Cryptographic Keys - Enable access to encrypted storage and security functions
  • FileVault Requirement - Required for users to unlock FileVault-encrypted drives
  • Bootstrap Tokens - Facilitate secure boot and system recovery processes
  • Authentication Bridge - Connect user credentials to system-level security operations
  • Legacy Compatibility - Replace older authentication mechanisms in modern macOS

Secure Token Requirements

  • macOS 10.13+ - High Sierra and later versions support secure tokens
  • Admin Privileges - Granting tokens requires existing admin with secure token
  • User Authentication - Both admin and target user passwords required
  • System Integrity - SIP (System Integrity Protection) must be properly configured
  • Volume Ownership - Users need appropriate volume access permissions

Secure Token Status Verification

Check Individual User Status

#!/bin/bash

# Check secure token status for a specific user
check_user_secure_token() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        echo "❌ Usage: check_user_secure_token <username>"
        return 1
    fi
    
    # Verify user exists
    if ! id "$username" >/dev/null 2>&1; then
        echo "❌ User '$username' does not exist"
        return 1
    fi
    
    echo "🔍 Checking secure token status for user: $username"
    
    # Check secure token status
    local token_status
    token_status=$(sysadminctl -secureTokenStatus "$username" 2>&1)
    
    if echo "$token_status" | grep -q "ENABLED"; then
        echo "✅ User '$username' has secure token enabled"
        return 0
    elif echo "$token_status" | grep -q "DISABLED"; then
        echo "❌ User '$username' does not have secure token"
        return 1
    else
        echo "âš ī¸ Unable to determine secure token status for '$username'"
        echo "Output: $token_status"
        return 2
    fi
}

# Example usage
# check_user_secure_token "john.doe"

Check All Users Status

#!/bin/bash

# Check secure token status for all users
check_all_users_secure_tokens() {
    echo "🔍 Checking secure token status for all users..."
    echo ""
    
    local enabled_count=0
    local disabled_count=0
    local error_count=0
    
    # Get all users with UID >= 500 (non-system users)
    local users
    users=$(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}')
    
    printf "%-20s %-15s %-30s\n" "Username" "Status" "Details"
    printf "%-20s %-15s %-30s\n" "--------" "------" "-------"
    
    for user in $users; do
        local status
        local details=""
        
        # Skip system accounts that might have high UIDs
        if [[ "$user" =~ ^(_|com\.|root|daemon|nobody) ]]; then
            continue
        fi
        
        # Check secure token status
        local token_output
        token_output=$(sysadminctl -secureTokenStatus "$user" 2>&1)
        
        if echo "$token_output" | grep -q "ENABLED"; then
            status="✅ Enabled"
            details="Secure token active"
            ((enabled_count++))
        elif echo "$token_output" | grep -q "DISABLED"; then
            status="❌ Disabled"
            details="No secure token"
            ((disabled_count++))
        else
            status="âš ī¸ Error"
            details="Unable to determine"
            ((error_count++))
        fi
        
        printf "%-20s %-15s %-30s\n" "$user" "$status" "$details"
    done
    
    echo ""
    echo "=== Summary ==="
    echo "Users with secure token: $enabled_count"
    echo "Users without secure token: $disabled_count"
    echo "Errors/Unknown: $error_count"
    
    # Recommendations
    if [[ "$disabled_count" -gt 0 ]]; then
        echo ""
        echo "💡 $disabled_count users lack secure tokens - consider granting for FileVault access"
    fi
    
    if [[ "$enabled_count" -eq 0 ]]; then
        echo ""
        echo "âš ī¸ No users have secure tokens - system may have security limitations"
    fi
}

# Execute the check
check_all_users_secure_tokens

Granting Secure Tokens

Basic Secure Token Grant

#!/bin/bash

# Grant secure token to a user
grant_secure_token() {
    local admin_user="$1"
    local admin_password="$2"
    local target_user="$3"
    local target_password="$4"
    
    if [[ -z "$admin_user" || -z "$admin_password" || -z "$target_user" || -z "$target_password" ]]; then
        echo "❌ Usage: grant_secure_token <admin_user> <admin_password> <target_user> <target_password>"
        return 1
    fi
    
    echo "🔐 Granting secure token to user: $target_user"
    
    # Verify admin user has secure token
    echo "Verifying admin credentials..."
    local admin_token_status
    admin_token_status=$(sysadminctl -secureTokenStatus "$admin_user" 2>&1)
    
    if ! echo "$admin_token_status" | grep -q "ENABLED"; then
        echo "❌ Admin user '$admin_user' does not have secure token"
        echo "Cannot grant secure token without an admin user who already has one"
        return 1
    fi
    
    echo "✅ Admin user '$admin_user' has secure token"
    
    # Check if target user already has secure token
    echo "Checking target user status..."
    local target_token_status
    target_token_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
    
    if echo "$target_token_status" | grep -q "ENABLED"; then
        echo "â„šī¸ User '$target_user' already has secure token - no action needed"
        return 0
    fi
    
    # Grant secure token
    echo "Granting secure token to '$target_user'..."
    
    if sysadminctl \
        -adminUser "$admin_user" \
        -adminPassword "$admin_password" \
        -secureTokenOn "$target_user" \
        -password "$target_password"; then
        
        echo "✅ Successfully granted secure token to '$target_user'"
        
        # Verify the grant was successful
        echo "Verifying secure token grant..."
        local verify_status
        verify_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
        
        if echo "$verify_status" | grep -q "ENABLED"; then
            echo "✅ Verification passed - '$target_user' now has secure token"
            return 0
        else
            echo "❌ Verification failed - secure token may not have been granted properly"
            return 1
        fi
    else
        echo "❌ Failed to grant secure token to '$target_user'"
        echo "Check credentials and user permissions"
        return 1
    fi
}

# Interactive secure token grant
interactive_grant_secure_token() {
    echo "🔐 Interactive Secure Token Grant"
    echo "================================"
    
    # Get admin credentials
    read -p "Admin username: " admin_user
    read -s -p "Admin password: " admin_password
    echo ""
    
    # Get target user info
    read -p "Target username: " target_user
    read -s -p "Target user password: " target_password
    echo ""
    
    echo ""
    grant_secure_token "$admin_user" "$admin_password" "$target_user" "$target_password"
}

# Example usage (uncomment to use interactively)
# interactive_grant_secure_token

Advanced Secure Token Management

#!/bin/bash

# Advanced secure token management with validation
advanced_secure_token_grant() {
    local admin_user="$1"
    local admin_password="$2"
    local target_user="$3"
    local target_password="$4"
    local force_mode="${5:-false}"
    
    echo "🔐 Advanced Secure Token Management"
    echo "Target user: $target_user"
    echo "Admin user: $admin_user"
    echo "Force mode: $force_mode"
    echo ""
    
    # macOS version check
    local macos_version
    macos_version=$(sw_vers -productVersion)
    local macos_major
    macos_major=$(echo "$macos_version" | cut -d. -f1)
    local macos_minor
    macos_minor=$(echo "$macos_version" | cut -d. -f2)
    
    echo "macOS version: $macos_version"
    
    # Check macOS compatibility
    if [[ "$macos_major" -lt 10 ]] || [[ "$macos_major" -eq 10 && "$macos_minor" -lt 13 ]]; then
        echo "❌ Secure tokens require macOS 10.13 (High Sierra) or later"
        echo "Current version ($macos_version) is not supported"
        return 1
    fi
    
    # Verify users exist
    if ! id "$admin_user" >/dev/null 2>&1; then
        echo "❌ Admin user '$admin_user' does not exist"
        return 1
    fi
    
    if ! id "$target_user" >/dev/null 2>&1; then
        echo "❌ Target user '$target_user' does not exist"
        return 1
    fi
    
    # Check if admin user is actually an admin
    if ! dseditgroup -o checkmember -m "$admin_user" admin >/dev/null 2>&1; then
        echo "❌ User '$admin_user' is not a member of the admin group"
        return 1
    fi
    
    echo "✅ User validation passed"
    
    # Check secure token status for admin
    local admin_token_status
    admin_token_status=$(sysadminctl -secureTokenStatus "$admin_user" 2>&1)
    
    if echo "$admin_token_status" | grep -q "DISABLED"; then
        # Special handling for macOS 10.15+
        if [[ "$macos_major" -gt 10 ]] || [[ "$macos_major" -eq 10 && "$macos_minor" -gt 14 ]]; then
            echo "âš ī¸ In macOS 10.15+, secure tokens may be automatically granted"
            echo "   to the first user who enables FileVault if no other users have tokens"
            if [[ "$force_mode" != "true" ]]; then
                echo "   Use force_mode=true to bypass this check"
                return 1
            fi
        else
            echo "❌ Admin user '$admin_user' does not have secure token"
            echo "   Cannot grant token without an admin who already has one"
            return 1
        fi
    else
        echo "✅ Admin user '$admin_user' has secure token"
    fi
    
    # Check target user current status
    local target_token_status
    target_token_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
    
    if echo "$target_token_status" | grep -q "ENABLED"; then
        echo "â„šī¸ User '$target_user' already has secure token"
        if [[ "$force_mode" != "true" ]]; then
            echo "   No action needed"
            return 0
        else
            echo "   Force mode enabled - will attempt to refresh token"
        fi
    fi
    
    # Attempt to grant secure token
    echo ""
    echo "Granting secure token to '$target_user'..."
    
    local grant_output
    grant_output=$(sysadminctl \
        -adminUser "$admin_user" \
        -adminPassword "$admin_password" \
        -secureTokenOn "$target_user" \
        -password "$target_password" 2>&1)
    
    local grant_result=$?
    
    if [[ $grant_result -eq 0 ]]; then
        echo "✅ Secure token grant command executed successfully"
    else
        echo "❌ Secure token grant command failed"
        echo "Output: $grant_output"
        return 1
    fi
    
    # Verify the result
    echo "Verifying secure token status..."
    local final_status
    final_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
    
    if echo "$final_status" | grep -q "ENABLED"; then
        echo "✅ Verification successful - '$target_user' now has secure token"
        
        # Additional checks
        echo ""
        echo "=== Additional Information ==="
        echo "FileVault eligibility: User can now unlock FileVault volumes"
        echo "Security operations: User can perform cryptographic operations"
        echo "System recovery: User can participate in secure boot processes"
        
        return 0
    elif echo "$final_status" | grep -q "DISABLED"; then
        echo "❌ Verification failed - secure token was not granted"
        echo "This may indicate:"
        echo "  - Incorrect credentials"
        echo "  - System security restrictions"
        echo "  - FileVault configuration issues"
        return 1
    else
        echo "âš ī¸ Unexpected result from verification"
        echo "Status output: $final_status"
        return 2
    fi
}

Bulk Secure Token Management

Batch Grant Operations

#!/bin/bash

# Batch grant secure tokens to multiple users
batch_grant_secure_tokens() {
    local admin_user="$1"
    local admin_password="$2"
    local user_file="$3"
    
    if [[ -z "$admin_user" || -z "$admin_password" || -z "$user_file" ]]; then
        echo "❌ Usage: batch_grant_secure_tokens <admin_user> <admin_password> <user_file>"
        echo "User file format: username:password (one per line)"
        return 1
    fi
    
    if [[ ! -f "$user_file" ]]; then
        echo "❌ User file not found: $user_file"
        return 1
    fi
    
    echo "🔐 Batch Secure Token Grant Operation"
    echo "Admin user: $admin_user"
    echo "User file: $user_file"
    echo ""
    
    # Verify admin user has secure token
    local admin_token_status
    admin_token_status=$(sysadminctl -secureTokenStatus "$admin_user" 2>&1)
    
    if ! echo "$admin_token_status" | grep -q "ENABLED"; then
        echo "❌ Admin user '$admin_user' does not have secure token"
        return 1
    fi
    
    echo "✅ Admin user verified"
    
    local total_users=0
    local successful_grants=0
    local failed_grants=0
    local skipped_users=0
    
    # Process each user in the file
    while IFS=':' read -r username password; do
        # Skip empty lines and comments
        if [[ -z "$username" || "$username" =~ ^#.* ]]; then
            continue
        fi
        
        ((total_users++))
        
        echo ""
        echo "Processing user $total_users: $username"
        
        # Check if user exists
        if ! id "$username" >/dev/null 2>&1; then
            echo "  ❌ User does not exist - skipping"
            ((failed_grants++))
            continue
        fi
        
        # Check current status
        local current_status
        current_status=$(sysadminctl -secureTokenStatus "$username" 2>&1)
        
        if echo "$current_status" | grep -q "ENABLED"; then
            echo "  â„šī¸ User already has secure token - skipping"
            ((skipped_users++))
            continue
        fi
        
        # Grant secure token
        echo "  🔐 Granting secure token..."
        
        if sysadminctl \
            -adminUser "$admin_user" \
            -adminPassword "$admin_password" \
            -secureTokenOn "$username" \
            -password "$password" >/dev/null 2>&1; then
            
            # Verify grant
            local verify_status
            verify_status=$(sysadminctl -secureTokenStatus "$username" 2>&1)
            
            if echo "$verify_status" | grep -q "ENABLED"; then
                echo "  ✅ Successfully granted secure token"
                ((successful_grants++))
            else
                echo "  ❌ Grant command succeeded but verification failed"
                ((failed_grants++))
            fi
        else
            echo "  ❌ Failed to grant secure token"
            ((failed_grants++))
        fi
    done < "$user_file"
    
    echo ""
    echo "=== Batch Operation Summary ==="
    echo "Total users processed: $total_users"
    echo "Successful grants: $successful_grants"
    echo "Failed grants: $failed_grants"
    echo "Skipped (already have token): $skipped_users"
    
    if [[ "$failed_grants" -gt 0 ]]; then
        echo ""
        echo "âš ī¸ Some operations failed - check credentials and user accounts"
    fi
    
    if [[ "$successful_grants" -gt 0 ]]; then
        echo ""
        echo "✅ $successful_grants users now have secure tokens"
    fi
}

# Create sample user file
create_sample_user_file() {
    local sample_file="users_for_secure_token.txt"
    
    cat > "$sample_file" << 'EOF'
# Secure Token User File
# Format: username:password
# Lines starting with # are comments

john.doe:password123
jane.smith:securepass456
# admin.user:adminpass789
EOF
    
    echo "📄 Sample user file created: $sample_file"
    echo "Edit this file with actual usernames and passwords"
    echo "âš ī¸ Ensure file has restricted permissions for security"
    chmod 600 "$sample_file"
}

Enterprise Secure Token Management

#!/bin/bash

# MacFleet Secure Token Management Tool
# Comprehensive secure token management for enterprise environments

# Configuration
LOG_FILE="/var/log/macfleet_securetoken.log"
REPORT_DIR="/var/reports/macfleet/securetoken"
CONFIG_FILE="/etc/macfleet/securetoken_policy.conf"
BACKUP_DIR="/var/backups/macfleet/securetoken"

# Policy settings
REQUIRE_SECURE_TOKENS=true
AUTO_GRANT_ON_CREATION=false
MINIMUM_ADMIN_TOKENS=2
ALERT_ON_TOKEN_LOSS=true
AUDIT_TOKEN_CHANGES=true

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

# Setup directories
setup_directories() {
    for dir in "$REPORT_DIR" "$(dirname "$CONFIG_FILE")" "$BACKUP_DIR"; do
        if [[ ! -d "$dir" ]]; then
            sudo mkdir -p "$dir"
            log_action "Created directory: $dir"
        fi
    done
}

# Generate comprehensive secure token report
generate_secure_token_report() {
    local report_file="$REPORT_DIR/securetoken_report_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "📊 Generating comprehensive secure token report..."
    
    {
        echo "MacFleet Secure Token Management Report"
        echo "Generated: $(date)"
        echo "Device: $(hostname)"
        echo "macOS Version: $(sw_vers -productVersion)"
        echo "======================================"
        echo ""
        
        # System information
        echo "=== System Information ==="
        echo "Device: $(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}' | xargs)"
        echo "Serial: $(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F': ' '{print $2}' | xargs)"
        echo "macOS Version: $(sw_vers -productVersion)"
        echo "Build: $(sw_vers -buildVersion)"
        echo ""
        
        # FileVault status
        echo "=== FileVault Information ==="
        local fv_status=$(fdesetup status 2>/dev/null || echo "FileVault status unavailable")
        echo "FileVault Status: $fv_status"
        
        if echo "$fv_status" | grep -q "On"; then
            echo "FileVault Users:"
            fdesetup list 2>/dev/null | while read -r user; do
                echo "  - $user"
            done
        fi
        echo ""
        
        # Secure token analysis
        echo "=== Secure Token Analysis ==="
        
        local total_users=0
        local enabled_tokens=0
        local disabled_tokens=0
        local admin_with_tokens=0
        local standard_with_tokens=0
        
        # Analyze all users
        local users
        users=$(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}')
        
        printf "%-25s %-12s %-10s %-15s\n" "Username" "Token Status" "Admin" "UID"
        printf "%-25s %-12s %-10s %-15s\n" "--------" "------------" "-----" "---"
        
        for user in $users; do
            # Skip system accounts
            if [[ "$user" =~ ^(_|com\.|root|daemon|nobody) ]]; then
                continue
            fi
            
            ((total_users++))
            
            local uid
            uid=$(id -u "$user" 2>/dev/null || echo "N/A")
            
            local is_admin="No"
            if dseditgroup -o checkmember -m "$user" admin >/dev/null 2>&1; then
                is_admin="Yes"
            fi
            
            local token_status
            local token_output
            token_output=$(sysadminctl -secureTokenStatus "$user" 2>&1)
            
            if echo "$token_output" | grep -q "ENABLED"; then
                token_status="✅ Enabled"
                ((enabled_tokens++))
                if [[ "$is_admin" == "Yes" ]]; then
                    ((admin_with_tokens++))
                else
                    ((standard_with_tokens++))
                fi
            elif echo "$token_output" | grep -q "DISABLED"; then
                token_status="❌ Disabled"
                ((disabled_tokens++))
            else
                token_status="âš ī¸ Unknown"
            fi
            
            printf "%-25s %-12s %-10s %-15s\n" "$user" "$token_status" "$is_admin" "$uid"
        done
        
        echo ""
        echo "=== Statistics ==="
        echo "Total users analyzed: $total_users"
        echo "Users with secure tokens: $enabled_tokens"
        echo "Users without secure tokens: $disabled_tokens"
        echo "Admin users with tokens: $admin_with_tokens"
        echo "Standard users with tokens: $standard_with_tokens"
        
        # Security assessment
        echo ""
        echo "=== Security Assessment ==="
        
        local security_score=100
        local issues_found=0
        
        if [[ "$enabled_tokens" -eq 0 ]]; then
            echo "❌ CRITICAL: No users have secure tokens"
            security_score=$((security_score - 50))
            ((issues_found++))
        fi
        
        if [[ "$admin_with_tokens" -eq 0 ]]; then
            echo "❌ CRITICAL: No admin users have secure tokens"
            security_score=$((security_score - 40))
            ((issues_found++))
        elif [[ "$admin_with_tokens" -lt "$MINIMUM_ADMIN_TOKENS" ]]; then
            echo "âš ī¸ WARNING: Fewer than $MINIMUM_ADMIN_TOKENS admin users have secure tokens"
            security_score=$((security_score - 20))
            ((issues_found++))
        fi
        
        if [[ "$disabled_tokens" -gt "$enabled_tokens" ]]; then
            echo "âš ī¸ WARNING: More users lack secure tokens than have them"
            security_score=$((security_score - 15))
            ((issues_found++))
        fi
        
        # FileVault compatibility check
        if echo "$fv_status" | grep -q "On"; then
            local fv_users
            fv_users=$(fdesetup list 2>/dev/null | wc -l)
            if [[ "$enabled_tokens" -lt "$fv_users" ]]; then
                echo "âš ī¸ WARNING: FileVault is enabled but some users may lack secure tokens"
                security_score=$((security_score - 10))
                ((issues_found++))
            fi
        fi
        
        if [[ "$issues_found" -eq 0 ]]; then
            echo "✅ No security issues detected"
        fi
        
        echo ""
        echo "Security Score: $security_score/100"
        
        # Recommendations
        echo ""
        echo "=== Recommendations ==="
        
        if [[ "$disabled_tokens" -gt 0 ]]; then
            echo "💡 Grant secure tokens to $disabled_tokens users for full FileVault compatibility"
        fi
        
        if [[ "$admin_with_tokens" -lt 2 ]]; then
            echo "💡 Ensure at least 2 admin users have secure tokens for redundancy"
        fi
        
        if [[ "$enabled_tokens" -gt 0 && "$disabled_tokens" -gt 0 ]]; then
            echo "💡 Consider enterprise policy to require secure tokens for all users"
        fi
        
        echo "💡 Regular secure token audits recommended for compliance"
        
        # Compliance status
        if [[ "$REQUIRE_SECURE_TOKENS" == "true" ]]; then
            echo ""
            echo "=== Policy Compliance ==="
            echo "Policy: Secure tokens required for all users"
            
            if [[ "$disabled_tokens" -eq 0 ]]; then
                echo "Status: ✅ COMPLIANT"
            else
                echo "Status: ❌ NON-COMPLIANT"
                echo "Action needed: Grant tokens to $disabled_tokens users"
            fi
        fi
        
    } > "$report_file"
    
    echo "📊 Report saved to: $report_file"
    log_action "Secure token report generated: $report_file"
}

# Monitor secure token changes
monitor_secure_token_changes() {
    echo "🔍 Starting secure token monitoring..."
    log_action "Secure token monitoring started"
    
    # Create baseline if it doesn't exist
    local baseline_file="$BACKUP_DIR/token_baseline.txt"
    local current_file="$BACKUP_DIR/token_current.txt"
    
    # Generate current state
    dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}' | while read -r user; do
        if [[ ! "$user" =~ ^(_|com\.|root|daemon|nobody) ]]; then
            local status
            status=$(sysadminctl -secureTokenStatus "$user" 2>&1)
            echo "$user:$status"
        fi
    done > "$current_file"
    
    if [[ ! -f "$baseline_file" ]]; then
        cp "$current_file" "$baseline_file"
        echo "📄 Baseline created: $baseline_file"
        log_action "Secure token baseline created"
        return 0
    fi
    
    # Compare current state with baseline
    local changes_detected=false
    
    echo "Comparing current state with baseline..."
    
    # Check for changes
    if ! diff -q "$baseline_file" "$current_file" >/dev/null 2>&1; then
        changes_detected=true
        echo "âš ī¸ Secure token changes detected!"
        
        local changes_file="$BACKUP_DIR/token_changes_$(date +%Y%m%d_%H%M%S).txt"
        
        {
            echo "Secure Token Changes Detected"
            echo "Timestamp: $(date)"
            echo "=========================="
            echo ""
            diff "$baseline_file" "$current_file"
        } > "$changes_file"
        
        echo "📄 Changes logged to: $changes_file"
        log_action "ALERT: Secure token changes detected - $changes_file"
        
        # Update baseline
        cp "$current_file" "$baseline_file"
        log_action "Secure token baseline updated"
    else
        echo "✅ No changes detected since last check"
    fi
    
    rm -f "$current_file"
    return 0
}

# Main execution function
main() {
    local action="${1:-help}"
    local target_user="${2:-}"
    local admin_user="${3:-}"
    
    log_action "=== MacFleet Secure Token Management Started ==="
    
    setup_directories
    
    case "$action" in
        "check")
            if [[ -n "$target_user" ]]; then
                check_user_secure_token "$target_user"
            else
                check_all_users_secure_tokens
            fi
            ;;
        "grant")
            if [[ -n "$target_user" && -n "$admin_user" ]]; then
                echo "Interactive secure token grant for $target_user"
                read -s -p "Admin password for $admin_user: " admin_pass
                echo ""
                read -s -p "Password for $target_user: " target_pass
                echo ""
                advanced_secure_token_grant "$admin_user" "$admin_pass" "$target_user" "$target_pass"
            else
                echo "❌ Usage: $0 grant <target_user> <admin_user>"
            fi
            ;;
        "batch")
            if [[ -n "$target_user" && -n "$admin_user" ]]; then
                # target_user is actually the user file in this context
                read -s -p "Admin password for $admin_user: " admin_pass
                echo ""
                batch_grant_secure_tokens "$admin_user" "$admin_pass" "$target_user"
            else
                echo "❌ Usage: $0 batch <user_file> <admin_user>"
                echo "Create user file with: $0 create-sample-file"
            fi
            ;;
        "report")
            generate_secure_token_report
            ;;
        "monitor")
            monitor_secure_token_changes
            ;;
        "create-sample-file")
            create_sample_user_file
            ;;
        "version")
            local macos_version
            macos_version=$(sw_vers -productVersion)
            echo "macOS Version: $macos_version"
            
            local macos_major
            macos_major=$(echo "$macos_version" | cut -d. -f1)
            local macos_minor
            macos_minor=$(echo "$macos_version" | cut -d. -f2)
            
            if [[ "$macos_major" -lt 10 ]] || [[ "$macos_major" -eq 10 && "$macos_minor" -lt 13 ]]; then
                echo "❌ Secure tokens require macOS 10.13 or later"
            else
                echo "✅ Secure tokens supported on this macOS version"
            fi
            ;;
        "help"|*)
            echo "MacFleet Secure Token Management Tool"
            echo "Usage: $0 [action] [options]"
            echo ""
            echo "Actions:"
            echo "  check [user]                     - Check secure token status (all users if no user specified)"
            echo "  grant <user> <admin>             - Grant secure token to user (interactive passwords)"
            echo "  batch <user_file> <admin>        - Grant tokens to multiple users from file"
            echo "  report                           - Generate comprehensive secure token report"
            echo "  monitor                          - Monitor for secure token changes"
            echo "  create-sample-file               - Create sample user file for batch operations"
            echo "  version                          - Check macOS version compatibility"
            echo "  help                             - Show this help message"
            echo ""
            echo "Examples:"
            echo "  $0 check                         # Check all users"
            echo "  $0 check john.doe                # Check specific user"
            echo "  $0 grant john.doe admin.user     # Grant token interactively"
            echo "  $0 batch users.txt admin.user    # Batch grant from file"
            echo "  $0 report                        # Generate detailed report"
            echo ""
            echo "Secure Token Requirements:"
            echo "  - macOS 10.13 (High Sierra) or later"
            echo "  - Admin user with existing secure token"
            echo "  - Valid credentials for both admin and target users"
            echo "  - Proper system permissions and SIP configuration"
            ;;
    esac
    
    log_action "=== MacFleet Secure Token Management Completed ==="
}

# Execute main function
main "$@"

Secure Token Best Practices

Security Considerations

AspectRecommendationRationale
Admin RedundancyMaintain 2+ admin users with tokensPrevents lockout scenarios
Password SecurityUse strong, unique passwordsTokens are only as secure as passwords
Regular AuditsMonthly token status reviewsDetect unauthorized changes
FileVault IntegrationGrant tokens before enabling FileVaultEnsures all users can unlock drives
DocumentationMaintain user token registryTrack enterprise compliance

Troubleshooting Common Issues

# Common secure token troubleshooting
troubleshoot_secure_tokens() {
    echo "🔧 Secure Token Troubleshooting Guide"
    echo "===================================="
    
    # Check macOS version
    local macos_version
    macos_version=$(sw_vers -productVersion)
    echo "macOS Version: $macos_version"
    
    # Check SIP status
    echo ""
    echo "System Integrity Protection (SIP) Status:"
    csrutil status
    
    # Check for FileVault
    echo ""
    echo "FileVault Status:"
    fdesetup status 2>/dev/null || echo "Unable to determine FileVault status"
    
    # List users with UIDs
    echo ""
    echo "User Accounts (UID >= 500):"
    dscl . list /Users UniqueID | awk '$2 >= 500 {printf "%-20s UID: %s\n", $1, $2}'
    
    # Common issues and solutions
    echo ""
    echo "Common Issues & Solutions:"
    echo "========================="
    echo "1. 'No admin with secure token' error:"
    echo "   - Check if any admin users have tokens: $0 check"
    echo "   - On macOS 10.15+, first FileVault user may get automatic token"
    echo ""
    echo "2. Grant operation fails:"
    echo "   - Verify admin user has secure token"
    echo "   - Check both user passwords are correct"
    echo "   - Ensure target user exists and is properly configured"
    echo ""
    echo "3. FileVault users can't unlock:"
    echo "   - Grant secure tokens to all FileVault users"
    echo "   - Use: fdesetup list to see FileVault-enabled users"
    echo ""
    echo "4. System shows 'DISABLED' for all users:"
    echo "   - May indicate system-level issue"
    echo "   - Check SIP configuration"
    echo "   - Verify macOS version compatibility"
}

Important Notes

  • macOS Version Requirements - Secure tokens require macOS 10.13 (High Sierra) or later
  • Admin Prerequisites - Granting tokens requires an existing admin user with secure token
  • Password Security - Both admin and target user passwords must be provided for token grants
  • FileVault Integration - Users need secure tokens to unlock FileVault-encrypted volumes
  • Enterprise Deployment - Test token operations on individual devices before fleet deployment
  • Monitoring - Regular audits ensure compliance with enterprise security policies

Secure Data Erasure on macOS

Manage secure data erasure and privacy protection across your MacFleet devices using advanced data sanitization systems. This tutorial covers free space erasure, secure deletion, compliance monitoring, and comprehensive data lifecycle management.

Understanding macOS Secure Data Erasure

macOS provides secure data erasure capabilities for privacy and compliance:

  • diskutil secureErase - Secure erasure of free space and volumes
  • Free Space Erasure - Remove traces of deleted files from disk
  • Secure Wipe Levels - Multiple security standards (DoD, DoE, Gutmann)
  • Privacy Protection - Prevent data recovery and forensic analysis
  • Compliance Requirements - Meet regulatory standards for data destruction

Basic Secure Erasure Operations

Erase Free Space

#!/bin/bash

# Basic free space erasure
diskutil secureErase freespace 4 /Volumes/Macintosh\ HD

echo "Free space secure erasure completed"

Enhanced Secure Erasure Configuration

#!/bin/bash

# Comprehensive secure erasure with multiple security levels
secure_erase_freespace() {
    local volume_path="$1"
    local security_level="${2:-4}"
    
    echo "=== Secure Free Space Erasure ==="
    echo "Volume: $volume_path"
    echo "Security Level: $security_level"
    
    # Validate volume exists
    if [[ ! -d "$volume_path" ]]; then
        echo "❌ Volume not found: $volume_path"
        return 1
    fi
    
    # Display security level information
    case "$security_level" in
        0) echo "Security Method: Single-pass zero-fill erase" ;;
        1) echo "Security Method: Single-pass random-fill erase" ;;
        2) echo "Security Method: US DoD 7-pass secure erase" ;;
        3) echo "Security Method: Gutmann algorithm 35-pass secure erase" ;;
        4) echo "Security Method: US DoE algorithm 3-pass secure erase" ;;
        *) echo "❌ Invalid security level: $security_level"; return 1 ;;
    esac
    
    # Get volume information
    local free_space
    free_space=$(df -h "$volume_path" | tail -1 | awk '{print $4}')
    echo "Free Space to Erase: $free_space"
    
    # Estimate time based on security level and free space
    echo "âąī¸  Estimated time: This may take several hours depending on drive size and security level"
    
    # Perform secure erasure
    echo "Starting secure erasure..."
    if diskutil secureErase freespace "$security_level" "$volume_path"; then
        echo "✅ Secure free space erasure completed successfully"
        log_erasure_action "freespace" "$volume_path" "$security_level" "success"
    else
        echo "❌ Secure erasure failed"
        log_erasure_action "freespace" "$volume_path" "$security_level" "failed"
        return 1
    fi
    
    return 0
}

# Logging function
log_erasure_action() {
    local action="$1"
    local target="$2"
    local level="$3"
    local result="$4"
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Secure Erasure: $action on $target (Level: $level) - $result" >> "/var/log/macfleet_secure_erasure.log"
}

# Example usage
# secure_erase_freespace "/Volumes/Macintosh HD" 4

Secure Erasure Categories

Data Classification Levels

#!/bin/bash

# Secure erasure categories for different data sensitivity levels
declare -A ERASURE_CATEGORIES=(
    ["public_data"]="Low-sensitivity public information requiring basic erasure"
    ["internal_business"]="Internal business data requiring standard secure erasure"
    ["confidential_data"]="Confidential business information requiring enhanced erasure"
    ["restricted_financial"]="Financial and accounting data requiring strict erasure protocols"
    ["personal_identifiable"]="PII data requiring privacy-compliant erasure procedures"
    ["healthcare_records"]="HIPAA-protected health information requiring medical-grade erasure"
    ["legal_privileged"]="Attorney-client privileged information requiring maximum security erasure"
    ["classified_government"]="Government classified data requiring military-grade erasure"
    ["research_intellectual"]="Research and IP data requiring comprehensive erasure protocols"
    ["forensic_evidence"]="Digital forensic evidence requiring chain-of-custody erasure"
)

# Security levels for each category
declare -A CATEGORY_SECURITY_LEVELS=(
    ["public_data"]="1"           # Single-pass random
    ["internal_business"]="2"     # DoD 7-pass
    ["confidential_data"]="4"     # DoE 3-pass
    ["restricted_financial"]="4"  # DoE 3-pass
    ["personal_identifiable"]="4" # DoE 3-pass
    ["healthcare_records"]="3"    # Gutmann 35-pass
    ["legal_privileged"]="3"      # Gutmann 35-pass
    ["classified_government"]="3" # Gutmann 35-pass
    ["research_intellectual"]="4" # DoE 3-pass
    ["forensic_evidence"]="3"     # Gutmann 35-pass
)

# Compliance frameworks
declare -A COMPLIANCE_FRAMEWORKS=(
    ["public_data"]="basic_security"
    ["internal_business"]="iso27001"
    ["confidential_data"]="iso27001,sox"
    ["restricted_financial"]="sox,pci_dss"
    ["personal_identifiable"]="gdpr,ccpa"
    ["healthcare_records"]="hipaa,hitech"
    ["legal_privileged"]="attorney_client_privilege"
    ["classified_government"]="fisma,nist_sp800"
    ["research_intellectual"]="iso27001,trade_secrets"
    ["forensic_evidence"]="chain_of_custody,legal_discovery"
)

print_erasure_categories() {
    echo "=== Secure Erasure Categories ==="
    for category in "${!ERASURE_CATEGORIES[@]}"; do
        echo "Category: $category"
        echo "  Description: ${ERASURE_CATEGORIES[$category]}"
        echo "  Security Level: ${CATEGORY_SECURITY_LEVELS[$category]}"
        echo "  Compliance: ${COMPLIANCE_FRAMEWORKS[$category]}"
        echo ""
    done
}

# Display available categories
print_erasure_categories

Secure Erasure Policies

Privacy Protection Policies

#!/bin/bash

# Secure erasure policies for different privacy and compliance requirements
declare -A ERASURE_POLICIES=(
    ["privacy_basic"]="Basic privacy protection with standard erasure methods"
    ["gdpr_compliant"]="GDPR-compliant personal data erasure with audit trails"
    ["hipaa_medical"]="HIPAA-compliant medical record erasure with certification"
    ["financial_sox"]="SOX-compliant financial data erasure with validation"
    ["government_classified"]="Government classified data erasure with chain of custody"
    ["forensic_legal"]="Legal and forensic data erasure with evidence preservation"
)

# Get erasure policy configuration
get_erasure_policy() {
    local policy_type="$1"
    
    case "$policy_type" in
        "privacy_basic")
            cat << EOF
{
    "erasure_enabled": true,
    "default_security_level": 2,
    "automatic_scheduling": false,
    "verification_required": false,
    "audit_logging": "basic",
    "compliance_frameworks": ["basic_security"],
    "certificate_generation": false,
    "chain_of_custody": false,
    "data_classification": "public_internal",
    "retention_policy": "immediate_erasure",
    "verification_methods": ["basic_check"],
    "reporting_level": "summary"
}
EOF
            ;;
        "gdpr_compliant")
            cat << EOF
{
    "erasure_enabled": true,
    "default_security_level": 4,
    "automatic_scheduling": true,
    "verification_required": true,
    "audit_logging": "comprehensive",
    "compliance_frameworks": ["gdpr", "ccpa"],
    "certificate_generation": true,
    "chain_of_custody": true,
    "data_classification": "personal_identifiable",
    "retention_policy": "verified_erasure",
    "verification_methods": ["forensic_verification", "entropy_analysis"],
    "reporting_level": "detailed",
    "privacy_impact_assessment": true,
    "data_subject_rights": "right_to_erasure",
    "cross_border_considerations": true
}
EOF
            ;;
        "hipaa_medical")
            cat << EOF
{
    "erasure_enabled": true,
    "default_security_level": 3,
    "automatic_scheduling": true,
    "verification_required": true,
    "audit_logging": "comprehensive",
    "compliance_frameworks": ["hipaa", "hitech"],
    "certificate_generation": true,
    "chain_of_custody": true,
    "data_classification": "healthcare_records",
    "retention_policy": "medical_retention_schedule",
    "verification_methods": ["forensic_verification", "medical_certification"],
    "reporting_level": "detailed",
    "encryption_verification": true,
    "access_controls": "role_based",
    "medical_device_considerations": true
}
EOF
            ;;
        "government_classified")
            cat << EOF
{
    "erasure_enabled": true,
    "default_security_level": 3,
    "automatic_scheduling": false,
    "verification_required": true,
    "audit_logging": "comprehensive",
    "compliance_frameworks": ["fisma", "nist_sp800", "dod_5220"],
    "certificate_generation": true,
    "chain_of_custody": true,
    "data_classification": "classified_government",
    "retention_policy": "government_retention_schedule",
    "verification_methods": ["military_verification", "security_clearance_required"],
    "reporting_level": "classified",
    "physical_destruction_option": true,
    "witness_requirement": true,
    "security_clearance_verification": true
}
EOF
            ;;
        *)
            echo "Unknown erasure policy: $policy_type"
            return 1
            ;;
    esac
}

# Apply erasure policy
apply_erasure_policy() {
    local policy="$1"
    local config_file="/tmp/erasure_policy.json"
    
    echo "Applying secure erasure policy: $policy"
    
    get_erasure_policy "$policy" > "$config_file"
    
    if [[ ! -f "$config_file" ]]; then
        echo "❌ Failed to generate policy configuration"
        return 1
    fi
    
    echo "✅ Secure erasure policy applied successfully"
    echo "Configuration: $config_file"
    
    # Display key policy settings
    echo "=== Policy Summary ==="
    echo "Erasure Enabled: $(jq -r '.erasure_enabled' "$config_file")"
    echo "Default Security Level: $(jq -r '.default_security_level' "$config_file")"
    echo "Verification Required: $(jq -r '.verification_required' "$config_file")"
    echo "Audit Logging: $(jq -r '.audit_logging' "$config_file")"
    echo "Compliance Frameworks: $(jq -r '.compliance_frameworks[]' "$config_file" | tr '\n' ', ' | sed 's/,$//')"
    
    return 0
}

Advanced Secure Erasure Monitoring

Erasure Verification and Analytics

#!/bin/bash

# Comprehensive secure erasure monitoring and verification
verify_secure_erasure() {
    local verification_profile="$1"
    local target_volume="$2"
    local verification_report="/tmp/erasure_verification_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Secure Erasure Verification ==="
    echo "Verification Profile: $verification_profile"
    echo "Target Volume: $target_volume"
    
    # Initialize verification report
    cat > "$verification_report" << EOF
{
    "verification_profile": "$verification_profile",
    "target_volume": "$target_volume",
    "verification_timestamp": "$(date -Iseconds)",
    "hostname": "$(hostname)",
    "verification_results": {},
    "compliance_status": {},
    "forensic_analysis": {}
}
EOF
    
    # Perform verification checks
    echo "Performing verification checks..."
    
    # Check volume status
    local volume_status="unknown"
    if [[ -d "$target_volume" ]]; then
        volume_status="accessible"
    else
        volume_status="inaccessible"
    fi
    
    # Analyze free space entropy
    echo "Analyzing free space entropy..."
    local entropy_score
    entropy_score=$(calculate_entropy "$target_volume")
    
    # Check for data remnants
    echo "Scanning for data remnants..."
    local remnant_scan_result
    remnant_scan_result=$(scan_data_remnants "$target_volume")
    
    # Verify erasure completeness
    echo "Verifying erasure completeness..."
    local completeness_score
    completeness_score=$(verify_erasure_completeness "$target_volume")
    
    # Update verification report
    jq --arg volume_status "$volume_status" \
       --arg entropy_score "$entropy_score" \
       --arg remnant_result "$remnant_scan_result" \
       --arg completeness "$completeness_score" \
       '.verification_results = {
          "volume_status": $volume_status,
          "entropy_score": $entropy_score,
          "remnant_scan": $remnant_result,
          "completeness_score": $completeness
        }' "$verification_report" > "${verification_report}.tmp" && mv "${verification_report}.tmp" "$verification_report"
    
    # Display results
    echo ""
    echo "Verification Results:"
    echo "  Volume Status: $volume_status"
    echo "  Entropy Score: $entropy_score"
    echo "  Data Remnants: $remnant_scan_result"
    echo "  Completeness: $completeness_score"
    echo "  Verification Report: $verification_report"
    
    # Log verification activity
    audit_log "Secure erasure verification completed: $verification_profile for $target_volume"
    
    return 0
}

# Helper functions
calculate_entropy() {
    local volume="$1"
    # Simplified entropy calculation
    echo "high_entropy"
}

scan_data_remnants() {
    local volume="$1"
    # Simplified remnant scanning
    echo "no_remnants_detected"
}

verify_erasure_completeness() {
    local volume="$1"
    # Simplified completeness verification
    echo "100_percent"
}

Secure Data Erasure Management System

#!/bin/bash

# MacFleet Secure Data Erasure Management System
# Comprehensive data sanitization, privacy protection, and compliance monitoring

# Configuration
CONFIG_DIR="/etc/macfleet/erasure"
LOG_FILE="/var/log/macfleet_secure_erasure.log"
DATA_DIR="/var/data/macfleet/erasure"
REPORTS_DIR="/var/reports/macfleet/erasure"
AUDIT_LOG="/var/log/macfleet_erasure_audit.log"
CERTIFICATES_DIR="/var/certificates/macfleet/erasure"

# Create required directories
create_directories() {
    local directories=("$CONFIG_DIR" "$DATA_DIR" "$REPORTS_DIR" "$CERTIFICATES_DIR")
    
    for dir in "${directories[@]}"; do
        if [[ ! -d "$dir" ]]; then
            sudo mkdir -p "$dir"
            sudo chmod 755 "$dir"
        fi
    done
}

# Logging functions
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] $1" | tee -a "$LOG_FILE"
}

log_error() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] $1" | tee -a "$LOG_FILE" >&2
}

audit_log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [AUDIT] $1" | tee -a "$AUDIT_LOG"
}

# Volume discovery and analysis
discover_volumes() {
    echo "=== Volume Discovery ==="
    
    log_action "Starting volume discovery"
    
    # List all mounted volumes
    echo "Mounted Volumes:"
    df -h | grep "^/dev/" | while read -r line; do
        local device
        device=$(echo "$line" | awk '{print $1}')
        local mount_point
        mount_point=$(echo "$line" | awk '{print $9}')
        local size
        size=$(echo "$line" | awk '{print $2}')
        local available
        available=$(echo "$line" | awk '{print $4}')
        
        echo "  Device: $device"
        echo "  Mount Point: $mount_point"
        echo "  Size: $size"
        echo "  Available: $available"
        echo ""
    done
    
    # List diskutil volumes
    echo "All Volumes (diskutil):"
    diskutil list
    
    log_action "Volume discovery completed"
}

# Secure erasure execution
execute_secure_erasure() {
    local volume_path="$1"
    local security_level="$2"
    local category="${3:-internal_business}"
    local policy="${4:-privacy_basic}"
    
    log_action "Executing secure erasure: $volume_path (Level: $security_level, Category: $category)"
    
    echo "=== Secure Erasure Execution ==="
    echo "Volume: $volume_path"
    echo "Security Level: $security_level"
    echo "Data Category: $category"
    echo "Erasure Policy: $policy"
    
    # Pre-erasure validation
    echo "Performing pre-erasure validation..."
    
    # Check volume accessibility
    if [[ ! -d "$volume_path" ]]; then
        log_error "Volume not accessible: $volume_path"
        return 1
    fi
    
    # Check available space
    local free_space_kb
    free_space_kb=$(df "$volume_path" | tail -1 | awk '{print $4}')
    
    if [[ $free_space_kb -lt 1024 ]]; then
        echo "âš ī¸  Warning: Very little free space to erase (<1MB)"
    fi
    
    # Generate pre-erasure report
    local pre_report="$REPORTS_DIR/pre_erasure_$(date +%Y%m%d_%H%M%S).json"
    cat > "$pre_report" << EOF
{
    "operation": "secure_erasure",
    "volume_path": "$volume_path",
    "security_level": $security_level,
    "data_category": "$category",
    "erasure_policy": "$policy",
    "pre_erasure_timestamp": "$(date -Iseconds)",
    "hostname": "$(hostname)",
    "free_space_kb": $free_space_kb,
    "operator": "$(whoami)"
}
EOF
    
    # Execute erasure based on security level
    echo "Starting secure erasure operation..."
    local start_time
    start_time=$(date +%s)
    
    case "$security_level" in
        0|1|2|3|4)
            if diskutil secureErase freespace "$security_level" "$volume_path"; then
                local end_time
                end_time=$(date +%s)
                local duration=$((end_time - start_time))
                
                echo "✅ Secure erasure completed successfully"
                echo "âąī¸  Duration: ${duration} seconds"
                
                # Generate completion certificate
                generate_erasure_certificate "$volume_path" "$security_level" "$category" "$policy" "$duration" "success"
                
                audit_log "Secure erasure successful: $volume_path (Level: $security_level, Duration: ${duration}s)"
                return 0
            else
                log_error "Secure erasure failed: $volume_path"
                
                # Generate failure report
                generate_erasure_certificate "$volume_path" "$security_level" "$category" "$policy" "0" "failed"
                
                audit_log "Secure erasure failed: $volume_path (Level: $security_level)"
                return 1
            fi
            ;;
        *)
            log_error "Invalid security level: $security_level"
            return 1
            ;;
    esac
}

# Generate erasure certificate
generate_erasure_certificate() {
    local volume_path="$1"
    local security_level="$2"
    local category="$3"
    local policy="$4"
    local duration="$5"
    local status="$6"
    
    local certificate_file="$CERTIFICATES_DIR/erasure_certificate_$(date +%Y%m%d_%H%M%S).json"
    
    # Get security method description
    local security_method
    case "$security_level" in
        0) security_method="Single-pass zero-fill erase" ;;
        1) security_method="Single-pass random-fill erase" ;;
        2) security_method="US DoD 7-pass secure erase" ;;
        3) security_method="Gutmann algorithm 35-pass secure erase" ;;
        4) security_method="US DoE algorithm 3-pass secure erase" ;;
        *) security_method="Unknown method" ;;
    esac
    
    cat > "$certificate_file" << EOF
{
    "certificate_type": "secure_data_erasure",
    "certificate_id": "CERT-$(date +%Y%m%d%H%M%S)-$(uuidgen | cut -d'-' -f1)",
    "erasure_details": {
        "volume_path": "$volume_path",
        "security_level": $security_level,
        "security_method": "$security_method",
        "data_category": "$category",
        "erasure_policy": "$policy",
        "duration_seconds": $duration,
        "status": "$status"
    },
    "system_information": {
        "hostname": "$(hostname)",
        "operator": "$(whoami)",
        "timestamp": "$(date -Iseconds)",
        "macos_version": "$(sw_vers -productVersion)",
        "hardware_uuid": "$(system_profiler SPHardwareDataType | grep 'Hardware UUID' | awk '{print $3}')"
    },
    "compliance_information": {
        "frameworks": "$(get_compliance_frameworks "$category")",
        "verification_performed": true,
        "chain_of_custody": true,
        "audit_trail": "available"
    },
    "digital_signature": {
        "signed": true,
        "signature_algorithm": "SHA-256",
        "signature_timestamp": "$(date -Iseconds)"
    }
}
EOF
    
    echo "📜 Erasure certificate generated: $certificate_file"
    log_action "Erasure certificate generated: $certificate_file"
}

# Get compliance frameworks for category
get_compliance_frameworks() {
    local category="$1"
    echo "${COMPLIANCE_FRAMEWORKS[$category]:-basic_security}"
}

# Fleet-wide erasure scheduling
schedule_fleet_erasure() {
    local schedule_type="$1"
    local security_level="$2"
    local target_category="${3:-all}"
    
    log_action "Scheduling fleet-wide secure erasure: $schedule_type (Level: $security_level)"
    
    echo "=== Fleet-Wide Erasure Scheduling ==="
    echo "Schedule Type: $schedule_type"
    echo "Security Level: $security_level"
    echo "Target Category: $target_category"
    
    case "$schedule_type" in
        "weekly_maintenance")
            echo "Setting up weekly maintenance erasure..."
            # Create launchd plist for weekly execution
            create_erasure_schedule "weekly" "$security_level" "$target_category"
            ;;
        "monthly_compliance")
            echo "Setting up monthly compliance erasure..."
            create_erasure_schedule "monthly" "$security_level" "$target_category"
            ;;
        "immediate_fleet")
            echo "Executing immediate fleet-wide erasure..."
            execute_fleet_erasure "$security_level" "$target_category"
            ;;
        *)
            echo "❌ Unknown schedule type: $schedule_type"
            return 1
            ;;
    esac
    
    audit_log "Fleet erasure scheduling completed: $schedule_type"
}

# Create erasure schedule
create_erasure_schedule() {
    local frequency="$1"
    local security_level="$2"
    local category="$3"
    
    local plist_file="/Library/LaunchDaemons/com.macfleet.secure.erasure.$frequency.plist"
    
    # Create launchd plist for scheduled erasure
    sudo tee "$plist_file" > /dev/null << 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>Label</key>
    <string>com.macfleet.secure.erasure.$frequency</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/macfleet_erasure</string>
        <string>auto_erase</string>
        <string>$security_level</string>
        <string>$category</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Weekday</key>
        <integer>0</integer>
        <key>Hour</key>
        <integer>2</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>
EOF
    
    sudo launchctl load "$plist_file"
    echo "✅ Scheduled erasure created: $frequency"
}

# Execute fleet-wide erasure
execute_fleet_erasure() {
    local security_level="$1"
    local category="$2"
    
    echo "Executing fleet-wide secure erasure..."
    
    # Get all volumes for erasure
    df -h | grep "^/dev/" | while read -r line; do
        local mount_point
        mount_point=$(echo "$line" | awk '{print $9}')
        
        if [[ "$mount_point" != "/" ]]; then  # Skip root volume for safety
            echo "Processing volume: $mount_point"
            execute_secure_erasure "$mount_point" "$security_level" "$category" "fleet_policy"
        fi
    done
}

# Main function with command routing
main() {
    local command="$1"
    shift
    
    # Initialize
    create_directories
    
    case "$command" in
        "erase_freespace")
            # Execute secure free space erasure
            execute_secure_erasure "$@"
            ;;
        "discover_volumes")
            # Discover and list available volumes
            discover_volumes
            ;;
        "verify_erasure")
            # Verify erasure completeness
            verify_secure_erasure "$@"
            ;;
        "apply_policy")
            # Apply erasure policy
            apply_erasure_policy "$@"
            ;;
        "generate_certificate")
            # Generate erasure certificate
            generate_erasure_certificate "$@"
            ;;
        "schedule_fleet")
            # Schedule fleet-wide erasure
            schedule_fleet_erasure "$@"
            ;;
        "show_categories")
            # Show erasure categories
            print_erasure_categories
            ;;
        "show_policies")
            # Show available policies
            for policy in privacy_basic gdpr_compliant hipaa_medical financial_sox government_classified forensic_legal; do
                echo "Policy: $policy"
                get_erasure_policy "$policy" | jq .
                echo ""
            done
            ;;
        "compliance_report")
            # Generate compliance report
            generate_compliance_report "$@"
            ;;
        *)
            echo "MacFleet Secure Data Erasure Management System"
            echo "Usage: $0 <command> [options]"
            echo ""
            echo "Commands:"
            echo "  erase_freespace <volume> <level> [category] [policy]  - Execute secure free space erasure"
            echo "  discover_volumes                                      - Discover available volumes"
            echo "  verify_erasure <profile> <volume>                     - Verify erasure completeness"
            echo "  apply_policy <policy>                                 - Apply erasure policy"
            echo "  generate_certificate <volume> <level> <category>      - Generate erasure certificate"
            echo "  schedule_fleet <type> <level> [category]              - Schedule fleet-wide erasure"
            echo "  show_categories                                       - Show data categories"
            echo "  show_policies                                         - Show erasure policies"
            echo "  compliance_report <framework>                         - Generate compliance report"
            echo ""
            echo "Security Levels:"
            echo "  0 - Single-pass zero-fill erase"
            echo "  1 - Single-pass random-fill erase"
            echo "  2 - US DoD 7-pass secure erase"
            echo "  3 - Gutmann algorithm 35-pass secure erase"
            echo "  4 - US DoE algorithm 3-pass secure erase"
            echo ""
            echo "Examples:"
            echo "  $0 erase_freespace \"/Volumes/Data\" 4 confidential_data gdpr_compliant"
            echo "  $0 discover_volumes"
            echo "  $0 verify_erasure comprehensive \"/Volumes/Data\""
            echo "  $0 apply_policy hipaa_medical"
            echo "  $0 schedule_fleet weekly_maintenance 2 internal_business"
            ;;
    esac
}

# Execute main function with all arguments
main "$@"

Security Considerations

Data Sanitization Security

  • Multi-Pass Overwriting - Use appropriate security levels for data sensitivity
  • Verification Procedures - Verify complete erasure and data unrecoverability
  • Compliance Standards - Meet regulatory requirements for data destruction
  • Chain of Custody - Maintain audit trails and documentation
  • Physical Security - Consider physical destruction for highest security needs

Compliance Framework

  • GDPR Compliance - Right to erasure and data protection requirements
  • HIPAA Medical - Medical record destruction with proper certification
  • SOX Financial - Financial data erasure with audit requirements
  • Government Standards - FISMA, NIST SP 800-88 for classified data
  • Industry Standards - DoD 5220.22-M, Common Criteria for secure erasure

Troubleshooting Guide

Common Issues

Erasure Process Fails

  • Check volume is not in use: lsof | grep /Volumes/VolumeName
  • Verify sufficient permissions: Run with sudo if needed
  • Check disk health: diskutil verifyVolume /Volumes/VolumeName

Slow Erasure Performance

  • Higher security levels (3,4) take significantly longer
  • SSD vs HDD performance differences
  • System load and available resources affect speed

Volume Not Found

  • List available volumes: diskutil list
  • Check mount points: df -h
  • Verify volume name escaping for spaces: Volume\ Name

Diagnostic Commands

# List all volumes
diskutil list

# Check volume information
diskutil info /Volumes/VolumeName

# Check free space
df -h /Volumes/VolumeName

# Monitor erasure progress
sudo fs_usage -w -f diskio diskutil

Important Notes

  • Backup Critical Data - Always backup important files before erasure
  • Time Requirements - Higher security levels require significantly more time
  • Volume Names - Escape spaces in volume names with backslashes
  • Security vs Performance - Balance security needs with time constraints
  • Verification - Always verify erasure completion for compliance
  • Documentation - Maintain proper audit trails and certificates for regulatory compliance

Secure Archive Management on macOS

Manage secure file archives across your MacFleet devices with enterprise-grade compression and encryption tools. This tutorial covers password-protected ZIP creation, batch archive operations, security compliance, and comprehensive fleet-wide archive management.

Understanding Secure Archive Management

Secure archive management on macOS involves creating protected compressed files for data transfer, storage, and compliance:

Core Components

  • ZIP Compression - Standard archive format with broad compatibility
  • Password Protection - AES encryption for archive security
  • Batch Operations - Mass archive creation and management
  • Integrity Verification - Archive validation and corruption detection
  • Compliance Tracking - Audit trails and security reporting

Enterprise Benefits

  • Data Security - Protected file transfer and storage
  • Storage Optimization - Compressed archives save disk space
  • Compliance Requirements - Secure data archival for regulations
  • Fleet Management - Standardized archive operations across devices
  • Audit Capabilities - Complete tracking of archive operations

Basic Password-Protected ZIP Creation

Simple ZIP Creation with Password

#!/bin/bash

# Basic password-protected ZIP creation
create_basic_password_zip() {
    local file_path="${1:-/Users/Shared/example.txt}"
    local zip_name="${2:-secure_archive.zip}"
    local password="${3:-ChangeMeNow123!}"
    local content="${4:-Hello MacFleet - Secure Archive Created}"
    
    echo "đŸ“Ļ Creating Password-Protected ZIP Archive"
    echo "========================================="
    echo "File: $file_path"
    echo "Archive: $zip_name"
    echo "Content: $content"
    echo ""
    
    # Create the file with content
    echo "Creating file with content..."
    touch "$file_path"
    printf '%s\n' "$content" > "$file_path"
    
    if [[ -f "$file_path" ]]; then
        echo "✅ File created successfully: $file_path"
    else
        echo "❌ Failed to create file: $file_path"
        return 1
    fi
    
    # Navigate to file directory
    local file_dir=$(dirname "$file_path")
    local file_name=$(basename "$file_path")
    
    echo "Navigating to directory: $file_dir"
    cd "$file_dir" || return 1
    
    # Create password-protected ZIP
    echo "Creating password-protected ZIP archive..."
    if zip -r "$zip_name" "$file_name" --password "$password" >/dev/null 2>&1; then
        echo "✅ ZIP archive created successfully: $file_dir/$zip_name"
        
        # Verify archive
        if [[ -f "$zip_name" ]]; then
            local zip_size=$(du -h "$zip_name" | cut -f1)
            echo "Archive size: $zip_size"
            echo "Archive location: $file_dir/$zip_name"
        fi
    else
        echo "❌ Failed to create ZIP archive"
        return 1
    fi
    
    # Clean up original file (optional)
    echo ""
    read -p "Remove original file? (y/n): " remove_original
    if [[ "$remove_original" =~ ^[Yy]$ ]]; then
        rm "$file_path"
        echo "✅ Original file removed"
    fi
    
    return 0
}

# Execute basic ZIP creation
create_basic_password_zip "/Users/Shared/macfleet_test.txt" "macfleet_secure.zip" "SecurePass123!" "MacFleet Enterprise Archive"

Convert Existing File to Password-Protected ZIP

#!/bin/bash

# Convert existing file to password-protected ZIP
convert_file_to_secure_zip() {
    local source_file="$1"
    local zip_name="${2:-}"
    local password="${3:-}"
    local compression_level="${4:-6}"
    
    echo "🔄 Converting File to Secure ZIP"
    echo "================================"
    echo ""
    
    # Validate input file
    if [[ ! -f "$source_file" ]]; then
        echo "❌ Source file not found: $source_file"
        echo "Please provide a valid file path"
        return 1
    fi
    
    # Get file information
    local file_dir=$(dirname "$source_file")
    local file_name=$(basename "$source_file")
    local file_ext="${file_name##*.}"
    local file_base="${file_name%.*}"
    
    # Generate ZIP name if not provided
    if [[ -z "$zip_name" ]]; then
        zip_name="${file_base}_secure.zip"
    fi
    
    # Generate secure password if not provided
    if [[ -z "$password" ]]; then
        password=$(openssl rand -base64 12 | tr -d "=+/" | cut -c1-12)
        echo "🔐 Generated secure password: $password"
        echo "âš ī¸ Save this password - it cannot be recovered!"
    fi
    
    echo "Source file: $source_file"
    echo "Archive name: $zip_name"
    echo "Compression level: $compression_level (1-9)"
    echo ""
    
    # Get file size before compression
    local original_size=$(du -h "$source_file" | cut -f1)
    echo "Original file size: $original_size"
    
    # Navigate to file directory
    cd "$file_dir" || return 1
    
    # Create secure ZIP with specified compression
    echo "Creating secure ZIP archive..."
    if zip -"$compression_level" -r "$zip_name" "$file_name" --password "$password" >/dev/null 2>&1; then
        echo "✅ Secure ZIP created successfully"
        
        # Get compressed size and calculate compression ratio
        local compressed_size=$(du -h "$zip_name" | cut -f1)
        local original_bytes=$(du -b "$source_file" | cut -f1)
        local compressed_bytes=$(du -b "$zip_name" | cut -f1)
        local compression_ratio=$(echo "scale=1; (($original_bytes - $compressed_bytes) * 100) / $original_bytes" | bc 2>/dev/null || echo "N/A")
        
        echo ""
        echo "=== Archive Summary ==="
        echo "Original size: $original_size"
        echo "Compressed size: $compressed_size"
        echo "Compression ratio: ${compression_ratio}%"
        echo "Archive location: $file_dir/$zip_name"
        echo "Password: $password"
        
        # Test archive integrity
        echo ""
        echo "Testing archive integrity..."
        if unzip -t "$zip_name" >/dev/null 2>&1; then
            echo "✅ Archive integrity verified"
        else
            echo "âš ī¸ Archive integrity check failed"
        fi
        
    else
        echo "❌ Failed to create secure ZIP archive"
        return 1
    fi
    
    return 0
}

# Example usage
echo "Example: Convert existing file to secure ZIP"
# convert_file_to_secure_zip "/Users/Shared/document.pdf" "secure_document.zip" "MySecurePass123!"

Enterprise Archive Management

Comprehensive Archive Creation System

#!/bin/bash

# Enterprise archive management system
enterprise_archive_manager() {
    local operation="${1:-create}"
    local source_path="$2"
    local archive_config="${3:-default}"
    local output_dir="${4:-/tmp/macfleet_archives}"
    
    echo "đŸĸ MacFleet Enterprise Archive Manager"
    echo "====================================="
    echo "Operation: $operation"
    echo "Source: $source_path"
    echo "Config: $archive_config"
    echo "Output: $output_dir"
    echo ""
    
    # Ensure output directory exists
    mkdir -p "$output_dir"
    
    # Configuration presets
    declare -A archive_configs
    archive_configs[default]="zip:6:AES256"
    archive_configs[high_security]="zip:9:AES256"
    archive_configs[fast]="zip:1:AES128"
    archive_configs[maximum]="zip:9:AES256"
    
    # Parse configuration
    local config_string="${archive_configs[$archive_config]:-${archive_configs[default]}}"
    IFS=':' read -r format compression encryption <<< "$config_string"
    
    # Generate secure metadata
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local hostname=$(hostname)
    local user=$(whoami)
    local archive_id=$(openssl rand -hex 8)
    
    case "$operation" in
        "create")
            create_enterprise_archive "$source_path" "$output_dir" "$format" "$compression" "$encryption" "$timestamp" "$archive_id"
            ;;
        "batch")
            batch_archive_creation "$source_path" "$output_dir" "$format" "$compression" "$encryption"
            ;;
        "verify")
            verify_archive_integrity "$source_path"
            ;;
        "extract")
            secure_archive_extraction "$source_path" "$output_dir"
            ;;
        *)
            echo "❌ Unknown operation: $operation"
            echo "Available operations: create, batch, verify, extract"
            return 1
            ;;
    esac
}

# Create enterprise-grade archive
create_enterprise_archive() {
    local source="$1"
    local output_dir="$2"
    local format="$3"
    local compression="$4"
    local encryption="$5"
    local timestamp="$6"
    local archive_id="$7"
    
    echo "đŸ“Ļ Creating Enterprise Archive"
    echo "============================="
    
    # Validate source
    if [[ ! -e "$source" ]]; then
        echo "❌ Source not found: $source"
        return 1
    fi
    
    # Generate secure password
    local password=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
    
    # Determine archive name
    local source_name=$(basename "$source")
    local archive_name="macfleet_${archive_id}_${timestamp}.${format}"
    local archive_path="$output_dir/$archive_name"
    local metadata_file="$output_dir/${archive_name}.metadata.json"
    local password_file="$output_dir/${archive_name}.password"
    
    echo "Archive ID: $archive_id"
    echo "Source: $source"
    echo "Archive: $archive_path"
    echo "Compression: Level $compression"
    echo "Encryption: $encryption"
    echo ""
    
    # Get source information
    local source_size=""
    local source_type=""
    local file_count=0
    
    if [[ -f "$source" ]]; then
        source_type="file"
        source_size=$(du -h "$source" | cut -f1)
        file_count=1
    elif [[ -d "$source" ]]; then
        source_type="directory"
        source_size=$(du -sh "$source" | cut -f1)
        file_count=$(find "$source" -type f | wc -l | xargs)
    fi
    
    echo "Source type: $source_type"
    echo "Source size: $source_size"
    echo "File count: $file_count"
    echo ""
    
    # Create archive
    echo "Creating archive..."
    local start_time=$(date +%s)
    
    if zip -r -"$compression" "$archive_path" "$source" --password "$password" >/dev/null 2>&1; then
        local end_time=$(date +%s)
        local duration=$((end_time - start_time))
        
        echo "✅ Archive created successfully"
        echo "Creation time: ${duration}s"
        
        # Get archive statistics
        local archive_size=$(du -h "$archive_path" | cut -f1)
        local checksum=$(shasum -a 256 "$archive_path" | cut -d' ' -f1)
        
        # Save password securely
        echo "$password" > "$password_file"
        chmod 600 "$password_file"
        
        # Generate metadata
        cat > "$metadata_file" << EOF
{
    "archive_info": {
        "id": "$archive_id",
        "name": "$archive_name",
        "created": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
        "hostname": "$(hostname)",
        "user": "$(whoami)",
        "macfleet_version": "2025.07"
    },
    "source_info": {
        "path": "$source",
        "type": "$source_type",
        "size": "$source_size",
        "file_count": $file_count
    },
    "archive_details": {
        "format": "$format",
        "compression_level": $compression,
        "encryption": "$encryption",
        "size": "$archive_size",
        "checksum_sha256": "$checksum",
        "creation_duration": ${duration}
    },
    "security": {
        "password_protected": true,
        "password_file": "${archive_name}.password",
        "encryption_algorithm": "AES-256"
    }
}
EOF
        
        echo ""
        echo "=== Archive Summary ==="
        echo "Archive: $archive_path"
        echo "Size: $archive_size"
        echo "Checksum: $checksum"
        echo "Password file: $password_file"
        echo "Metadata: $metadata_file"
        
    else
        echo "❌ Failed to create archive"
        return 1
    fi
}

# Batch archive creation
batch_archive_creation() {
    local source_dir="$1"
    local output_dir="$2"
    local format="$3"
    local compression="$4"
    local encryption="$5"
    
    echo "đŸ“Ļ Batch Archive Creation"
    echo "========================"
    echo "Source directory: $source_dir"
    echo ""
    
    if [[ ! -d "$source_dir" ]]; then
        echo "❌ Source directory not found: $source_dir"
        return 1
    fi
    
    local processed=0
    local failed=0
    
    # Process each item in source directory
    for item in "$source_dir"/*; do
        if [[ -e "$item" ]]; then
            local item_name=$(basename "$item")
            echo "Processing: $item_name"
            
            local timestamp=$(date +"%Y%m%d_%H%M%S")
            local archive_id=$(openssl rand -hex 4)
            
            if create_enterprise_archive "$item" "$output_dir" "$format" "$compression" "$encryption" "$timestamp" "$archive_id"; then
                echo "✅ Successfully archived: $item_name"
                ((processed++))
            else
                echo "❌ Failed to archive: $item_name"
                ((failed++))
            fi
            echo ""
        fi
    done
    
    echo "=== Batch Summary ==="
    echo "Processed: $processed"
    echo "Failed: $failed"
    echo "Total: $((processed + failed))"
}

# Archive integrity verification
verify_archive_integrity() {
    local archive_path="$1"
    
    echo "🔍 Archive Integrity Verification"
    echo "================================="
    echo "Archive: $archive_path"
    echo ""
    
    if [[ ! -f "$archive_path" ]]; then
        echo "❌ Archive not found: $archive_path"
        return 1
    fi
    
    # Check if it's a ZIP file
    if ! file "$archive_path" | grep -q "Zip archive"; then
        echo "❌ Not a valid ZIP archive"
        return 1
    fi
    
    # Test archive integrity
    echo "Testing archive integrity..."
    if unzip -t "$archive_path" >/dev/null 2>&1; then
        echo "✅ Archive integrity verified"
        
        # Get archive information
        local archive_size=$(du -h "$archive_path" | cut -f1)
        local file_count=$(unzip -l "$archive_path" 2>/dev/null | tail -1 | awk '{print $2}' || echo "Unknown")
        
        echo ""
        echo "=== Archive Information ==="
        echo "Size: $archive_size"
        echo "Files: $file_count"
        echo "Format: ZIP"
        
        # Check for metadata
        local metadata_file="${archive_path}.metadata.json"
        if [[ -f "$metadata_file" ]]; then
            echo "Metadata: Available"
            local creation_date=$(jq -r '.archive_info.created' "$metadata_file" 2>/dev/null || echo "Unknown")
            local archive_id=$(jq -r '.archive_info.id' "$metadata_file" 2>/dev/null || echo "Unknown")
            echo "Created: $creation_date"
            echo "Archive ID: $archive_id"
        else
            echo "Metadata: Not available"
        fi
        
    else
        echo "❌ Archive integrity check failed"
        echo "Archive may be corrupted or password-protected"
        return 1
    fi
}

# Usage examples
echo "Archive Manager Examples:"
echo "==================================="
echo ""

echo "1. Create enterprise archive:"
enterprise_archive_manager "create" "/Users/Shared/documents" "high_security" "/tmp/archives"
echo ""

echo "2. Batch archive creation:"
enterprise_archive_manager "batch" "/Users/Shared/batch_source" "default" "/tmp/batch_archives"
echo ""

echo "3. Verify archive integrity:"
enterprise_archive_manager "verify" "/tmp/archives/example.zip"

Security and Compliance Features

Advanced Security Archive System

#!/bin/bash

# Advanced security and compliance archive system
secure_compliance_archiver() {
    local operation="${1:-audit}"
    local archive_path="$2"
    local compliance_level="${3:-standard}"
    
    echo "🔒 Secure Compliance Archiver"
    echo "============================="
    echo "Operation: $operation"
    echo "Compliance level: $compliance_level"
    echo ""
    
    case "$operation" in
        "audit")
            perform_security_audit "$archive_path" "$compliance_level"
            ;;
        "encrypt")
            apply_advanced_encryption "$archive_path" "$compliance_level"
            ;;
        "validate")
            validate_compliance_requirements "$archive_path" "$compliance_level"
            ;;
        "report")
            generate_compliance_report "$compliance_level"
            ;;
        *)
            echo "❌ Unknown operation: $operation"
            echo "Available operations: audit, encrypt, validate, report"
            return 1
            ;;
    esac
}

# Security audit for archives
perform_security_audit() {
    local archive_path="$1"
    local compliance_level="$2"
    
    echo "🔍 Security Audit"
    echo "================="
    echo ""
    
    local audit_passed=0
    local audit_warnings=0
    local audit_failures=0
    
    # Check file permissions
    if [[ -f "$archive_path" ]]; then
        local permissions=$(stat -f "%A" "$archive_path" 2>/dev/null || echo "unknown")
        echo "File permissions: $permissions"
        
        if [[ "$permissions" =~ ^[67][0-4][0-4]$ ]]; then
            echo "✅ Permissions are secure"
            ((audit_passed++))
        else
            echo "âš ī¸ Permissions may be too permissive"
            ((audit_warnings++))
        fi
    fi
    
    # Check encryption status
    if file "$archive_path" | grep -q "password-protected\|encrypted"; then
        echo "✅ Archive is password-protected"
        ((audit_passed++))
    else
        echo "❌ Archive is not password-protected"
        ((audit_failures++))
    fi
    
    # Check metadata integrity
    local metadata_file="${archive_path}.metadata.json"
    if [[ -f "$metadata_file" ]]; then
        echo "✅ Metadata file present"
        ((audit_passed++))
        
        # Validate JSON
        if jq empty "$metadata_file" 2>/dev/null; then
            echo "✅ Metadata format valid"
            ((audit_passed++))
        else
            echo "❌ Metadata format invalid"
            ((audit_failures++))
        fi
    else
        echo "âš ī¸ Metadata file missing"
        ((audit_warnings++))
    fi
    
    # Compliance-specific checks
    case "$compliance_level" in
        "high"|"enterprise")
            # Check for secure password file
            local password_file="${archive_path}.password"
            if [[ -f "$password_file" ]]; then
                local pass_permissions=$(stat -f "%A" "$password_file" 2>/dev/null || echo "unknown")
                if [[ "$pass_permissions" == "600" ]]; then
                    echo "✅ Password file permissions secure"
                    ((audit_passed++))
                else
                    echo "❌ Password file permissions insecure"
                    ((audit_failures++))
                fi
            fi
            ;;
    esac
    
    # Generate audit summary
    echo ""
    echo "=== Security Audit Summary ==="
    echo "Passed: $audit_passed"
    echo "Warnings: $audit_warnings"
    echo "Failures: $audit_failures"
    
    local total_checks=$((audit_passed + audit_warnings + audit_failures))
    if [[ "$audit_failures" -eq 0 ]]; then
        echo "🎉 Security audit PASSED"
        return 0
    else
        echo "❌ Security audit FAILED"
        return 1
    fi
}

# Generate compliance report
generate_compliance_report() {
    local compliance_level="$1"
    local report_file="/tmp/macfleet_archive_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📊 Generating Compliance Report"
    echo "==============================="
    echo ""
    
    # Scan for all MacFleet archives
    local archive_dirs=("/tmp/macfleet_archives" "/tmp/archives" "/tmp/batch_archives")
    local total_archives=0
    local compliant_archives=0
    local non_compliant_archives=0
    
    {
        echo "{"
        echo "  \"compliance_report\": {"
        echo "    \"generated\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\","
        echo "    \"hostname\": \"$(hostname)\","
        echo "    \"compliance_level\": \"$compliance_level\","
        echo "    \"archives\": ["
        
        local first_archive=true
        
        for dir in "${archive_dirs[@]}"; do
            if [[ -d "$dir" ]]; then
                for archive in "$dir"/*.zip; do
                    if [[ -f "$archive" ]]; then
                        if [[ "$first_archive" == "false" ]]; then
                            echo ","
                        fi
                        
                        local archive_name=$(basename "$archive")
                        local archive_size=$(du -h "$archive" | cut -f1)
                        local is_compliant="false"
                        
                        # Check compliance
                        if perform_security_audit "$archive" "$compliance_level" >/dev/null 2>&1; then
                            is_compliant="true"
                            ((compliant_archives++))
                        else
                            ((non_compliant_archives++))
                        fi
                        
                        echo "      {"
                        echo "        \"name\": \"$archive_name\","
                        echo "        \"path\": \"$archive\","
                        echo "        \"size\": \"$archive_size\","
                        echo "        \"compliant\": $is_compliant"
                        echo -n "      }"
                        
                        first_archive=false
                        ((total_archives++))
                    fi
                done
            fi
        done
        
        echo ""
        echo "    ],"
        echo "    \"summary\": {"
        echo "      \"total_archives\": $total_archives,"
        echo "      \"compliant\": $compliant_archives,"
        echo "      \"non_compliant\": $non_compliant_archives,"
        echo "      \"compliance_rate\": \"$(echo "scale=1; ($compliant_archives * 100) / $total_archives" | bc 2>/dev/null || echo "0")%\""
        echo "    }"
        echo "  }"
        echo "}"
    } > "$report_file"
    
    echo "✅ Compliance report generated: $report_file"
    echo ""
    echo "=== Summary ==="
    echo "Total archives: $total_archives"
    echo "Compliant: $compliant_archives"
    echo "Non-compliant: $non_compliant_archives"
    
    if [[ "$total_archives" -gt 0 ]]; then
        local compliance_rate=$(echo "scale=1; ($compliant_archives * 100) / $total_archives" | bc 2>/dev/null || echo "0")
        echo "Compliance rate: ${compliance_rate}%"
    fi
}

# Execute compliance operations
echo "Security and Compliance Examples:"
echo "================================"
echo ""

echo "1. Generate compliance report:"
secure_compliance_archiver "report" "" "enterprise"

Important Notes

Enterprise Features

  • Advanced Security - AES-256 encryption with secure password generation
  • Metadata Management - Comprehensive archive tracking and documentation
  • Batch Operations - Mass archive creation and management
  • Integrity Verification - Archive validation and corruption detection
  • Compliance Reporting - Security audit and compliance tracking
  • Fleet Deployment - Standardized archive operations across devices

Security Best Practices

  • Strong Passwords - Cryptographically secure password generation
  • Secure Storage - Protected password files with restricted permissions
  • Encryption Standards - AES-256 encryption for maximum security
  • Audit Trails - Complete operation logging and tracking
  • Access Controls - Proper file permissions and security measures

Supported Operations

  • Create - Single file or directory archive creation
  • Batch - Multiple archive creation from directory contents
  • Verify - Archive integrity testing and validation
  • Extract - Secure archive extraction with verification
  • Audit - Security compliance checking and reporting

Usage Examples

# Basic password-protected ZIP
touch /Users/Shared/filename.txt
printf 'Hello world\n' > /Users/Shared/filename.txt
cd /Users/Shared
zip -r filename.zip filename.txt --password 1234

# Enhanced MacFleet enterprise archive
create_basic_password_zip "/Users/Shared/document.pdf" "secure_doc.zip" "SecurePass123!"

# Enterprise archive with metadata
enterprise_archive_manager "create" "/Users/Shared/projects" "high_security" "/tmp/archives"

# Batch archive creation
enterprise_archive_manager "batch" "/Users/Shared/documents" "default" "/tmp/batch_archives"

# Security audit
secure_compliance_archiver "audit" "/tmp/archives/example.zip" "enterprise"

Configure Screenshot Settings on macOS

Learn how to customize screenshot behavior on Mac devices including file format, save location, and naming conventions. Essential for standardizing screenshot settings across enterprise Mac fleets.

Change Screenshot Format

Change the default screenshot format from PNG to other formats:

#!/bin/bash

# Get current user context
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

# Configuration
SCREENSHOT_FORMAT="JPG"  # Options: PNG, JPG, PDF, PSD, TIFF, GIF, BMP

echo "Setting screenshot format to: $SCREENSHOT_FORMAT"

# Apply screenshot format setting
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture type "$SCREENSHOT_FORMAT"

# Restart SystemUIServer to apply changes
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Screenshot format changed to $SCREENSHOT_FORMAT"

Change Screenshot Location

Change the default save location from Desktop to another folder:

#!/bin/bash

# Get current user context
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

# Configuration
SCREENSHOT_LOCATION="$HOME/Downloads"  # Change to desired location

echo "Setting screenshot location to: $SCREENSHOT_LOCATION"

# Ensure directory exists
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    mkdir -p "$SCREENSHOT_LOCATION"

# Apply screenshot location setting
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture location "$SCREENSHOT_LOCATION"

# Restart SystemUIServer to apply changes
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Screenshot location changed to $SCREENSHOT_LOCATION"

Change Screenshot Naming

Customize screenshot filename prefix and date/time inclusion:

#!/bin/bash

# Get current user context
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

# Configuration
SCREENSHOT_PREFIX="MacFleet"  # Change prefix from "Screenshot"
INCLUDE_DATETIME="0"          # 0=exclude, 1=include date/time

echo "Setting screenshot prefix to: $SCREENSHOT_PREFIX"
echo "Include date/time: $INCLUDE_DATETIME"

# Apply screenshot naming settings
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture name "$SCREENSHOT_PREFIX"

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture include-date "$INCLUDE_DATETIME"

# Restart SystemUIServer to apply changes
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Screenshot naming updated"
if [[ "$INCLUDE_DATETIME" == "0" ]]; then
    echo "📝 New filename format: ${SCREENSHOT_PREFIX}.png"
else
    echo "📝 New filename format: ${SCREENSHOT_PREFIX} [date] at [time].png"
fi

Complete Screenshot Configuration

Comprehensive script to configure all screenshot settings at once:

#!/bin/bash

# Function to configure screenshot settings
configure_screenshot_settings() {
    local format="$1"
    local location="$2"
    local prefix="$3"
    local include_date="$4"
    
    # Get current user context
    local current_user=$(stat -f "%Su" /dev/console)
    local current_user_uid=$(id -u "$current_user")
    
    echo "=== MacFleet Screenshot Configuration ==="
    echo "👤 User: $current_user"
    echo "📸 Format: $format"
    echo "📁 Location: $location"
    echo "📝 Prefix: $prefix"
    echo "📅 Include date/time: $include_date"
    echo "========================================"
    
    # Create location directory if needed
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        mkdir -p "$location"
    
    # Apply all screenshot settings
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture type "$format"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture location "$location"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture name "$prefix"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture include-date "$include_date"
    
    # Restart SystemUIServer to apply all changes
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        killall SystemUIServer
    
    echo "✅ All screenshot settings applied successfully"
    
    # Show example filename
    if [[ "$include_date" == "0" ]]; then
        echo "📝 Example filename: ${prefix}.${format,,}"
    else
        echo "📝 Example filename: ${prefix} $(date '+%Y-%m-%d') at $(date '+%H.%M.%S').${format,,}"
    fi
}

# Enterprise configuration
SCREENSHOT_FORMAT="PNG"
SCREENSHOT_LOCATION="/Users/$(stat -f "%Su" /dev/console)/Pictures/Screenshots"
SCREENSHOT_PREFIX="MacFleet-Screenshot"
INCLUDE_DATETIME="1"

# Apply configuration
configure_screenshot_settings "$SCREENSHOT_FORMAT" "$SCREENSHOT_LOCATION" "$SCREENSHOT_PREFIX" "$INCLUDE_DATETIME"

Reset to Default Settings

Restore screenshot settings to macOS defaults:

#!/bin/bash

# Get current user context
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

echo "🔄 Resetting screenshot settings to defaults..."

# Remove custom screenshot settings
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture type 2>/dev/null || true

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture location 2>/dev/null || true

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture name 2>/dev/null || true

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture include-date 2>/dev/null || true

# Restart SystemUIServer to apply changes
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Screenshot settings reset to defaults"
echo "📝 Default: PNG format, Desktop location, 'Screenshot' prefix with date/time"

Enterprise Deployment Script

Script for bulk deployment across multiple Mac devices:

#!/bin/bash

# Enterprise screenshot standardization
COMPANY_NAME="MacFleet"
SCREENSHOT_CONFIG=(
    "format:PNG"
    "location:/Users/CURRENT_USER/Documents/Screenshots"
    "prefix:${COMPANY_NAME}-Screen"
    "include-date:1"
)

# Function to apply enterprise screenshot policy
apply_enterprise_screenshot_policy() {
    local current_user=$(stat -f "%Su" /dev/console)
    local current_user_uid=$(id -u "$current_user")
    
    echo "đŸĸ Applying Enterprise Screenshot Policy"
    echo "========================================="
    echo "Device: $(hostname)"
    echo "User: $current_user"
    echo "Timestamp: $(date)"
    
    # Parse configuration
    local format location prefix include_date
    for config in "${SCREENSHOT_CONFIG[@]}"; do
        IFS=':' read -r key value <<< "$config"
        # Replace CURRENT_USER placeholder
        value="${value//CURRENT_USER/$current_user}"
        
        case "$key" in
            "format") format="$value" ;;
            "location") location="$value" ;;
            "prefix") prefix="$value" ;;
            "include-date") include_date="$value" ;;
        esac
    done
    
    echo "📸 Format: $format"
    echo "📁 Location: $location"
    echo "📝 Prefix: $prefix"
    echo "📅 Include date: $include_date"
    
    # Create screenshots directory
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        mkdir -p "$location"
    
    # Apply settings
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture type "$format"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture location "$location"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture name "$prefix"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture include-date "$include_date"
    
    # Apply changes
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        killall SystemUIServer
    
    echo "✅ Enterprise screenshot policy applied"
    echo "📊 Configuration complete on $(hostname)"
}

# Execute enterprise policy
apply_enterprise_screenshot_policy

Usage with MacFleet

  1. Configure desired format, location, and naming in the script variables
  2. Deploy through MacFleet's remote script execution
  3. Verify settings by taking a test screenshot
  4. Monitor compliance across device fleet

Supported File Formats

FormatDescriptionUse Case
PNGLossless compressionDefault, best quality
JPGLossy compressionSmaller file sizes
PDFVector formatDocument screenshots
TIFFHigh qualityProfessional imaging
GIFAnimation supportSimple graphics
BMPUncompressedWindows compatibility
PSDPhotoshop formatDesign workflows

Common Location Options

LocationPathPurpose
Desktop~/DesktopDefault location
Downloads~/DownloadsEasy access
Documents~/DocumentsOrganization
Pictures~/Pictures/ScreenshotsPhoto library
Custom/path/to/folderCompany specific

Troubleshooting

Settings not applied: Ensure SystemUIServer is restarted after changes Permission denied: Verify user context with launchctl asuser Directory not found: Ensure target directory exists before setting location

Managing Screen Mirroring Icon in Mac Menu Bar

Screen Mirroring on Mac utilizes Apple's AirPlay technology to wirelessly display your Mac's screen content on compatible devices like Apple TV or AirPlay-enabled smart TVs. For administrators managing multiple Mac systems, controlling the visibility of the Screen Mirroring icon in the menu bar can help streamline the user interface and maintain consistency across devices.

This guide provides shell scripts to programmatically show or hide the Screen Mirroring icon in the Mac menu bar, particularly useful for fleet management and automated deployment scenarios.

Understanding Screen Mirroring

Screen Mirroring allows you to:

  • Display your Mac's screen on Apple TV or compatible smart TVs
  • Mirror presentations during meetings
  • Stream content to larger displays
  • Share your screen wirelessly within the same network

The Screen Mirroring option can be controlled through System Settings, but for automated management across multiple devices, shell scripts provide a more efficient solution.

Prerequisites

Before running these scripts, ensure you have:

  • Administrative privileges on the Mac
  • Terminal access
  • macOS 10.15 or later
  • Understanding of shell scripting basics

Script to Show Screen Mirroring Icon

This script makes the Screen Mirroring icon visible in the menu bar:

#!/bin/bash

# Get the current user and their UID
CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
CurrentUserUID=$(id -u "$CurrentUser")

# Enable Screen Mirroring in menu bar
launchctl asuser $CurrentUserUID sudo -iu "$CurrentUser" defaults write com.apple.airplay showInMenuBarIfPresent -int 1

echo "Screen Mirroring icon has been enabled in the menu bar"

What this script does:

  1. Identifies the current user: Uses /dev/console to determine who is currently logged in
  2. Gets user ID: Retrieves the numeric user ID for the current user
  3. Applies setting: Uses launchctl asuser to run the defaults command in the user's context
  4. Enables the icon: Sets showInMenuBarIfPresent to 1 to show the icon

Script to Hide Screen Mirroring Icon

This script hides the Screen Mirroring icon from the menu bar:

#!/bin/bash

# Get the current user and their UID
CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
CurrentUserUID=$(id -u "$CurrentUser")

# Disable Screen Mirroring in menu bar
launchctl asuser $CurrentUserUID sudo -iu "$CurrentUser" defaults write com.apple.airplay showInMenuBarIfPresent -int 0

echo "Screen Mirroring icon has been hidden from the menu bar"

What this script does:

  1. Identifies the current user: Same process as the show script
  2. Gets user ID: Retrieves the numeric user ID
  3. Applies setting: Uses launchctl asuser for proper user context
  4. Hides the icon: Sets showInMenuBarIfPresent to 0 to hide the icon

Usage Instructions

Running the Scripts

  1. Save the script to a file (e.g., show_screen_mirroring.sh or hide_screen_mirroring.sh)
  2. Make it executable:
    chmod +x show_screen_mirroring.sh
  3. Run the script:
    ./show_screen_mirroring.sh

Verification

After running either script, you can verify the changes:

  1. Check the menu bar: The Screen Mirroring icon should appear or disappear based on the script executed
  2. Check System Settings:
    • Go to System Settings > Control Center > Screen Mirroring
    • The "Always Show in Menu Bar" option should reflect the script's action

Advanced Usage

Checking Current Status

You can check the current status of the Screen Mirroring icon:

#!/bin/bash

CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
CurrentUserUID=$(id -u "$CurrentUser")

status=$(launchctl asuser $CurrentUserUID sudo -iu "$CurrentUser" defaults read com.apple.airplay showInMenuBarIfPresent 2>/dev/null)

if [ "$status" = "1" ]; then
    echo "Screen Mirroring icon is currently shown in menu bar"
elif [ "$status" = "0" ]; then
    echo "Screen Mirroring icon is currently hidden from menu bar"
else
    echo "Screen Mirroring menu bar setting is not configured"
fi

Compatibility Notes

  • macOS 12.0 and below: The setting is located in System Preferences > Dock & Menu Bar > AirPlay
  • macOS 13.0 and above: The setting is in System Settings > Control Center > Screen Mirroring
  • User Override: Users can manually change this setting from the System Settings, overriding the script's configuration

Best Practices

  1. Test First: Always test scripts on a single device before bulk deployment
  2. Backup Settings: Consider backing up current settings before making changes
  3. User Communication: Inform users about changes to their menu bar configuration
  4. Documentation: Keep records of which devices have which configurations
  5. Regular Audits: Periodically verify that settings remain as intended

Troubleshooting

Common Issues

  1. Permission Denied: Ensure the script has sudo privileges
  2. User Not Found: The script may fail if run when no user is logged in
  3. Setting Not Applied: Try logging out and back in to refresh the menu bar

Debugging

Add debugging to your scripts:

#!/bin/bash

# Enable debugging
set -x

CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
echo "Current user: $CurrentUser"

CurrentUserUID=$(id -u "$CurrentUser")
echo "User UID: $CurrentUserUID"

# Continue with the rest of the script...

Security Considerations

  • These scripts require administrative privileges
  • Always validate the source of scripts before execution
  • Consider implementing logging for audit trails
  • Test scripts in a controlled environment first

Conclusion

Managing the Screen Mirroring icon visibility in the Mac menu bar through shell scripts provides administrators with powerful tools for maintaining consistent user interfaces across their Mac fleet. Whether you're deploying to a single device or managing hundreds of Macs, these scripts offer a reliable, automated solution.

Remember to thoroughly test any scripts in your environment and consider the user experience when making interface changes. With proper implementation, you can streamline your Mac management workflow while maintaining the flexibility that users need for their daily work.