# MacLockdown — Privileged Helper Architecture v01

**Fecha:** 2026-03-17  
**Estado:** diseño técnico aprobado para siguiente fase  
**Impacto en funcionalidad actual:** ninguno; documento de arquitectura y plan de migración

---

## 1. Objetivo

Definir el salto desde el modelo actual de privilegios:

- `NSAppleScript`
- `do shell script ... with administrator privileges`
- ejecución dinámica de comandos root

hacia un modelo más robusto:

- helper privilegiado formal
- `LaunchDaemon` registrado desde el bundle
- IPC explícito
- superficie privilegiada reducida

Este documento no cambia la versión actual de `MacLockdown.app`.

Su función es dejar una ruta de implementación que no rompa producto ni UX.

---

## 2. Por qué hacer este cambio

El modelo actual fue suficiente para beta y permitió validar:

- batching de fixes privilegiados
- menos prompts de contraseña
- mejor consistencia post-fix

Pero sigue teniendo límites serios:

1. el proceso UI sigue disparando root vía AppleScript
2. la app sigue construyendo scripts shell completos en memoria
3. la frontera de privilegios sigue siendo demasiado amplia
4. la historia de seguridad frente a auditoría sigue siendo débil
5. no existe un “allowlist” fuerte de operaciones privilegiadas

En términos de producto, esto limita dos narrativas futuras:

- `trusted fix engine`
- `secure execution layer`

---

## 3. Referencias Apple usadas

Este diseño se apoya en documentación oficial de Apple:

- `SMAppService`
  - controla helpers dentro del bundle para `LaunchAgents` y `LaunchDaemons`
- `Authorization Services`
  - permite pedir y preautorizar derechos sin capturar la contraseña en la app
- `XPC`
  - canal recomendado para IPC entre app y daemon

Notas relevantes de Apple:

- en macOS 13+ `SMAppService` es la vía moderna para registrar `LaunchDaemons`
- `LaunchDaemons` requieren aprobación admin
- Apple recomienda XPC para comunicación con daemons/agents
- `Authorization Services` delega la autenticación al sistema y evita que la app gestione directamente la contraseña

---

## 4. Objetivos de seguridad

El helper privilegiado debe mejorar estos puntos:

1. **La UI nunca debe manejar la contraseña**
2. **El proceso principal no debe construir shell root genérico**
3. **Las operaciones privilegiadas deben estar cerradas por allowlist**
4. **Cada operación privilegiada debe mapear a una intención de producto concreta**
5. **La verificación post-fix debe seguir siendo soportada**
6. **La migración no debe romper `Apply Fix` ni `Apply All Fixes`**

Objetivo de memoria:

- reducir el valor de un dump del proceso principal
- minimizar strings privilegiados persistentes en heap
- evitar almacenar comandos root arbitrarios o credenciales en estructuras largas

---

## 5. Arquitectura propuesta

```text
MacLockdown.app
├── UI / ViewModel
├── ScanEngine
├── ReportEngine
└── PrivilegedClient
      │
      │  XPC / NSXPCConnection
      ▼
MacLockdownPrivilegedHelper
├── operación allowlisted
├── validación de parámetros
├── ejecución privilegiada controlada
└── respuesta estructurada
```

### Separación de responsabilidades

**App principal**

- descubre controles
- calcula score
- decide qué operación necesita
- muestra UI
- recibe resultados

**Helper privilegiado**

- ejecuta operaciones root permitidas
- valida argumentos
- expone resultados estructurados
- no renderiza UI
- no conoce pricing, CTI, score ni lógica comercial

---

## 6. Operaciones permitidas

El helper no debe aceptar `bash -c` arbitrario.

Debe exponer un set pequeño de operaciones semánticas, por ejemplo:

- `enableFirewall`
- `enableStealthMode`
- `disableRemoteLogin`
- `disableRemoteManagement`
- `disablePrinterSharing`
- `disableWakeOnNetwork`
- `setSudoTimeoutZero`
- `disableAutoLogin`
- `disableAppleRemoteEvents`
- `disableInternetSharing`

Cada una debe:

- recibir solo parámetros mínimos
- validar entradas
- ejecutar comandos internos definidos por código del helper
- devolver:
  - `success`
  - `exitCode`
  - `stdout/stderr` reducidos o sanitizados
  - `verificationPayload`

No permitido:

- shell libre
- rutas arbitrarias desde UI
- argumentos arbitrarios concatenados desde JSON
- ejecución de comandos no modelados

---

## 7. Modelo de IPC

### Canal recomendado

- `NSXPCConnection` sobre un `LaunchDaemon`

### Protocolo esperado

```text
PrivilegedHelperProtocol
├── perform(operation:parameters:reply:)
├── verify(operation:reply:)
└── getVersion(reply:)
```

### Respuesta

```text
PrivilegedOperationResult
├── success: Bool
├── exitCode: Int32
├── message: String
├── sanitizedOutput: String
└── verification: [String: String]
```

`sanitizedOutput` existe para:

- troubleshooting mínimo
- no volcar demasiado estado sensible en memoria/UI/logs

---

## 8. Autorización

### Modelo recomendado

- usar `Authorization Services` desde la app para pedir derechos antes de registrar o usar el helper
- dejar que la autenticación la haga el sistema
- no recoger la contraseña en UI propia

### Implicaciones

- sigue existiendo prompt del sistema
- la app no guarda la contraseña
- la autorización puede preautorizarse para reducir fricción

### Importante

Apple indica que `Authorization Services` no funciona dentro de App Sandbox cuando implica escalación de privilegios.

Eso es compatible con la naturaleza actual del producto.

---

## 9. Service Management

### Registro

Usar `SMAppService` para registrar el helper empaquetado en el bundle.

Estructura objetivo:

```text
MacLockdown.app
└── Contents
    └── Library
        └── LaunchDaemons
            └── com.maclockdown.privilegedhelper.plist
```

Y un binario helper asociado dentro del bundle firmado.

### Consideraciones

- el daemon requiere aprobación admin
- el usuario debe entender por qué existe
- la app debe verificar estado de registro y aprobación
- si falta autorización, debe guiar a la persona a System Settings

---

## 10. Estrategia de migración

### Fase 1 — Diseño y preparación

- definir operaciones allowlisted
- mapear cada fix privilegiado actual a una operación
- introducir `PrivilegedClient` como capa abstracta

### Fase 2 — Cliente dual

- `FixEngine` deja de llamar directamente a `ShellEngine.runPrivileged`
- pasa a llamar a una abstracción:
  - `PrivilegedExecutor`
- implementaciones:
  - `AppleScriptPrivilegedExecutor`
  - `HelperPrivilegedExecutor`

Objetivo:

- no romper la funcionalidad actual
- poder alternar por feature flag

### Fase 3 — Helper PoC

- helper con 1 o 2 operaciones
  - `enableFirewall`
  - `setSudoTimeoutZero`
- validación de instalación
- validación de IPC

### Fase 4 — Migración progresiva

- migrar primero fixes privilegiados de bajo riesgo
- mantener AppleScript como fallback temporal
- medir prompts, errores y resultados

### Fase 5 — Retiro del modelo viejo

- eliminar `runPrivileged(_:)` genérico para fixes productivos
- conservarlo solo como fallback de dev si fuera necesario

---

## 11. Cambios de código esperados

Archivos probables:

- nuevo target helper
- nuevo `PrivilegedClient.swift`
- nuevo protocolo XPC compartido
- [FixEngine.swift](/Users/jeeydee/Documents/PRY_MACLOCKDOWN/Dev/MacLockdown/MacLockdown/FixEngine.swift)
- [ShellEngine.swift](/Users/jeeydee/Documents/PRY_MACLOCKDOWN/Dev/MacLockdown/MacLockdown/ShellEngine.swift)
- [AdminSession.swift](/Users/jeeydee/Documents/PRY_MACLOCKDOWN/Dev/MacLockdown/MacLockdown/MacLockdown/AdminSession.swift)
- [SecurityViewModel.swift](/Users/jeeydee/Documents/PRY_MACLOCKDOWN/Dev/MacLockdown/MacLockdown/SecurityViewModel.swift)

Cambios de proyecto:

- signing
- entitlements
- packaging del daemon
- plist del `LaunchDaemon`

---

## 12. Riesgos

### Riesgo técnico

- setup de signing más delicado
- errores de instalación del daemon
- debugging más complejo que AppleScript

### Riesgo de producto

- puede aumentar complejidad si se intenta migrar todo de una sola vez

### Riesgo de distribución

- notarización
- provisioning
- cambios en pipeline de build y packaging

---

## 13. Decisión recomendada

Sí conviene hacer el salto.

Pero no como refactor directo dentro de la versión actual.

La secuencia correcta es:

1. aprobar esta arquitectura
2. introducir abstracción `PrivilegedExecutor`
3. construir PoC de helper con pocas operaciones
4. migrar gradualmente

Eso permite avanzar en seguridad real sin afectar funcionalidades ya validadas.

---

## 14. Resultado esperado cuando se implemente

MacLockdown pasaría de:

`root via AppleScript + shell commands`

a:

`privileged daemon + allowlisted operations + structured IPC`

Eso mejora:

- seguridad
- auditabilidad
- control de memoria útil para un atacante
- coherencia con un producto que pretende vender hardening serio
