Arquitectura y límites de autoridad¶
BloqueApp combina un cliente Android de aplicación de reglas, un servicio ASP.NET Core, un almacén SQLite y una pequeña aplicación web para la persona que aprueba solicitudes. Cada componente tiene una función delimitada: el servicio autentica y registra decisiones, mientras el teléfono aplica localmente la política verificada.
Para los flujos cotidianos, consulte la guía de uso. Los conceptos compartidos explican la política, las autorizaciones de la persona aprobadora, las solicitudes, las reglas de descanso y el funcionamiento sin conexión. El glosario reúne los términos y limitaciones describe los límites actuales.
flowchart LR
Phone[Teléfono Android<br/>política y aplicación locales]
API[API ASP.NET Core]
DB[(SQLite)]
Page[Página de aprobación]
SW[Service worker del navegador]
Push[Servicio Web Push]
Hub[Hub SignalR autenticado]
Phone <-->|HTTPS: política, solicitudes, comprobantes| API
API <--> DB
Page <-->|HTTPS del mismo origen: decisiones y comprobantes| API
API -->|cola duradera de entrega| Push
Push --> SW
SW -->|abrir o enfocar la página| Page
API -->|aviso de cambio de mejor esfuerzo| Hub
Hub -->|conexión en primer plano| Phone
El diagrama muestra vías de comunicación, no autoridades intercambiables. Las notificaciones push y SignalR son avisos de entrega. SQLite conserva las decisiones y los datos firmados de política o autorización constituyen la autoridad durable.
Cliente Android¶
La aplicación Android está escrita en Java nativo y usa Views de la plataforma. Su evaluador local AccessPolicy interpreta una instantánea aceptada, la pertenencia de paquetes, los horarios de descanso y una autorización activa. RuntimePolicyEnforcer reconcilia esa decisión con la suspensión de paquetes de Android y la expiración programada. La evaluación local no consulta el servidor por cada cambio de aplicación.
El servicio firma la instantánea de política y la vincula al dispositivo y a la asociación emparejada. El cliente verifica la firma con una clave pública configurada como parámetro de confianza del APK, valida el documento acotado y guarda atómicamente la envoltura aceptada. El estado de aplicación de reglas y la caché de política usan almacenamiento protegido por dispositivo para poder reconciliarse antes del primer desbloqueo después de reiniciar. Las credenciales de emparejamiento se cifran con una clave respaldada por Android Keystore en almacenamiento protegido por credenciales.
La suspensión de paquetes es una acción del sistema operativo que requiere autoridad Device Owner. Puede impedir que se inicie un paquete seleccionado; no identifica ni bloquea pestañas, videos o funciones individuales dentro de otro paquete. La política no puede seleccionar aplicaciones esenciales del sistema o de recuperación, y la aplicación conserva rutas explícitas de recuperación y permisos.
Los bancos de tiempo son otra vía local. Usan eventos de uso de Android para estimar intervalos de actividad en primer plano, una sesión iniciada explícitamente por la persona y una ventana de acceso renovable de corta duración. Una muestra incierta termina la sesión sin cobrar el intervalo incierto. Consulte crédito del banco y el análisis algorítmico.
Servicio y página de aprobación¶
El servicio usa .NET 10, ASP.NET Core Minimal APIs, Microsoft.Data.Sqlite y SignalR. SQLite conserva asociaciones, hashes de sesiones de dispositivos y personas aprobadoras, solicitudes y decisiones, autorizaciones firmadas, revisiones de política, suscripciones push y la cola de entrega Web Push. La escritura de una decisión se confirma en una transacción SQLite antes de enviar un aviso en tiempo real.
La página de aprobación es una aplicación estática del mismo origen, construida con HTML, CSS, JavaScript, un manifiesto y un service worker. Una cookie Secure, HttpOnly y SameSite=Strict identifica la sesión de aprobación. Si se configura la entrega Web Push, el servidor agrega un elemento durable a la cola por cada suscripción elegible. El service worker puede mostrar una notificación aunque la página esté cerrada; una acción aún debe llegar al servidor autenticado y recibir confirmación antes de presentarse como completada.
SignalR es un transporte en primer plano para la pantalla de solicitudes Android. El hub acepta la credencial bearer de un dispositivo emparejado, limita cada conexión a ese dispositivo y envía avisos versionados RequestChanged. El teléfono responde consultando por HTTPS el comprobante durable. La reanudación de la pantalla y los reintentos también funcionan sin mensajes SignalR. Un aviso nunca aprueba una solicitud.
Topología de despliegue¶
Las propuestas de política siguen el mismo principio de estado duradero. La pantalla Android recibe avisos PolicyProposalChanged en el hub del dispositivo y consulta los recibos; una aceptación requiere verificar la política firmada actual. Las páginas abiertas de la persona aprobadora usan un hub separado en /api/v1/approver/events, autenticado mediante cookie y limitado a su asociación. Una cola duradera de propuestas reutiliza el emisor Web Push del navegador para avisos que abren la revisión autenticada con la página cerrada. Estas notificaciones no publican políticas por sí mismas; la entrega de resultados en segundo plano al Android nativo sigue pendiente.
En la configuración de producción con Compose, un contenedor ASP.NET Core sirve tanto la API como la aplicación estática de aprobación. Kestrel escucha en el puerto 8080 del contenedor; Compose lo mapea a un puerto de loopback del host, 127.0.0.1:8090 de forma predeterminada. Nginx del host termina el HTTPS público en el puerto 443 y envía las solicitudes HTTP normales a ese mapeo de loopback. El endpoint de tiempo real Android usa el mismo origen HTTPS público con una actualización a WebSocket (wss://<host-publico>/api/v1/device/events); Nginx reenvía la actualización al mismo servicio Kestrel. Esta topología no necesita exponer Kestrel públicamente ni instalar otro servidor WebSocket. En desarrollo local, Compose mapea 127.0.0.1:5080 al puerto 8080 del contenedor.
Los encabezados reenviados de esquema y dirección del cliente solo son confiables cuando se configura como proxy conocido la dirección real que Kestrel observa. El puerto del host y la dirección del proxy son ajustes de despliegue, no garantías portables. La disponibilidad en /health/ready comprueba dependencias de almacenamiento del servicio; no demuestra que una solicitud se haya aprobado, que el teléfono acepte una autorización, que una notificación push llegue al navegador ni que Android esté aplicando reglas. Consulte seguridad para conocer los límites de confianza y la guía de uso para entender la experiencia.
Límites de autoridad¶
El servicio es responsable de autenticar dispositivos y personas aprobadoras, mantener las asociaciones, registrar decisiones durables, publicar la política fuente y firmar. Comprueba que la solicitud pertenezca al dispositivo autenticado y a la asociación vigente, que el paquete y la duración estén permitidos por la política actual y que decida la persona aprobadora vinculada a esa asociación.
El teléfono toma la decisión final de aplicación local. Verifica la autorización con su configuración de confianza fijada y con el emisor, dispositivo, asociación, solicitud, paquete, identificador y revisión de política, alcance y vencimiento esperados. Una firma válida demuestra que el servidor de confianza emitió esos datos; no omite la política local vigente. El teléfono suspende un paquete solo después de que la verificación y las comprobaciones locales concluyen correctamente.
La política fuente y la política efectiva para una asociación tienen revisiones separadas. Una excepción acotada para conservar permanentemente una aplicación sin restricciones puede registrarse para una asociación, pero no constituye un editor general ni reemplaza cualquier política fuente. Una restricción fuente explícita posterior elimina la excepción correspondiente. El teléfono evalúa el acceso local con la política efectiva firmada más reciente.
El navegador gestiona la interacción de aprobación, no el acceso del dispositivo. Su cookie no autentica como el dispositivo Android y la página no recibe sus credenciales. Esta separación permite que el teléfono aplique localmente la última política aceptada mientras el navegador o el servicio no están disponibles, pero impide obtener una nueva autorización de otra persona sin conexión.
Funcionamiento sin conexión y compromisos¶
Sin conectividad, el teléfono puede seguir evaluando una política firmada aceptada previamente y reconciliar localmente el estado de sus paquetes y sus vencimientos. No puede obtener una política nueva ni una nueva autorización firmada. Una autorización ya aceptada conserva su vencimiento absoluto cuando cambia la política, mientras se siguen aplicando la pertenencia actual del paquete y las reglas de descanso. El teléfono observa una actualización de política o una revocación de asociación cuando vuelve a conectarse; sin conexión no puede conocer un cambio que todavía no recibió.
El servicio conserva la autoridad sobre las decisiones durables. El comprobante guardado en el teléfono ayuda a recuperarse de una respuesta perdida, pero por sí mismo no permite abrir una aplicación. Si falla la consulta de un comprobante, el cliente reintenta dentro de límites de recuperación en primer plano; no envía otra solicitud diferente ni infiere una aprobación a partir de una notificación.
Esta elección prioriza la aplicación local y la recuperación acotada frente a depender de la red dentro de un callback de Android. Su límite es que una revocación remota no surte efecto en un teléfono desconectado hasta que este la recibe; por eso las autorizaciones tienen vencimientos finitos y el cliente aplica de inmediato los horarios y las restricciones locales que ya conoce.
Alcance¶
La aplicación de reglas implementada opera a nivel de paquete: no puede controlar pestañas individuales ni el contenido dentro de una aplicación, y no ofrece controles de navegador o dominio. La aplicación también depende del aprovisionamiento real como Device Owner y de las capacidades de suspensión de paquetes disponibles en cada versión y dispositivo Android. No interprete indicadores de estado del servicio ni un servicio activo como prueba de un modo estricto. Consulte las limitaciones y la guía de uso.