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.

Admin Rights Management on macOS

Manage and control administrator privileges across your MacFleet devices using advanced command-line tools and centralized privilege management policies. This tutorial covers temporary admin rights, privilege escalation control, security governance, and enterprise-grade admin rights management with comprehensive auditing and compliance capabilities.

Understanding macOS Admin Rights Management

macOS provides several tools and methods for managing administrator privileges:

  • dscl - Directory Services Command Line utility for user and group management
  • sudo - Execute commands with elevated privileges
  • launchctl - Launch daemon management for scheduled tasks
  • Groups framework - Built-in admin group membership management
  • Security Framework - Authorization and privilege validation

Enterprise admin rights management requires careful balance between security, productivity, and compliance requirements.

Basic Admin Rights Commands

Grant Admin Rights (Basic)

#!/bin/bash

# Basic admin rights grant
grant_admin_rights_basic() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        echo "Usage: grant_admin_rights_basic <username>"
        return 1
    fi
    
    # Verify user exists
    if ! dscl . -read /Users/"$username" >/dev/null 2>&1; then
        echo "❌ User '$username' not found"
        return 1
    fi
    
    # Add user to admin group
    dscl . -append /Groups/admin GroupMembership "$username"
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Admin rights granted to user: $username"
        return 0
    else
        echo "❌ Failed to grant admin rights to user: $username"
        return 1
    fi
}

# Example usage
# grant_admin_rights_basic "john.doe"

Revoke Admin Rights (Basic)

#!/bin/bash

# Basic admin rights revocation
revoke_admin_rights_basic() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        echo "Usage: revoke_admin_rights_basic <username>"
        return 1
    fi
    
    # Verify user exists
    if ! dscl . -read /Users/"$username" >/dev/null 2>&1; then
        echo "❌ User '$username' not found"
        return 1
    fi
    
    # Remove user from admin group
    dscl . -delete /Groups/admin GroupMembership "$username"
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Admin rights revoked from user: $username"
        return 0
    else
        echo "❌ Failed to revoke admin rights from user: $username"
        return 1
    fi
}

# Example usage
# revoke_admin_rights_basic "john.doe"

Check Admin Status

#!/bin/bash

# Check if user has admin privileges
check_admin_status() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        echo "Usage: check_admin_status <username>"
        return 1
    fi
    
    # Check if user is in admin group
    local admin_members
    admin_members=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | grep -o "$username")
    
    if [[ -n "$admin_members" ]]; then
        echo "✅ User '$username' has admin privileges"
        return 0
    else
        echo "❌ User '$username' does not have admin privileges"
        return 1
    fi
}

# List all admin users
list_admin_users() {
    echo "=== Current Admin Users ==="
    echo ""
    
    local admin_users
    admin_users=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | cut -d: -f2 | tr ' ' '\n' | grep -v '^$' | sort)
    
    if [[ -n "$admin_users" ]]; then
        echo "Administrator accounts:"
        while IFS= read -r user; do
            # Get user real name if available
            local real_name
            real_name=$(dscl . -read /Users/"$user" RealName 2>/dev/null | cut -d: -f2 | sed 's/^ *//')
            
            if [[ -n "$real_name" && "$real_name" != "$user" ]]; then
                echo "  • $user ($real_name)"
            else
                echo "  • $user"
            fi
        done <<< "$admin_users"
    else
        echo "No admin users found"
    fi
    echo ""
}

# Example usage
# check_admin_status "john.doe"
# list_admin_users

Advanced Admin Rights Management

Temporary Admin Rights

#!/bin/bash

# Enhanced temporary admin rights
grant_temporary_admin_rights() {
    local username="$1"
    local duration_minutes="${2:-30}"
    local reason="${3:-Administrative task}"
    local require_confirmation="${4:-true}"
    
    if [[ -z "$username" ]]; then
        echo "Usage: grant_temporary_admin_rights <username> [duration_minutes] [reason] [require_confirmation]"
        return 1
    fi
    
    # Verify user exists
    if ! dscl . -read /Users/"$username" >/dev/null 2>&1; then
        echo "❌ User '$username' not found"
        return 1
    fi
    
    # Check if user already has admin rights
    if check_admin_status "$username" >/dev/null; then
        echo "⚠️  User '$username' already has admin privileges"
        read -p "Continue with temporary admin setup? (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            return 1
        fi
    fi
    
    # Display confirmation dialog if required
    if [[ "$require_confirmation" == "true" ]]; then
        osascript -e "display dialog \"You have been granted administrator rights for $duration_minutes minutes.\\n\\nReason: $reason\\n\\nPlease do not misuse this privilege.\" buttons {\"Accept Admin Rights\"} default button 1 with title \"MacFleet Admin Rights Grant\""
        
        if [[ $? -ne 0 ]]; then
            echo "❌ User declined admin rights grant"
            return 1
        fi
    fi
    
    # Create tracking directory
    local tracking_dir="/private/var/macfleet_admin_tracking"
    sudo mkdir -p "$tracking_dir"
    
    # Create user tracking file with metadata
    local tracking_file="$tracking_dir/${username}_admin.json"
    cat > "$tracking_file" <<EOF
{
    "username": "$username",
    "granted_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "duration_minutes": $duration_minutes,
    "reason": "$reason",
    "granted_by": "$(whoami)",
    "hostname": "$(hostname)",
    "pid": $$,
    "expires_at": "$(date -u -v+${duration_minutes}M +%Y-%m-%dT%H:%M:%SZ)"
}
EOF
    
    # Grant admin rights
    dscl . -append /Groups/admin GroupMembership "$username"
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Temporary admin rights granted to '$username' for $duration_minutes minutes"
        
        # Create removal script
        create_admin_removal_script "$username" "$duration_minutes"
        
        # Schedule removal
        schedule_admin_removal "$username" "$duration_minutes"
        
        return 0
    else
        echo "❌ Failed to grant admin rights to '$username'"
        rm -f "$tracking_file"
        return 1
    fi
}

# Create admin removal script
create_admin_removal_script() {
    local username="$1"
    local duration_minutes="$2"
    
    local script_path="/Library/Application Support/MacFleet/remove_admin_${username}.sh"
    mkdir -p "$(dirname "$script_path")"
    
    cat > "$script_path" <<'EOF'
#!/bin/bash

USERNAME="{{USERNAME}}"
TRACKING_DIR="/private/var/macfleet_admin_tracking"
TRACKING_FILE="$TRACKING_DIR/${USERNAME}_admin.json"
LOG_FILE="/var/log/macfleet_admin_rights.log"

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

log_action "Starting admin rights removal for user: $USERNAME"

# Check if user still has admin rights
if dscl . -read /Groups/admin GroupMembership 2>/dev/null | grep -q "$USERNAME"; then
    # Remove admin rights
    dscl . -delete /Groups/admin GroupMembership "$USERNAME"
    
    if [[ $? -eq 0 ]]; then
        log_action "✅ Admin rights successfully removed from user: $USERNAME"
        
        # Notify user if they're logged in
        if pgrep -u "$USERNAME" >/dev/null; then
            sudo -u "$USERNAME" osascript -e 'display notification "Your temporary administrator privileges have expired." with title "MacFleet Admin Rights"' 2>/dev/null
        fi
    else
        log_action "❌ Failed to remove admin rights from user: $USERNAME"
    fi
else
    log_action "⚠️  User $USERNAME did not have admin rights (already removed or never granted)"
fi

# Clean up tracking file
if [[ -f "$TRACKING_FILE" ]]; then
    # Archive the tracking data
    ARCHIVE_DIR="/var/log/macfleet_admin_archive"
    mkdir -p "$ARCHIVE_DIR"
    mv "$TRACKING_FILE" "$ARCHIVE_DIR/${USERNAME}_admin_$(date +%Y%m%d_%H%M%S).json"
    log_action "Admin rights tracking data archived for user: $USERNAME"
fi

# Remove launch daemon
PLIST_PATH="/Library/LaunchDaemons/com.macfleet.remove_admin_${USERNAME}.plist"
if [[ -f "$PLIST_PATH" ]]; then
    launchctl unload "$PLIST_PATH" 2>/dev/null
    rm -f "$PLIST_PATH"
    log_action "Launch daemon removed for user: $USERNAME"
fi

# Remove this script
rm -f "$0"

log_action "Admin rights removal process completed for user: $USERNAME"
exit 0
EOF
    
    # Replace placeholder with actual username
    sed -i '' "s/{{USERNAME}}/$username/g" "$script_path"
    
    # Set permissions
    chmod 755 "$script_path"
    chown root:wheel "$script_path"
}

# Schedule admin removal using launchd
schedule_admin_removal() {
    local username="$1"
    local duration_minutes="$2"
    
    local plist_path="/Library/LaunchDaemons/com.macfleet.remove_admin_${username}.plist"
    local script_path="/Library/Application Support/MacFleet/remove_admin_${username}.sh"
    
    # Calculate execution time
    local start_time
    start_time=$(date -u -v+${duration_minutes}M +%Y-%m-%dT%H:%M:%SZ)
    
    # Create launch daemon plist
    cat > "$plist_path" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.macfleet.remove_admin_${username}</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>${script_path}</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Year</key>
        <integer>$(date -u -v+${duration_minutes}M +%Y)</integer>
        <key>Month</key>
        <integer>$(date -u -v+${duration_minutes}M +%m)</integer>
        <key>Day</key>
        <integer>$(date -u -v+${duration_minutes}M +%d)</integer>
        <key>Hour</key>
        <integer>$(date -u -v+${duration_minutes}M +%H)</integer>
        <key>Minute</key>
        <integer>$(date -u -v+${duration_minutes}M +%M)</integer>
    </dict>
    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>
EOF
    
    # Set permissions
    chown root:wheel "$plist_path"
    chmod 644 "$plist_path"
    
    # Load the daemon
    launchctl load "$plist_path"
    
    echo "⏰ Admin rights removal scheduled for $start_time"
}

# Example usage
# grant_temporary_admin_rights "john.doe" 30 "Software installation" true

Enterprise Admin Rights Management System

#!/bin/bash

# MacFleet Enterprise Admin Rights Management System
# Comprehensive privilege management, security governance, and compliance monitoring

# Configuration
LOG_FILE="/var/log/macfleet_admin_rights.log"
CONFIG_FILE="/etc/macfleet/admin_rights_config.conf"
AUDIT_DIR="/var/log/macfleet_admin_audit"
POLICY_DIR="/etc/macfleet/admin_policies"
TRACKING_DIR="/private/var/macfleet_admin_tracking"

# Create directory structure
setup_directories() {
    mkdir -p "$(dirname "$LOG_FILE")" "$AUDIT_DIR" "$POLICY_DIR" "$TRACKING_DIR" "$(dirname "$CONFIG_FILE")"
    touch "$LOG_FILE"
    
    # Set appropriate permissions
    chmod 755 "$AUDIT_DIR" "$POLICY_DIR"
    chmod 700 "$TRACKING_DIR"  # Restrict access to tracking data
}

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

# Load configuration
load_config() {
    if [[ -f "$CONFIG_FILE" ]]; then
        source "$CONFIG_FILE"
    else
        # Set defaults
        MAX_ADMIN_DURATION="${MAX_ADMIN_DURATION:-480}"  # 8 hours max
        DEFAULT_ADMIN_DURATION="${DEFAULT_ADMIN_DURATION:-30}"  # 30 minutes default
        REQUIRE_JUSTIFICATION="${REQUIRE_JUSTIFICATION:-true}"
        ENABLE_NOTIFICATIONS="${ENABLE_NOTIFICATIONS:-true}"
        AUDIT_ALL_CHANGES="${AUDIT_ALL_CHANGES:-true}"
        PROTECTED_ACCOUNTS="${PROTECTED_ACCOUNTS:-root,admin,macfleet}"
    fi
}

# Enterprise admin rights grant with policy enforcement
enterprise_grant_admin() {
    local username="$1"
    local duration_minutes="$2"
    local reason="$3"
    local approved_by="$4"
    
    load_config
    
    if [[ -z "$username" ]]; then
        log_action "ERROR: Username required for admin rights grant"
        return 1
    fi
    
    # Set default duration if not provided
    if [[ -z "$duration_minutes" ]]; then
        duration_minutes="$DEFAULT_ADMIN_DURATION"
    fi
    
    # Validate duration against policy
    if [[ "$duration_minutes" -gt "$MAX_ADMIN_DURATION" ]]; then
        log_action "ERROR: Requested duration ($duration_minutes min) exceeds maximum allowed ($MAX_ADMIN_DURATION min)"
        return 1
    fi
    
    # Require justification if policy enabled
    if [[ "$REQUIRE_JUSTIFICATION" == "true" && -z "$reason" ]]; then
        log_action "ERROR: Justification required for admin rights grant"
        return 1
    fi
    
    # Check if user exists
    if ! dscl . -read /Users/"$username" >/dev/null 2>&1; then
        log_action "ERROR: User '$username' not found"
        return 1
    fi
    
    # Check for protected accounts
    if echo "$PROTECTED_ACCOUNTS" | grep -q "$username"; then
        log_action "ERROR: Cannot modify admin rights for protected account: $username"
        return 1
    fi
    
    # Check for existing admin rights
    local current_admin_status
    if check_admin_status "$username" >/dev/null; then
        current_admin_status="already_admin"
    else
        current_admin_status="standard_user"
    fi
    
    # Create audit entry
    local audit_id
    audit_id=$(create_audit_entry "grant" "$username" "$duration_minutes" "$reason" "$approved_by" "$current_admin_status")
    
    # Grant admin rights
    if [[ "$current_admin_status" == "standard_user" ]]; then
        dscl . -append /Groups/admin GroupMembership "$username"
        
        if [[ $? -ne 0 ]]; then
            log_action "ERROR: Failed to grant admin rights to '$username'"
            update_audit_entry "$audit_id" "failed" "Failed to modify admin group"
            return 1
        fi
    fi
    
    # Create tracking entry
    create_tracking_entry "$username" "$duration_minutes" "$reason" "$approved_by" "$audit_id"
    
    # Schedule removal if temporary
    if [[ "$duration_minutes" -gt 0 ]]; then
        schedule_enterprise_admin_removal "$username" "$duration_minutes" "$audit_id"
    fi
    
    # Send notifications
    if [[ "$ENABLE_NOTIFICATIONS" == "true" ]]; then
        send_admin_notification "$username" "granted" "$duration_minutes" "$reason"
    fi
    
    log_action "✅ Admin rights granted to '$username' for $duration_minutes minutes (Audit ID: $audit_id)"
    update_audit_entry "$audit_id" "success" "Admin rights granted successfully"
    
    return 0
}

# Enterprise admin rights revocation
enterprise_revoke_admin() {
    local username="$1"
    local reason="$2"
    local revoked_by="$3"
    
    load_config
    
    if [[ -z "$username" ]]; then
        log_action "ERROR: Username required for admin rights revocation"
        return 1
    fi
    
    # Check if user exists
    if ! dscl . -read /Users/"$username" >/dev/null 2>&1; then
        log_action "ERROR: User '$username' not found"
        return 1
    fi
    
    # Check for protected accounts
    if echo "$PROTECTED_ACCOUNTS" | grep -q "$username"; then
        log_action "ERROR: Cannot modify admin rights for protected account: $username"
        return 1
    fi
    
    # Check current admin status
    if ! check_admin_status "$username" >/dev/null; then
        log_action "WARNING: User '$username' does not have admin privileges"
        return 0
    fi
    
    # Create audit entry
    local audit_id
    audit_id=$(create_audit_entry "revoke" "$username" "0" "$reason" "$revoked_by" "admin_user")
    
    # Remove admin rights
    dscl . -delete /Groups/admin GroupMembership "$username"
    
    if [[ $? -eq 0 ]]; then
        log_action "✅ Admin rights revoked from '$username' (Audit ID: $audit_id)"
        
        # Clean up tracking
        cleanup_user_tracking "$username"
        
        # Cancel scheduled removal if exists
        cancel_scheduled_removal "$username"
        
        # Send notifications
        if [[ "$ENABLE_NOTIFICATIONS" == "true" ]]; then
            send_admin_notification "$username" "revoked" "0" "$reason"
        fi
        
        update_audit_entry "$audit_id" "success" "Admin rights revoked successfully"
        return 0
    else
        log_action "ERROR: Failed to revoke admin rights from '$username'"
        update_audit_entry "$audit_id" "failed" "Failed to modify admin group"
        return 1
    fi
}

# Create audit entry
create_audit_entry() {
    local action="$1"
    local username="$2"
    local duration="$3"
    local reason="$4"
    local operator="$5"
    local previous_status="$6"
    
    local audit_id="$(date +%s)_${username}_${action}"
    local audit_file="$AUDIT_DIR/${audit_id}.json"
    
    cat > "$audit_file" <<EOF
{
    "audit_id": "$audit_id",
    "action": "$action",
    "username": "$username",
    "duration_minutes": $duration,
    "reason": "$reason",
    "operator": "$operator",
    "previous_status": "$previous_status",
    "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "hostname": "$(hostname)",
    "system_info": {
        "macos_version": "$(sw_vers -productVersion)",
        "build_version": "$(sw_vers -buildVersion)"
    },
    "status": "pending",
    "completion_time": null,
    "result_message": null
}
EOF
    
    echo "$audit_id"
}

# Update audit entry
update_audit_entry() {
    local audit_id="$1"
    local status="$2"
    local message="$3"
    
    local audit_file="$AUDIT_DIR/${audit_id}.json"
    
    if [[ -f "$audit_file" ]]; then
        # Update status and completion time
        local temp_file=$(mktemp)
        jq --arg status "$status" --arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg msg "$message" \
           '.status = $status | .completion_time = $time | .result_message = $msg' \
           "$audit_file" > "$temp_file" && mv "$temp_file" "$audit_file"
    fi
}

# Create tracking entry
create_tracking_entry() {
    local username="$1"
    local duration="$2"
    local reason="$3"
    local operator="$4"
    local audit_id="$5"
    
    local tracking_file="$TRACKING_DIR/${username}_admin.json"
    
    cat > "$tracking_file" <<EOF
{
    "username": "$username",
    "granted_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "duration_minutes": $duration,
    "expires_at": "$(date -u -v+${duration}M +%Y-%m-%dT%H:%M:%SZ)",
    "reason": "$reason",
    "granted_by": "$operator",
    "audit_id": "$audit_id",
    "hostname": "$(hostname)",
    "pid": $$,
    "status": "active"
}
EOF
}

# Schedule enterprise admin removal
schedule_enterprise_admin_removal() {
    local username="$1"
    local duration_minutes="$2"
    local audit_id="$3"
    
    local script_path="/Library/Application Support/MacFleet/enterprise_remove_admin_${username}.sh"
    local plist_path="/Library/LaunchDaemons/com.macfleet.enterprise_remove_admin_${username}.plist"
    
    # Create enhanced removal script
    mkdir -p "$(dirname "$script_path")"
    
    cat > "$script_path" <<EOF
#!/bin/bash

# MacFleet Enterprise Admin Rights Removal
USERNAME="$username"
AUDIT_ID="$audit_id"
LOG_FILE="$LOG_FILE"
TRACKING_DIR="$TRACKING_DIR"
AUDIT_DIR="$AUDIT_DIR"

# Source the main script functions
source /usr/local/bin/macfleet_admin_management.sh

log_action "Starting scheduled admin rights removal for user: \$USERNAME (Audit ID: \$AUDIT_ID)"

# Remove admin rights
enterprise_revoke_admin "\$USERNAME" "Automatic expiration" "system"

# Clean up launch daemon
launchctl unload "$plist_path" 2>/dev/null
rm -f "$plist_path"
rm -f "\$0"

log_action "Scheduled admin rights removal completed for user: \$USERNAME"
exit 0
EOF
    
    chmod 755 "$script_path"
    chown root:wheel "$script_path"
    
    # Create launch daemon
    create_removal_launch_daemon "$username" "$duration_minutes" "$script_path" "$plist_path"
}

# Send admin notifications
send_admin_notification() {
    local username="$1"
    local action="$2"
    local duration="$3"
    local reason="$4"
    
    local message
    case "$action" in
        "granted")
            if [[ "$duration" -gt 0 ]]; then
                message="Administrator privileges granted for $duration minutes. Reason: $reason"
            else
                message="Administrator privileges granted permanently. Reason: $reason"
            fi
            ;;
        "revoked")
            message="Administrator privileges have been revoked. Reason: $reason"
            ;;
        "expired")
            message="Temporary administrator privileges have expired."
            ;;
    esac
    
    # Send notification to user if logged in
    if pgrep -u "$username" >/dev/null; then
        sudo -u "$username" osascript -e "display notification \"$message\" with title \"MacFleet Admin Rights\"" 2>/dev/null
    fi
    
    # Log notification
    log_action "Notification sent to '$username': $message"
}

# Admin rights security audit
perform_admin_audit() {
    local audit_file="$AUDIT_DIR/security_audit_$(date +%Y%m%d_%H%M%S).json"
    
    log_action "Performing admin rights security audit: $audit_file"
    
    {
        echo "{"
        echo "  \"audit_type\": \"admin_rights_security\","
        echo "  \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
        echo "  \"hostname\": \"$(hostname)\","
        echo "  \"auditor\": \"$(whoami)\","
        
        # Current admin users analysis
        echo "  \"current_admin_users\": ["
        local admin_users
        admin_users=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | cut -d: -f2 | tr ' ' '\n' | grep -v '^$' | sort)
        
        local first_user=true
        while IFS= read -r user; do
            if [[ -n "$user" ]]; then
                if [[ "$first_user" == "false" ]]; then
                    echo ","
                fi
                first_user=false
                
                local real_name uid last_login
                real_name=$(dscl . -read /Users/"$user" RealName 2>/dev/null | cut -d: -f2 | sed 's/^ *//')
                uid=$(dscl . -read /Users/"$user" UniqueID 2>/dev/null | awk '{print $2}')
                last_login=$(last -1 "$user" 2>/dev/null | head -1 | awk '{print $4, $5, $6, $7}')
                
                echo "    {"
                echo "      \"username\": \"$user\","
                echo "      \"real_name\": \"${real_name:-Unknown}\","
                echo "      \"uid\": \"${uid:-Unknown}\","
                echo "      \"last_login\": \"${last_login:-Never}\","
                
                # Check if user has active tracking
                local tracking_file="$TRACKING_DIR/${user}_admin.json"
                if [[ -f "$tracking_file" ]]; then
                    local expires_at reason
                    expires_at=$(jq -r '.expires_at' "$tracking_file" 2>/dev/null)
                    reason=$(jq -r '.reason' "$tracking_file" 2>/dev/null)
                    
                    echo "      \"temporary_admin\": true,"
                    echo "      \"expires_at\": \"$expires_at\","
                    echo "      \"reason\": \"$reason\""
                else
                    echo "      \"temporary_admin\": false,"
                    echo "      \"expires_at\": null,"
                    echo "      \"reason\": null"
                fi
                echo -n "    }"
            fi
        done <<< "$admin_users"
        echo ""
        echo "  ],"
        
        # Active tracking entries
        echo "  \"active_temporary_admin\": ["
        local first_tracking=true
        for tracking_file in "$TRACKING_DIR"/*_admin.json; do
            if [[ -f "$tracking_file" ]]; then
                if [[ "$first_tracking" == "false" ]]; then
                    echo ","
                fi
                first_tracking=false
                cat "$tracking_file"
            fi
        done
        echo ""
        echo "  ],"
        
        # Recent audit entries (last 24 hours)
        echo "  \"recent_admin_changes\": ["
        local cutoff_time
        cutoff_time=$(date -u -v-1d +%s)
        local first_audit=true
        
        for audit_file in "$AUDIT_DIR"/*.json; do
            if [[ -f "$audit_file" ]]; then
                local audit_timestamp
                audit_timestamp=$(jq -r '.timestamp' "$audit_file" 2>/dev/null)
                local audit_epoch
                audit_epoch=$(date -jf "%Y-%m-%dT%H:%M:%SZ" "$audit_timestamp" +%s 2>/dev/null)
                
                if [[ "$audit_epoch" -gt "$cutoff_time" ]]; then
                    if [[ "$first_audit" == "false" ]]; then
                        echo ","
                    fi
                    first_audit=false
                    cat "$audit_file"
                fi
            fi
        done
        echo ""
        echo "  ]"
        echo "}"
    } > "$audit_file"
    
    log_action "Admin rights security audit completed: $audit_file"
    echo "$audit_file"
}

# Main management function
main() {
    local action="${1:-status}"
    local parameter1="$2"
    local parameter2="$3"
    local parameter3="$4"
    local parameter4="$5"
    
    setup_directories
    log_action "MacFleet Admin Rights Management started with action: $action"
    
    case "$action" in
        "grant")
            enterprise_grant_admin "$parameter1" "$parameter2" "$parameter3" "$parameter4"
            ;;
        "revoke")
            enterprise_revoke_admin "$parameter1" "$parameter2" "$parameter3"
            ;;
        "temp"|"temporary")
            grant_temporary_admin_rights "$parameter1" "$parameter2" "$parameter3" "$parameter4"
            ;;
        "check")
            check_admin_status "$parameter1"
            ;;
        "list")
            list_admin_users
            ;;
        "audit")
            perform_admin_audit
            ;;
        "status"|*)
            list_admin_users
            ;;
    esac
    
    log_action "MacFleet Admin Rights Management completed with action: $action"
}

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

Admin Rights Policy Templates

Corporate Admin Rights Policy

# /etc/macfleet/admin_rights_config.conf
# MacFleet Corporate Admin Rights Configuration

# Duration limits (in minutes)
MAX_ADMIN_DURATION="480"        # 8 hours maximum
DEFAULT_ADMIN_DURATION="30"     # 30 minutes default
WARNING_BEFORE_EXPIRY="5"       # 5 minutes warning

# Security requirements
REQUIRE_JUSTIFICATION="true"
REQUIRE_APPROVAL="true"
MINIMUM_JUSTIFICATION_LENGTH="10"

# Notification settings
ENABLE_NOTIFICATIONS="true"
NOTIFY_SECURITY_TEAM="true"
SECURITY_TEAM_EMAIL="security@company.com"

# Audit settings
AUDIT_ALL_CHANGES="true"
RETAIN_AUDIT_LOGS="90"          # 90 days
ENABLE_REALTIME_MONITORING="true"

# Protected accounts (cannot be modified)
PROTECTED_ACCOUNTS="root,admin,macfleet,security"

# Approval workflow
REQUIRE_MANAGER_APPROVAL="true"
ENABLE_EMERGENCY_BYPASS="false"
EMERGENCY_BYPASS_ACCOUNTS="security,ciso"

High Security Environment Policy

# /etc/macfleet/admin_policies/high_security.policy
# MacFleet High Security Admin Rights Policy

# Strict duration limits
MAX_ADMIN_DURATION="60"         # 1 hour maximum
DEFAULT_ADMIN_DURATION="15"     # 15 minutes default
AUTO_REVOKE_IDLE="true"         # Revoke if user idle
IDLE_TIMEOUT_MINUTES="10"       # 10 minutes idle timeout

# Enhanced security
REQUIRE_JUSTIFICATION="true"
REQUIRE_TWO_PERSON_APPROVAL="true"
ENABLE_SESSION_RECORDING="true"
BLOCK_ADMIN_OUTSIDE_HOURS="true"
ALLOWED_HOURS="09-17"           # 9 AM to 5 PM
ALLOWED_DAYS="1-5"              # Monday to Friday

# Monitoring
ENABLE_REALTIME_ALERTS="true"
ALERT_ON_ADMIN_GRANT="true"
ALERT_ON_SUSPICIOUS_ACTIVITY="true"
LOG_ALL_ADMIN_COMMANDS="true"

Security and Compliance Functions

Admin Rights Compliance Check

#!/bin/bash

# Comprehensive admin rights compliance check
check_admin_compliance() {
    echo "🔍 Admin Rights Compliance Check"
    echo "==============================="
    echo ""
    
    local compliance_issues=()
    local compliance_warnings=()
    
    # Check for unauthorized permanent admin accounts
    echo "1. UNAUTHORIZED PERMANENT ADMIN ACCOUNTS:"
    echo "----------------------------------------"
    
    local admin_users
    admin_users=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | cut -d: -f2 | tr ' ' '\n' | grep -v '^$')
    
    while IFS= read -r user; do
        if [[ -n "$user" ]]; then
            local tracking_file="$TRACKING_DIR/${user}_admin.json"
            
            # Skip protected accounts
            if echo "$PROTECTED_ACCOUNTS" | grep -q "$user"; then
                echo "  ✅ $user (Protected account)"
                continue
            fi
            
            # Check if user has temporary admin tracking
            if [[ ! -f "$tracking_file" ]]; then
                # No tracking = permanent admin (potential violation)
                compliance_issues+=("Permanent admin account without tracking: $user")
                echo "  ❌ $user (No temporary admin tracking found)"
            else
                # Check if temporary admin has expired
                local expires_at
                expires_at=$(jq -r '.expires_at' "$tracking_file" 2>/dev/null)
                local current_time
                current_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)
                
                if [[ "$expires_at" < "$current_time" ]]; then
                    compliance_issues+=("Expired temporary admin still active: $user")
                    echo "  ⚠️  $user (Temporary admin expired but still active)"
                else
                    local reason
                    reason=$(jq -r '.reason' "$tracking_file" 2>/dev/null)
                    echo "  ✅ $user (Temporary admin, expires: $expires_at, reason: $reason)"
                fi
            fi
        fi
    done <<< "$admin_users"
    echo ""
    
    # Check for stale tracking files
    echo "2. STALE TRACKING FILES:"
    echo "-----------------------"
    
    for tracking_file in "$TRACKING_DIR"/*_admin.json; do
        if [[ -f "$tracking_file" ]]; then
            local username
            username=$(basename "$tracking_file" _admin.json)
            
            # Check if user still has admin rights
            if ! check_admin_status "$username" >/dev/null 2>&1; then
                compliance_warnings+=("Stale tracking file for non-admin user: $username")
                echo "  ⚠️  Stale tracking file: $tracking_file"
            fi
        fi
    done
    echo ""
    
    # Check audit log integrity
    echo "3. AUDIT LOG INTEGRITY:"
    echo "----------------------"
    
    local recent_changes
    recent_changes=$(find "$AUDIT_DIR" -name "*.json" -mtime -1 | wc -l | tr -d ' ')
    
    if [[ "$recent_changes" -eq 0 ]]; then
        compliance_warnings+=("No admin rights changes in last 24 hours")
        echo "  ℹ️  No admin rights changes recorded in last 24 hours"
    else
        echo "  ✅ $recent_changes admin rights changes recorded in last 24 hours"
    fi
    echo ""
    
    # Generate compliance summary
    echo "4. COMPLIANCE SUMMARY:"
    echo "---------------------"
    
    if [[ ${#compliance_issues[@]} -eq 0 ]]; then
        echo "  ✅ No critical compliance issues found"
    else
        echo "  ❌ Critical compliance issues found:"
        for issue in "${compliance_issues[@]}"; do
            echo "    - $issue"
        done
    fi
    
    if [[ ${#compliance_warnings[@]} -gt 0 ]]; then
        echo "  ⚠️  Warnings:"
        for warning in "${compliance_warnings[@]}"; do
            echo "    - $warning"
        done
    fi
    
    echo ""
    echo "Recommendations:"
    echo "• Review and remediate any unauthorized permanent admin accounts"
    echo "• Implement regular compliance checks (daily/weekly)"
    echo "• Enable real-time monitoring for admin rights changes"
    echo "• Establish clear admin rights governance policies"
    echo "• Regular audit of admin activities and justifications"
    
    # Return appropriate exit code
    if [[ ${#compliance_issues[@]} -gt 0 ]]; then
        return 1
    else
        return 0
    fi
}

check_admin_compliance

Important Technical Notes

DSCL Command Reference

  • dscl . -append /Groups/admin GroupMembership <user>: Add user to admin group
  • dscl . -delete /Groups/admin GroupMembership <user>: Remove user from admin group
  • dscl . -read /Groups/admin GroupMembership: List all admin group members
  • dscl . -read /Users/<user>: Get detailed user information

Security Considerations

  1. Principle of Least Privilege: Grant minimum necessary privileges for minimum time
  2. Audit Trail: Maintain comprehensive logs of all admin rights changes
  3. Approval Workflow: Implement approval processes for admin rights grants
  4. Time Limits: Always use temporary admin rights with automatic expiration
  5. Monitoring: Real-time monitoring of admin activities and suspicious behavior

Compliance Requirements

  1. Documentation: Maintain detailed records of admin rights grants and revocations
  2. Justification: Require business justification for all privilege escalations
  3. Regular Audits: Perform regular compliance checks and reviews
  4. Protected Accounts: Safeguard critical system accounts from modification
  5. Retention Policies: Implement appropriate log retention and archival

Enterprise Use Cases

  1. Software Installation: Temporary admin rights for application installations
  2. System Maintenance: Scheduled admin access for maintenance windows
  3. Emergency Response: Rapid privilege escalation for incident response
  4. Compliance Auditing: Regular reviews of admin rights and activities
  5. Zero Trust Security: Continuous verification and minimal privilege access

Remember to test all scripts on individual devices before deploying across your MacFleet environment, and ensure compliance with corporate security policies and regulatory requirements when implementing enterprise admin rights management systems.

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.