Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Aviso importante

Los ejemplos de código y scripts proporcionados en estos tutoriales son solo para propósitos educativos. Macfleet no es responsable de ningún problema, daño o vulnerabilidad de seguridad que pueda surgir del uso, modificación o implementación de estos ejemplos. Siempre revisa y prueba el código en un entorno seguro antes de usarlo en sistemas de producción.

User Account Deletion and Lifecycle Management on macOS

Manage user account lifecycle and secure deletion processes across your MacFleet devices with comprehensive user management, data retention policies, and enterprise offboarding procedures. This tutorial covers secure user deletion, data archival, and compliance-driven user lifecycle management.

Understanding User Account Deletion

User account deletion on macOS involves multiple components and security considerations:

  • Account Removal - Deleting the user account from system databases
  • Data Management - Handling user home directories and associated files
  • Security Tokens - Managing Secure Token requirements for deletion
  • Enterprise Compliance - Meeting data retention and privacy requirements

Enterprise Considerations

Proper user account deletion requires enterprise planning:

  • Data Retention Policies - Compliance with legal and regulatory requirements
  • Security Protocols - Ensuring complete data removal and access revocation
  • Audit Requirements - Maintaining deletion logs for compliance tracking
  • Recovery Procedures - Backup and recovery capabilities before deletion
  • Process Automation - Streamlined offboarding for departing employees

Basic User Account Deletion

Prerequisites and Security Requirements

#!/bin/bash

# Check prerequisites for user deletion
check_deletion_prerequisites() {
    echo "=== User Deletion Prerequisites Check ==="
    
    # Check if running with administrator privileges
    if [[ $EUID -ne 0 ]]; then
        echo "⚠️ Warning: This script requires administrator privileges"
        echo "Run with: sudo $0"
    else
        echo "✓ Administrator privileges confirmed"
    fi
    
    # Check Service app full disk access
    echo ""
    echo "--- Full Disk Access Check ---"
    local tcc_db="/Library/Application Support/com.apple.TCC/TCC.db"
    if [[ -r "$tcc_db" ]]; then
        echo "✓ TCC database accessible - Full disk access likely granted"
    else
        echo "⚠️ Warning: TCC database not accessible"
        echo "Ensure Service app has Full Disk Access in System Preferences"
    fi
    
    # Check available Secure Token holders
    echo ""
    echo "--- Secure Token Analysis ---"
    local secure_token_users=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
    echo "Secure Token holders found: $secure_token_users"
    
    if [[ $secure_token_users -lt 2 ]]; then
        echo "⚠️ Warning: Less than 2 Secure Token holders detected"
        echo "Cannot delete the only Secure Token holder"
        echo "Add another admin user with Secure Token before deletion"
    else
        echo "✓ Multiple Secure Token holders available"
    fi
}

# Usage
check_deletion_prerequisites

Safe User Account Deletion

#!/bin/bash

# Safely delete user account with validation
delete_user_account() {
    local username="$1"
    local method="${2:-sysadminctl}"  # sysadminctl or dscl
    local backup_data="${3:-true}"
    
    if [[ -z "$username" ]]; then
        echo "Usage: delete_user_account <username> [method] [backup_data]"
        echo "Methods: sysadminctl (default), dscl"
        echo "Backup data: true (default), false"
        return 1
    fi
    
    echo "=== Safe User Account Deletion ==="
    echo "Target user: $username"
    echo "Deletion method: $method"
    echo "Backup data: $backup_data"
    echo ""
    
    # Validate user exists
    if ! id "$username" >/dev/null 2>&1; then
        echo "Error: User '$username' does not exist"
        return 1
    fi
    
    # Check if user is currently logged in
    local logged_in_users=$(who | awk '{print $1}' | sort -u)
    if echo "$logged_in_users" | grep -q "^$username$"; then
        echo "⚠️ Warning: User '$username' is currently logged in"
        echo "Force logout or wait for user to log out before deletion"
        return 1
    fi
    
    # Check Secure Token status
    local token_status=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep "Enabled")
    if [[ -n "$token_status" ]]; then
        echo "User '$username' has Secure Token"
        
        # Count total Secure Token holders
        local total_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
        if [[ $total_tokens -eq 1 ]]; then
            echo "Error: Cannot delete the only Secure Token holder"
            echo "Add another admin user with Secure Token first"
            return 1
        fi
    fi
    
    # Backup user data if requested
    if [[ "$backup_data" == "true" ]]; then
        echo "Creating backup of user data..."
        backup_user_data "$username"
    fi
    
    # Perform deletion based on method
    echo ""
    echo "--- Deleting User Account ---"
    case "$method" in
        "sysadminctl")
            delete_user_sysadminctl "$username"
            ;;
        "dscl")
            delete_user_dscl "$username"
            ;;
        *)
            echo "Error: Unknown deletion method: $method"
            return 1
            ;;
    esac
}

# Delete user using sysadminctl (macOS 10.13+)
delete_user_sysadminctl() {
    local username="$1"
    
    echo "Using sysadminctl to delete user: $username"
    
    if sysadminctl -deleteUser "$username" 2>/dev/null; then
        echo "✓ User account '$username' deleted successfully using sysadminctl"
        return 0
    else
        echo "✗ Failed to delete user '$username' using sysadminctl"
        return 1
    fi
}

# Delete user using dscl (legacy method)
delete_user_dscl() {
    local username="$1"
    
    echo "Using dscl to delete user: $username"
    
    if dscl . delete "/Users/$username" 2>/dev/null; then
        echo "✓ User account '$username' deleted successfully using dscl"
        return 0
    else
        echo "✗ Failed to delete user '$username' using dscl"
        return 1
    fi
}

# Usage example (commented out for safety)
# delete_user_account "departing_employee" "sysadminctl" "true"

User Data and Directory Management

#!/bin/bash

# Comprehensive user data management
manage_user_data() {
    local username="$1"
    local action="${2:-archive}"  # archive, delete, preserve
    local backup_location="${3:-/var/backups/user_data}"
    
    if [[ -z "$username" ]]; then
        echo "Usage: manage_user_data <username> [action] [backup_location]"
        echo "Actions: archive (default), delete, preserve"
        return 1
    fi
    
    echo "=== User Data Management ==="
    echo "Username: $username"
    echo "Action: $action"
    echo "Backup location: $backup_location"
    echo ""
    
    local user_home="/Users/$username"
    
    # Check if user home directory exists
    if [[ ! -d "$user_home" ]]; then
        echo "User home directory not found: $user_home"
        return 1
    fi
    
    # Get directory size for reporting
    local dir_size=$(du -sh "$user_home" 2>/dev/null | awk '{print $1}')
    echo "User home directory size: $dir_size"
    
    case "$action" in
        "archive")
            archive_user_data "$username" "$backup_location"
            ;;
        "delete")
            delete_user_data "$username"
            ;;
        "preserve")
            preserve_user_data "$username"
            ;;
        *)
            echo "Error: Unknown action: $action"
            return 1
            ;;
    esac
}

# Archive user data before deletion
archive_user_data() {
    local username="$1"
    local backup_location="$2"
    
    echo "--- Archiving User Data ---"
    
    # Create backup directory if it doesn't exist
    mkdir -p "$backup_location"
    
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local archive_name="${username}_backup_${timestamp}.tar.gz"
    local archive_path="$backup_location/$archive_name"
    
    echo "Creating archive: $archive_path"
    
    # Create compressed archive of user home directory
    if tar -czf "$archive_path" -C "/Users" "$username" 2>/dev/null; then
        echo "✓ User data archived successfully"
        
        # Create metadata file
        local metadata_file="$backup_location/${username}_metadata_${timestamp}.json"
        cat > "$metadata_file" << EOF
{
    "backup_metadata": {
        "username": "$username",
        "backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "archive_file": "$archive_name",
        "archive_size": "$(du -sh "$archive_path" | awk '{print $1}')",
        "original_path": "/Users/$username",
        "backup_location": "$backup_location",
        "hostname": "$(hostname)",
        "created_by": "$(whoami)"
    }
}
EOF
        
        echo "✓ Metadata file created: $metadata_file"
        echo "Archive details:"
        echo "  File: $archive_path"
        echo "  Size: $(du -sh "$archive_path" | awk '{print $1}')"
        
        return 0
    else
        echo "✗ Failed to create archive"
        return 1
    fi
}

# Delete user data and directories
delete_user_data() {
    local username="$1"
    local user_home="/Users/$username"
    
    echo "--- Deleting User Data ---"
    echo "⚠️ WARNING: This will permanently delete all user data"
    echo "Target directory: $user_home"
    
    # Safety check - don't delete system directories
    case "$username" in
        "root"|"admin"|"administrator"|"Guest"|"Shared")
            echo "Error: Cannot delete system user data: $username"
            return 1
            ;;
    esac
    
    if [[ "$user_home" == "/Users/"* && ${#username} -gt 2 ]]; then
        echo "Deleting user home directory..."
        if rm -rf "$user_home" 2>/dev/null; then
            echo "✓ User data deleted successfully: $user_home"
            return 0
        else
            echo "✗ Failed to delete user data: $user_home"
            return 1
        fi
    else
        echo "Error: Invalid user home path: $user_home"
        return 1
    fi
}

# Preserve user data with ownership change
preserve_user_data() {
    local username="$1"
    local user_home="/Users/$username"
    local preserved_name="${username}_preserved_$(date +%Y%m%d)"
    local preserved_path="/Users/$preserved_name"
    
    echo "--- Preserving User Data ---"
    echo "Renaming user directory for preservation"
    echo "From: $user_home"
    echo "To: $preserved_path"
    
    if mv "$user_home" "$preserved_path" 2>/dev/null; then
        # Change ownership to admin user
        chown -R root:admin "$preserved_path" 2>/dev/null
        chmod -R 755 "$preserved_path" 2>/dev/null
        
        echo "✓ User data preserved at: $preserved_path"
        echo "✓ Ownership changed to root:admin"
        return 0
    else
        echo "✗ Failed to preserve user data"
        return 1
    fi
}

# Usage example
# manage_user_data "departing_employee" "archive" "/var/backups/user_data"

Enterprise User Lifecycle Management

#!/bin/bash

# MacFleet User Account Deletion and Lifecycle Management Tool
# Comprehensive user offboarding, data management, and compliance

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_user_lifecycle.log"
REPORT_DIR="/etc/macfleet/reports/users"
CONFIG_DIR="/etc/macfleet/user_management"
POLICY_DIR="/etc/macfleet/policies/users"
BACKUP_DIR="/var/backups/macfleet/users"
COMPLIANCE_DIR="/etc/macfleet/compliance/users"

# Create directories if they don't exist
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$POLICY_DIR" "$BACKUP_DIR" "$COMPLIANCE_DIR"

# User lifecycle policies
declare -A LIFECYCLE_POLICIES=(
    ["immediate_deletion"]="delete_account,delete_data,no_backup,audit_log"
    ["secure_archival"]="backup_data,delete_account,delete_data,compliance_report"
    ["data_preservation"]="backup_data,preserve_home,delete_account,extended_audit"
    ["legal_hold"]="preserve_all,disable_account,legal_compliance,no_deletion"
    ["healthcare_hipaa"]="encrypted_backup,secure_deletion,hipaa_compliance,audit_trail"
    ["financial_compliance"]="full_backup,sox_compliance,retention_policy,secure_deletion"
    ["education_ferpa"]="student_data_protection,ferpa_compliance,selective_backup,audit_log"
    ["government_classified"]="classified_data_handling,security_clearance_check,secure_deletion,audit_trail"
    ["contractor_offboarding"]="project_data_separation,limited_backup,quick_deletion,access_revocation"
    ["temporary_disable"]="disable_only,preserve_all,no_deletion,reactivation_ready"
)

# Data retention periods (in days)
declare -A RETENTION_PERIODS=(
    ["immediate"]="0"
    ["short_term"]="30"
    ["medium_term"]="90"
    ["long_term"]="365"
    ["legal_hold"]="indefinite"
    ["compliance_minimum"]="2555"  # 7 years
)

# Compliance frameworks
declare -A COMPLIANCE_FRAMEWORKS=(
    ["hipaa"]="healthcare_data_protection,encrypted_storage,audit_logs,secure_deletion"
    ["sox"]="financial_records_retention,change_management,access_controls,audit_trail"
    ["ferpa"]="student_privacy,educational_records,consent_management,access_restrictions"
    ["gdpr"]="data_minimization,consent_withdrawal,right_to_erasure,data_portability"
    ["pci_dss"]="payment_data_protection,secure_deletion,access_monitoring,compliance_reporting"
)

# Logging function
log_action() {
    local message="$1"
    local severity="${2:-INFO}"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$severity] $message" | tee -a "$LOG_FILE"
}

# Enhanced user account deletion with enterprise features
enterprise_user_deletion() {
    local username="$1"
    local policy="${2:-secure_archival}"
    local compliance_framework="${3:-}"
    local retention_period="${4:-medium_term}"
    local authorized_by="${5:-$(whoami)}"
    
    log_action "Starting enterprise user deletion process" "INFO"
    log_action "Username: $username, Policy: $policy, Authorized by: $authorized_by" "INFO"
    
    echo "=== Enterprise User Deletion Process ==="
    echo "Username: $username"
    echo "Policy: $policy"
    echo "Compliance Framework: $compliance_framework"
    echo "Retention Period: $retention_period"
    echo "Authorized By: $authorized_by"
    echo "Process ID: $(uuidgen)"
    echo ""
    
    # Validate user exists
    if ! id "$username" >/dev/null 2>&1; then
        log_action "ERROR: User '$username' does not exist" "ERROR"
        return 1
    fi
    
    # Pre-deletion validation
    if ! pre_deletion_validation "$username"; then
        log_action "ERROR: Pre-deletion validation failed for user: $username" "ERROR"
        return 1
    fi
    
    # Apply policy-based deletion process
    apply_deletion_policy "$username" "$policy" "$compliance_framework" "$retention_period" "$authorized_by"
    
    # Generate compliance report
    generate_deletion_compliance_report "$username" "$policy" "$compliance_framework" "$authorized_by"
    
    log_action "user deletion process completed for user: $username" "INFO"
}

# Pre-deletion validation and safety checks
pre_deletion_validation() {
    local username="$1"
    
    echo "--- Pre-Deletion Validation ---"
    
    # Check if user is system user
    local user_id=$(id -u "$username" 2>/dev/null)
    if [[ $user_id -lt 500 ]]; then
        echo "✗ Cannot delete system user (UID < 500): $username"
        return 1
    fi
    
    # Check if user is currently logged in
    if who | grep -q "^$username "; then
        echo "✗ User is currently logged in: $username"
        log_action "Deletion blocked: User $username is currently logged in" "WARNING"
        return 1
    fi
    
    # Check Secure Token requirements
    local has_secure_token=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep -c "Enabled")
    if [[ $has_secure_token -eq 1 ]]; then
        local total_secure_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
        if [[ $total_secure_tokens -eq 1 ]]; then
            echo "✗ Cannot delete the only Secure Token holder: $username"
            log_action "Deletion blocked: $username is the only Secure Token holder" "ERROR"
            return 1
        fi
    fi
    
    # Check for active processes owned by user
    local user_processes=$(ps aux | awk -v user="$username" '$1 == user {print $2}' | wc -l | tr -d ' ')
    if [[ $user_processes -gt 0 ]]; then
        echo "⚠️ Warning: User has $user_processes active processes"
        echo "Terminating user processes..."
        pkill -u "$username" 2>/dev/null
        sleep 2
    fi
    
    # Check home directory size for backup planning
    local home_dir="/Users/$username"
    if [[ -d "$home_dir" ]]; then
        local dir_size=$(du -sm "$home_dir" 2>/dev/null | awk '{print $1}')
        echo "✓ Home directory size: ${dir_size}MB"
        
        # Check available disk space for backup
        local available_space=$(df -m "$BACKUP_DIR" | tail -1 | awk '{print $4}')
        if [[ $dir_size -gt $available_space ]]; then
            echo "⚠️ Warning: Insufficient space for backup"
            echo "Required: ${dir_size}MB, Available: ${available_space}MB"
        fi
    fi
    
    echo "✓ Pre-deletion validation completed"
    return 0
}

# Apply deletion policy
apply_deletion_policy() {
    local username="$1"
    local policy="$2"
    local compliance_framework="$3"
    local retention_period="$4"
    local authorized_by="$5"
    
    echo "--- Applying Deletion Policy: $policy ---"
    
    # Get policy actions
    local policy_actions="${LIFECYCLE_POLICIES[$policy]}"
    if [[ -z "$policy_actions" ]]; then
        log_action "ERROR: Unknown deletion policy: $policy" "ERROR"
        return 1
    fi
    
    echo "Policy actions: $policy_actions"
    
    # Execute policy actions
    IFS=',' read -ra ACTIONS <<< "$policy_actions"
    for action in "${ACTIONS[@]}"; do
        case "$action" in
            "backup_data")
                echo "Executing: Backup user data"
                backup_user_data_enterprise "$username" "$compliance_framework"
                ;;
            "delete_account")
                echo "Executing: Delete user account"
                delete_user_account_enterprise "$username"
                ;;
            "delete_data")
                echo "Executing: Delete user data"
                delete_user_data_secure "$username"
                ;;
            "preserve_home")
                echo "Executing: Preserve home directory"
                preserve_user_data "$username"
                ;;
            "disable_account")
                echo "Executing: Disable user account"
                disable_user_account "$username"
                ;;
            "audit_log")
                echo "Executing: Create audit log"
                create_audit_log "$username" "$policy" "$authorized_by"
                ;;
            "compliance_report")
                echo "Executing: Generate compliance report"
                # Will be handled separately
                ;;
            *)
                echo "Unknown action: $action"
                ;;
        esac
    done
}

# Enterprise backup with encryption and compliance
backup_user_data_enterprise() {
    local username="$1"
    local compliance_framework="$2"
    
    echo "--- Enterprise Data Backup ---"
    
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_name="${username}_enterprise_backup_${timestamp}"
    local backup_path="$BACKUP_DIR/$backup_name"
    
    # Create backup with metadata
    mkdir -p "$backup_path"
    
    # Copy user data
    local user_home="/Users/$username"
    if [[ -d "$user_home" ]]; then
        echo "Backing up user home directory..."
        tar -czf "$backup_path/home_directory.tar.gz" -C "/Users" "$username" 2>/dev/null
    fi
    
    # Backup user account information
    echo "Backing up account metadata..."
    dscl . read "/Users/$username" > "$backup_path/account_metadata.txt" 2>/dev/null
    
    # Create backup manifest
    cat > "$backup_path/backup_manifest.json" << EOF
{
    "backup_manifest": {
        "username": "$username",
        "backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "backup_type": "enterprise_offboarding",
        "compliance_framework": "$compliance_framework",
        "backup_location": "$backup_path",
        "files_included": [
            "home_directory.tar.gz",
            "account_metadata.txt",
            "backup_manifest.json"
        ],
        "backup_size": "$(du -sh "$backup_path" | awk '{print $1}')",
        "hostname": "$(hostname)",
        "authorized_by": "$(whoami)",
        "backup_integrity": "$(find "$backup_path" -type f -exec md5 {} \; | md5)"
    }
}
EOF
    
    # Apply compliance-specific protections
    if [[ -n "$compliance_framework" ]]; then
        apply_compliance_protections "$backup_path" "$compliance_framework"
    fi
    
    echo "✓ Enterprise backup completed: $backup_path"
    log_action "backup created for user $username at $backup_path" "INFO"
}

# Secure deletion with compliance requirements
delete_user_data_secure() {
    local username="$1"
    local user_home="/Users/$username"
    
    echo "--- Secure Data Deletion ---"
    
    if [[ -d "$user_home" ]]; then
        echo "Performing secure deletion of user data..."
        
        # Multiple-pass secure deletion (DoD 5220.22-M standard)
        if command -v gshred >/dev/null 2>&1; then
            echo "Using gshred for secure deletion..."
            find "$user_home" -type f -exec gshred -vfz -n 3 {} \; 2>/dev/null
        elif command -v shred >/dev/null 2>&1; then
            echo "Using shred for secure deletion..."
            find "$user_home" -type f -exec shred -vfz -n 3 {} \; 2>/dev/null
        else
            echo "Secure deletion tools not available, using standard deletion..."
        fi
        
        # Remove directory structure
        rm -rf "$user_home" 2>/dev/null
        
        echo "✓ Secure deletion completed"
        log_action "Secure deletion completed for user data: $user_home" "INFO"
    else
        echo "No user home directory found: $user_home"
    fi
}

# Disable user account instead of deletion
disable_user_account() {
    local username="$1"
    
    echo "--- Disabling User Account ---"
    
    # Disable account using dscl
    if dscl . create "/Users/$username" AuthenticationAuthority ";DisabledUser;" 2>/dev/null; then
        echo "✓ User account disabled: $username"
        log_action "User account disabled: $username" "INFO"
    else
        echo "✗ Failed to disable user account: $username"
        log_action "Failed to disable user account: $username" "ERROR"
    fi
    
    # Set account shell to /usr/bin/false
    dscl . create "/Users/$username" UserShell "/usr/bin/false" 2>/dev/null
    
    # Lock home directory
    local user_home="/Users/$username"
    if [[ -d "$user_home" ]]; then
        chmod 000 "$user_home" 2>/dev/null
        echo "✓ Home directory access revoked"
    fi
}

# Generate comprehensive compliance report
generate_deletion_compliance_report() {
    local username="$1"
    local policy="$2"
    local compliance_framework="$3"
    local authorized_by="$4"
    
    local report_file="$REPORT_DIR/user_deletion_report_${username}_$(date +%Y%m%d_%H%M%S).json"
    
    cat > "$report_file" << EOF
{
    "user_deletion_compliance_report": {
        "report_metadata": {
            "report_id": "$(uuidgen)",
            "generated_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
            "report_type": "user_account_deletion",
            "compliance_framework": "$compliance_framework",
            "hostname": "$(hostname)",
            "script_version": "$SCRIPT_VERSION"
        },
        "user_information": {
            "username": "$username",
            "deletion_policy": "$policy",
            "authorized_by": "$authorized_by",
            "deletion_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
        },
        "compliance_details": {
            "framework": "$compliance_framework",
            "data_retention_requirements": "$(echo "${RETENTION_PERIODS[medium_term]}" | sed 's/indefinite/Legal hold - indefinite retention/')",
            "secure_deletion_method": "DoD 5220.22-M standard",
            "backup_location": "$BACKUP_DIR",
            "audit_trail": "$LOG_FILE"
        },
        "system_information": {
            "os_version": "$(sw_vers -productVersion)",
            "hardware_model": "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk '{print $3}')",
            "secure_token_holders": $(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
        }
    }
}
EOF
    
    echo "Compliance report generated: $report_file"
    log_action "Compliance report generated: $report_file" "INFO"
}

# Fleet user management operations
manage_fleet_users() {
    local operation="$1"
    local user_list="$2"
    local policy="${3:-secure_archival}"
    local compliance_framework="${4:-}"
    
    echo "=== Fleet User Management ==="
    echo "Operation: $operation"
    echo "Policy: $policy"
    echo "Compliance Framework: $compliance_framework"
    echo ""
    
    case "$operation" in
        "bulk_delete")
            echo "Processing bulk user deletion..."
            IFS=',' read -ra USERS <<< "$user_list"
            for username in "${USERS[@]}"; do
                echo "Processing user: $username"
                enterprise_user_deletion "$username" "$policy" "$compliance_framework"
                echo ""
            done
            ;;
        "audit_all")
            echo "Auditing all user accounts..."
            audit_all_users
            ;;
        "compliance_check")
            echo "Running compliance check..."
            compliance_check_users "$compliance_framework"
            ;;
        *)
            echo "Unknown operation: $operation"
            return 1
            ;;
    esac
}

# Main execution function
main() {
    local action="${1:-help}"
    local param1="${2:-}"
    local param2="${3:-}"
    local param3="${4:-}"
    local param4="${5:-}"
    local param5="${6:-}"
    
    log_action "=== MacFleet User Lifecycle Management Started ===" "INFO"
    log_action "Action: $action" "INFO"
    
    case "$action" in
        "delete")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 delete <username> [policy] [compliance_framework] [retention_period] [authorized_by]"
                echo "Policies: ${!LIFECYCLE_POLICIES[*]}"
                echo "Compliance: ${!COMPLIANCE_FRAMEWORKS[*]}"
                echo "Retention: ${!RETENTION_PERIODS[*]}"
                exit 1
            fi
            enterprise_user_deletion "$param1" "$param2" "$param3" "$param4" "$param5"
            ;;
        "backup")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 backup <username> [compliance_framework]"
                exit 1
            fi
            backup_user_data_enterprise "$param1" "$param2"
            ;;
        "disable")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 disable <username>"
                exit 1
            fi
            disable_user_account "$param1"
            ;;
        "fleet")
            if [[ -z "$param1" || -z "$param2" ]]; then
                echo "Usage: $0 fleet <operation> <user_list> [policy] [compliance_framework]"
                echo "Operations: bulk_delete, audit_all, compliance_check"
                exit 1
            fi
            manage_fleet_users "$param1" "$param2" "$param3" "$param4"
            ;;
        "validate")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 validate <username>"
                exit 1
            fi
            pre_deletion_validation "$param1"
            ;;
        "prereq")
            check_deletion_prerequisites
            ;;
        "help")
            echo "Usage: $0 [action] [options...]"
            echo "Actions:"
            echo "  delete <username> [policy] [compliance] [retention] [authorized_by] - Delete user with enterprise policies"
            echo "  backup <username> [compliance] - Backup user data"
            echo "  disable <username> - Disable user account"
            echo "  fleet <operation> <user_list> [policy] [compliance] - Fleet user operations"
            echo "  validate <username> - Validate deletion prerequisites"
            echo "  prereq - Check system prerequisites"
            echo "  help - Show this help"
            echo ""
            echo "Policies: ${!LIFECYCLE_POLICIES[*]}"
            echo "Compliance: ${!COMPLIANCE_FRAMEWORKS[*]}"
            echo "Retention: ${!RETENTION_PERIODS[*]}"
            ;;
        *)
            log_action "ERROR: Unknown action: $action" "ERROR"
            echo "Use '$0 help' for usage information"
            exit 1
            ;;
    esac
    
    log_action "=== User lifecycle management completed ===" "INFO"
}

# Execute main function
main "$@"

Important Security Considerations

Secure Token Requirements

#!/bin/bash

# Manage Secure Token requirements for user deletion
manage_secure_tokens() {
    echo "=== Secure Token Management ==="
    
    # List all Secure Token holders
    echo "Current Secure Token holders:"
    sysadminctl -secureTokenStatus 2>/dev/null | grep -E "(Username|Enabled)"
    
    echo ""
    echo "--- Secure Token Guidelines ---"
    echo "1. Cannot delete the only Secure Token holder"
    echo "2. Must have at least one admin with Secure Token"
    echo "3. Grant Secure Token before attempting deletion"
    echo "4. Secure Token required for FileVault and certain operations"
}

# Grant Secure Token to admin user
grant_secure_token() {
    local admin_user="$1"
    local target_user="$2"
    
    if [[ -z "$admin_user" || -z "$target_user" ]]; then
        echo "Usage: grant_secure_token <admin_user> <target_user>"
        return 1
    fi
    
    echo "Granting Secure Token to $target_user via $admin_user..."
    sysadminctl -secureTokenOn "$target_user" -password -adminUser "$admin_user"
}

# Usage
manage_secure_tokens

Data Retention and Compliance

#!/bin/bash

# Implement data retention policies
implement_retention_policy() {
    local policy_name="$1"
    local retention_days="${2:-90}"
    
    echo "=== Data Retention Policy Implementation ==="
    echo "Policy: $policy_name"
    echo "Retention Period: $retention_days days"
    
    # Find old backups for cleanup
    local old_backups=$(find "$BACKUP_DIR" -type d -mtime +$retention_days 2>/dev/null)
    
    if [[ -n "$old_backups" ]]; then
        echo "Found backups older than $retention_days days:"
        echo "$old_backups"
        
        # Archive old backups before deletion (if required by policy)
        case "$policy_name" in
            "legal_hold")
                echo "Legal hold active - no deletion performed"
                ;;
            "compliance_minimum")
                echo "Compliance minimum retention - archiving to long-term storage"
                ;;
            *)
                echo "Standard retention - marking for deletion"
                ;;
        esac
    else
        echo "No backups found older than $retention_days days"
    fi
}

# Usage
implement_retention_policy "standard" "90"

Important Notes

  • Administrator Privileges - User deletion requires administrator privileges and proper authentication
  • Secure Token Management - Cannot delete the only Secure Token holder; ensure multiple admin users exist
  • Full Disk Access - Service app requires Full Disk Access permission in System Preferences
  • Data Backup - Always backup user data before deletion if required by organizational policies
  • Compliance Requirements - Different industries have specific data retention and deletion requirements
  • Audit Trails - Maintain comprehensive logs of all user deletion activities for compliance
  • Recovery Procedures - Test backup and recovery procedures before implementing deletion policies

Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Configurando un Runner de GitHub Actions en un Mac Mini (Apple Silicon)

Runner de GitHub Actions

GitHub Actions es una plataforma poderosa de CI/CD que te permite automatizar tus flujos de trabajo de desarrollo de software. Aunque GitHub ofrece runners hospedados, los runners auto-hospedados proporcionan mayor control y personalización para tu configuración de CI/CD. Este tutorial te guía a través de la configuración y conexión de un runner auto-hospedado en un Mac mini para ejecutar pipelines de macOS.

Prerrequisitos

Antes de comenzar, asegúrate de tener:

  • Un Mac mini (regístrate en Macfleet)
  • Un repositorio de GitHub con derechos de administrador
  • Un gestor de paquetes instalado (preferiblemente Homebrew)
  • Git instalado en tu sistema

Paso 1: Crear una Cuenta de Usuario Dedicada

Primero, crea una cuenta de usuario dedicada para el runner de GitHub Actions:

# Crear la cuenta de usuario 'gh-runner'
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Establecer la contraseña para el usuario
sudo dscl . -passwd /Users/gh-runner tu_contraseña

# Agregar 'gh-runner' al grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Cambia a la nueva cuenta de usuario:

su gh-runner

Paso 2: Instalar Software Requerido

Instala Git y Rosetta 2 (si usas Apple Silicon):

# Instalar Git si no está ya instalado
brew install git

# Instalar Rosetta 2 para Macs Apple Silicon
softwareupdate --install-rosetta

Paso 3: Configurar el Runner de GitHub Actions

  1. Ve a tu repositorio de GitHub
  2. Navega a Configuración > Actions > Runners

Runner de GitHub Actions

  1. Haz clic en "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecciona macOS como imagen del runner y ARM64 como arquitectura
  3. Sigue los comandos proporcionados para descargar y configurar el runner

Runner de GitHub Actions

Crea un archivo .env en el directorio _work del runner:

# archivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Ejecuta el script run.sh en tu directorio del runner para completar la configuración.
  2. Verifica que el runner esté activo y escuchando trabajos en la terminal y revisa la configuración del repositorio de GitHub para la asociación del runner y el estado Idle.

Runner de GitHub Actions

Paso 4: Configurar Sudoers (Opcional)

Si tus acciones requieren privilegios de root, configura el archivo sudoers:

sudo visudo

Agrega la siguiente línea:

gh-runner ALL=(ALL) NOPASSWD: ALL

Paso 5: Usar el Runner en Flujos de Trabajo

Configura tu flujo de trabajo de GitHub Actions para usar el runner auto-hospedado:

name: Flujo de trabajo de muestra

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: Instalar NodeJS
        run: brew install node

El runner está autenticado en tu repositorio y etiquetado con self-hosted, macOS, y ARM64. Úsalo en tus flujos de trabajo especificando estas etiquetas en el campo runs-on:

runs-on: [self-hosted, macOS, ARM64]

Mejores Prácticas

  • Mantén tu software del runner actualizado
  • Monitorea regularmente los logs del runner para problemas
  • Usa etiquetas específicas para diferentes tipos de runners
  • Implementa medidas de seguridad apropiadas
  • Considera usar múltiples runners para balanceo de carga

Solución de Problemas

Problemas comunes y soluciones:

  1. Runner no conectando:

    • Verifica conectividad de red
    • Verifica validez del token de GitHub
    • Asegúrate de permisos apropiados
  2. Fallas de construcción:

    • Verifica instalación de Xcode
    • Verifica dependencias requeridas
    • Revisa logs del flujo de trabajo
  3. Problemas de permisos:

    • Verifica permisos de usuario
    • Verifica configuración de sudoers
    • Revisa permisos del sistema de archivos

Conclusión

Ahora tienes un runner auto-hospedado de GitHub Actions configurado en tu Mac mini. Esta configuración te proporciona más control sobre tu entorno de CI/CD y te permite ejecutar flujos de trabajo específicos de macOS de manera eficiente.

Recuerda mantener regularmente tu runner y mantenerlo actualizado con los últimos parches de seguridad y versiones de software.

Aplicación Nativa

Aplicación nativa de Macfleet

Guía de Instalación de Macfleet

Macfleet es una solución poderosa de gestión de flota diseñada específicamente para entornos de Mac Mini alojados en la nube. Como proveedor de hosting en la nube de Mac Mini, puedes usar Macfleet para monitorear, gestionar y optimizar toda tu flota de instancias Mac virtualizadas.

Esta guía de instalación te llevará a través de la configuración del monitoreo de Macfleet en sistemas macOS, Windows y Linux para asegurar una supervisión integral de tu infraestructura en la nube.

🍎 macOS

  • Descarga el archivo .dmg para Mac aquí
  • Haz doble clic en el archivo .dmg descargado
  • Arrastra la aplicación Macfleet a la carpeta Aplicaciones
  • Expulsa el archivo .dmg
  • Abre Preferencias del Sistema > Seguridad y Privacidad
    • Pestaña Privacidad > Accesibilidad
    • Marca Macfleet para permitir el monitoreo
  • Inicia Macfleet desde Aplicaciones
  • El seguimiento comienza automáticamente

🪟 Windows

  • Descarga el archivo .exe para Windows aquí
  • Haz clic derecho en el archivo .exe > "Ejecutar como administrador"
  • Sigue el asistente de instalación
  • Acepta los términos y condiciones
  • Permite en Windows Defender si se solicita
  • Concede permisos de monitoreo de aplicaciones
  • Inicia Macfleet desde el Menú Inicio
  • La aplicación comienza el seguimiento automáticamente

🐧 Linux

  • Descarga el paquete .deb (Ubuntu/Debian) o .rpm (CentOS/RHEL) aquí
  • Instala usando tu gestor de paquetes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permite permisos de acceso X11 si se solicita
  • Agrega el usuario a los grupos apropiados si es necesario
  • Inicia Macfleet desde el menú de Aplicaciones
  • La aplicación comienza el seguimiento automáticamente

Nota: Después de la instalación en todos los sistemas, inicia sesión con tus credenciales de Macfleet para sincronizar datos con tu panel de control.