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.

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

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.