Empresa — Inscripción y flota
Una única copia de Bromure Agentic Coding es una herramienta personal. En un equipo, un administrador a menudo necesita responder preguntas organizativas: qué Macs están ejecutando la app, qué paquetes están incorporando los agentes, cuántos tokens se están gastando y si algún espacio de trabajo activó un detector de inyección de prompts. La inscripción con Bromure Enterprise Manager — un espacio de trabajo en bromure.io — proporciona exactamente esa visibilidad de la flota, transmitiendo metadatos de sesión (nunca prompts, nunca secretos) desde cada Mac inscrito.
Este capítulo trata sobre la inscripción de un Mac, la identidad mTLS que autentica sus cargas, exactamente qué se carga y qué no, la exclusión por espacio de trabajo, la vista de flota del administrador, la gestión del consentimiento remoto y la baja. El trazado local — el registro de auditoría en el Mac que la inscripción no reemplaza — se cubre en Trazado; el inventario de paquetes que alimenta la generación de informes empresariales es Protección de la cadena de suministro.
Dos sistemas independientes
La palabra "flota" abarca dos funciones que conviene mantener distintas, porque no comparten ninguna raíz de confianza:
- La inscripción en bromure.io (este capítulo) registra un Mac en tu espacio de trabajo y transmite los metadatos de sesión a la nube, autenticados por un certificado TLS mutuo emitido por la CA de tu organización.
- El cliente enriquecido (Acceso remoto) permite que un Mac replique las instancias en ejecución de otros Macs a través de SSH, autenticadas por claves de anfitrión SSH y claves públicas inscritas.
Ninguno depende del otro. Puedes inscribirte sin usar nunca el cliente enriquecido, replicar anfitriones sin inscribir ninguno de ellos, o hacer ambas cosas. La pila mTLS de la inscripción es únicamente telemetría de flota; la réplica del cliente enriquecido confía en SSH — las dos deliberadamente no se fusionan en esta versión.
Inscripción con Bromure Enterprise Manager
La inscripción se basa en códigos. Un administrador genera un código de inscripción de seis palabras de un solo uso en la página de detalles de tu usuario en bromure.io, delimitado a la app agentic-coding. Pegas ese código en la app (o en la CLI) y el Mac se registra a sí mismo como una instalación del espacio de trabajo.
Desde la app
- Obtén un código de inscripción de seis palabras de tu administrador.
- Abre Bromure Agentic Coding (el menú con el nombre de la app) → Inscribir en bromure.io… — el elemento se encuentra justo debajo de Buscar actualizaciones…. Se abre una ventana titulada Inscripción en bromure.io.
- Pega el código en el campo Código de inscripción (marcador de posición:
six-word-enrollment-code). - Opcionalmente edita Nombre del dispositivo (por defecto es el nombre de este Mac; texto de ayuda: "Se muestra a tu administrador para que pueda reconocer este Mac.").
- Opcionalmente expande Avanzado y establece URL del servidor (opcional) para un servidor autoalojado o de preproducción.
- Haz clic en Inscribir (Intro) o Cancelar (Esc).
La hoja indica claramente qué activa la inscripción: "envía metadatos de sesión (herramientas, archivos, comandos, uso de tokens) a tu espacio de trabajo para que los administradores puedan revisar la actividad. Los espacios de trabajo en modo privado nunca transmiten". Al tener éxito, la instalación aparece en la página /agentic-coding/installs del administrador.
Nota: Algún texto de ayuda dentro de la app todavía dice "Abre Ventana → Inscribir en bromure.io…", pero el elemento en realidad reside en el menú de la aplicación (nombre de la app) — esa es la ubicación autorizada. Un código generado para una app de Bromure diferente se rechaza con Code was issued for app '…', expected 'agentic-coding'., y una segunda inscripción falla con Bromure Agentic Coding is already enrolled.
Desde la CLI
Los flujos de la GUI tienen equivalentes exactos en la CLI, agrupados bajo Enterprise features en bromure-cli --help y compartiendo el mismo almacén en disco. Son útiles para el aprovisionamiento con scripts o para la inscripción a través de una sesión SSH existente.
| Comando | Qué hace |
|---|---|
bromure-cli enroll --code <code> [--server-url <url>] [--device-name <name>] | Inscribe este Mac. Imprime el correo electrónico, el espacio de trabajo, el ID de instalación, el servidor y el dispositivo al tener éxito; sale con un valor distinto de cero en caso de fallo. |
bromure-cli enrollment-status | Imprime el estado actual. Cuando no está inscrito, imprime not enrolled y sale con 0, de modo que la automatización pueda sondear con seguridad. |
bromure-cli unenroll [--force] | Cierra la sesión (consulta Revocación, baja y cancelación de inscripción). |
Los valores predeterminados coinciden con la GUI: URL del servidor https://bromure.io/api (anulable mediante BROMURE_MANAGED_URL o la clave de UserDefaults managed.serverURL), y el nombre del dispositivo es el nombre de anfitrión localizado del Mac.
La identidad de instalación mTLS
Las cargas de telemetría no llevan un token — se autentican con un certificado de cliente. En la inscripción (y en cada renovación) la app genera una clave RSA-2048 nueva, construye una solicitud de firma de certificado con el nombre común bromure-install-<installId>, y hace que la CA de la organización de tu espacio de trabajo la firme a través del servidor gestionado. Los certificados de hoja y de CA se almacenan como archivos PEM inspeccionables; la clave privada reside en el Llavero de macOS.
En el momento de la solicitud, el certificado y la clave se empaquetan en un PKCS#12 en memoria y se importan sin tocar el Llavero, de modo que nunca aparece ninguna entrada de Acceso a Llaveros ni ninguna solicitud de desbloqueo para la identidad en sí. El propio certificado de servidor del punto final de analítica se valida contra el almacén de raíces del sistema habitual.
Nota: La solicitud del certificado de hoja durante la inscripción es de mejor esfuerzo. Si la CA de la organización aún no está configurada, la inscripción sigue teniendo éxito y el certificado se obtiene en el primer latido.
El panel de estado de inscripción
Una vez inscrito, el mismo elemento de menú se renombra a Inscripción en bromure.io… y abre un panel de estado (título Inscripción en bromure.io) en lugar del formulario de entrada. Muestra las filas Espacio de trabajo, Usuario, Dispositivo, Servidor, Inscrito (fecha) y Certificado — todas seleccionables como texto. La fila Certificado muestra Válido hasta <date> o, si caducó, Caducado — renovando automáticamente.
Hay dos botones en la parte inferior: Renovar certificado fuerza un nuevo certificado de hoja; Cerrar sesión cancela la inscripción (destructivo — consulta más abajo). Los problemas de estado aparecen como un banner de advertencia naranja:
| Banner | Significado | Qué hacer |
|---|---|---|
| Inscripción revocada | "Tu administrador revocó esta instalación. Cierra la sesión e inscríbete de nuevo con un nuevo código para reanudar el modo gestionado." | Cierra la sesión e inscríbete con un código nuevo. |
| Inscripción ya no aceptada | "El servidor rechazó las credenciales de esta instalación — pueden haber caducado o haber sido restablecidas." | Cierra la sesión e inscríbete con un código nuevo. |
Una Renovar certificado exitosa borra un estado obsoleto de rechazo de credenciales, pero nunca borra un estado revocado — solo la reinscripción lo hace.
Latido y renovación de certificados
Mientras la app se ejecuta inscrita, una tarea en segundo plano publica un latido en el servidor del espacio de trabajo cada 10 minutos (y una vez inmediatamente al iniciar y al inscribirse), lo que mantiene actualizada la marca de tiempo de última visualización del administrador. La respuesta del servidor es autoritativa para el estado: una revocación cambia el banner; una respuesta limpia borra los estados incorrectos anteriores. Solo un 401/403 en el token portador del latido cambia el estado a "token rechazado" — los errores transitorios (sin conexión, 5xx) nunca lo cambian.
Cada tic de latido también comprueba el certificado de hoja mTLS y lo renueva siempre que falte o esté dentro de las 72 hours de su caducidad. La renovación se autentica con el token portador en lugar de la hoja, de modo que incluso un certificado ya caducado se recupera en el siguiente inicio.
Advertencia: Un Mac que se deje cerrado más allá de la caducidad de su certificado falla silenciosamente en las cargas gestionadas hasta que el siguiente inicio renueve la hoja. Esto es transparente en el uso normal, pero conviene saberlo si una máquina permanece apagada durante mucho tiempo.
Qué se carga — y qué no
Las sesiones inscritas y no privadas transmiten eventos de nube estructurados — un registro cada uno: id de sesión, id de espacio de trabajo, marca de tiempo, tipo de evento y una pequeña carga útil JSON. Aquí las sesiones son ventanas de actividad, no ciclos de vida de la VM: un id de sesión por espacio de trabajo por ventana de actividad, que se renueva tras 20 minutos de inactividad.
| Evento | Aspectos destacados de la carga útil |
|---|---|
session.start / session.end | Inicio y fin de una ventana de actividad; session.end lleva un motivo (p. ej. idle_timeout) y se retrotrae al límite de inactividad. |
llm.request | Proveedor, anfitrión, ruta, código de estado, latencia, modelo y recuentos de tokens de entrada/salida/caché. Las sesiones WebSocket en tiempo real añaden el transporte y el id de respuesta. |
tool.use | Nombre de la herramienta y un resumen de entrada (truncado a 240 caracteres). |
file.read / file.write | Ruta del archivo y la herramienta que lo tocó. |
command.run | El texto del comando (truncado a 500 caracteres) y la herramienta. |
credential.token_swap | Anfitrión y ruta, y breves vistas previas de los tokens falso y real — nunca los tokens en sí. |
credential.ssh_sign | Etiqueta de clave, huella SHA-256 y tipo de clave (gestionada / importada). |
credential.aws_sign | Método, anfitrión, ruta, servicio, región y una clave de acceso enmascarada. |
supply_chain.fetch | Ecosistema, paquete, versión, tipo de solicitud, resultado y motivo. |
vm.disk_reset | El motivo y las versiones de imagen base implicadas. |
prompt_injection.detection | Detector, método, acción, anfitrión, origen, puntuación, señales, id de uso de herramienta y todo el fragmento marcado (hasta 20.000 caracteres). |
El estado de transmisión es visible en cada ventana de sesión y se refleja en los informes de flota que ve un administrador.
Qué nunca sale del Mac
Esta es la parte que hay que precisar. El flujo son metadatos; el contenido de tu trabajo permanece local. Bromure nunca carga:
- Prompts de usuario sin procesar ni cuerpos de respuesta del modelo.
- Valores de secretos. Los eventos de credenciales solo llevan vistas previas enmascaradas o huellas — los bytes reales de las claves nunca salen del Mac.
- Nada de un espacio de trabajo en modo privado (consulta más abajo), y nada en absoluto cuando no está inscrito.
Los eventos almacenados en búfer se mantienen solo en memoria; un cierre forzado descarta los que aún no se hayan enviado, y no hay cola de reintento respaldada en disco. Esto se acepta por diseño — la telemetría es de mejor esfuerzo, nunca a expensas de tu trabajo.
Advertencia: Hay una excepción deliberada a la regla de solo metadatos:
prompt_injection.detectioncarga el fragmento marcado completo (hasta 20.000 caracteres), de modo que un administrador pueda ver exactamente qué estaba a punto de leer el agente. Esto es contenido, no metadatos — la contrapartida es que un intento de inyección de prompts es precisamente lo que los equipos de seguridad necesitan inspeccionar textualmente. Todo lo demás sigue siendo vistas previas, rutas, recuentos y máscaras. Consulta Protección contra la inyección de prompts para saber qué desencadena una detección.
Agrupación en lotes y entrega
Los eventos se agrupan en lotes en memoria y se publican en el punto final de ingesta de analítica, autenticados únicamente por el certificado de hoja mTLS — ningún token portador viaja con los datos de telemetría. El búfer se vacía cada 5 segundos, se autovacía a los 200 eventos pendientes y envía como máximo 500 eventos por solicitud. Durante una interrupción prolongada, el búfer se recorta a los eventos más recientes (los más antiguos se descartan) en lugar de crecer sin límite; un vaciado fallido reintenta el mismo lote en el siguiente tic.
Modo privado
La transmisión es de exclusión por espacio de trabajo. El interruptor Modo privado (icono de ojo tachado) en el editor de un espacio de trabajo mantiene la actividad de ese espacio de trabajo enteramente local: no se transmiten metadatos, el indicador de la barra de título desaparece para él, y la lista de sesiones del administrador no ve nada de él. El Inspector de trazas local no se ve afectado — sigue registrando según su propio nivel de traza. El interruptor está desactivado (transmisión habilitada) para cada espacio de trabajo, y aparece solo en los Macs inscritos, ya que de lo contrario no haría nada.
El modo privado reside con la configuración de Trazado en el editor del espacio de trabajo. En un Mac no inscrito, el interruptor simplemente está ausente, razón por la cual el panel de abajo muestra solo el selector de trazas:
Los eventos se filtran en el momento de la emisión — el tráfico en modo privado nunca llega siquiera a entrar en el búfer de carga.
Consejo: El modo privado es el interruptor adecuado cuando usas una clave de API personal en un espacio de trabajo y no quieres que esa actividad sea visible para los administradores de tu organización. No cambia nada del registro de auditoría local.
El indicador de transmisión
Siempre que un Mac esté inscrito y un espacio de trabajo no esté en modo privado, aparece un punto rojo palpitante de estilo grabación en la barra de herramientas de esa ventana de sesión (y como un punto en las filas de la barra lateral de la ventana unificada). Su información sobre herramientas dice "Se están enviando metadatos de sesión a bromure.io. Activa el Modo privado del espacio de trabajo para detener la transmisión." y su etiqueta de accesibilidad es Transmitiendo a bromure.io. El punto es puramente informativo y se oculta cuando no está inscrito o en modo privado.
Registro de IP de salida
Las instalaciones inscritas también publican un pequeño ping autenticado por mTLS en el punto final /register-ip del servicio de analítica cada 60 segundos (y una vez al iniciar y al inscribirse), de modo que los registros del espacio de trabajo reflejen la IP pública actual del Mac. Se omite silenciosamente cuando no está inscrito. El punto final es por defecto https://analytics.bromure.io/register-ip, anulable mediante BROMURE_AC_REGISTER_IP_URL o la clave de UserDefaults managed.acRegisterIPURL.
Inventario de la cadena de suministro y agregados de uso de tokens
Dos de los tipos de evento transmitidos son los que hacen útil la generación de informes de nivel empresarial en todo un equipo.
- Inventario de la cadena de suministro. Cada obtención de metadatos y artefactos emite un evento
supply_chain.fetchque lleva el ecosistema, el paquete, la versión, el tipo de solicitud, el resultado (allowed,rewritten,blockedostripped) y el motivo. La inscripción por sí sola da a los administradores un inventario a nivel de toda la organización de cada paquete que cada agente incorporó — incluso en espacios de trabajo con todas las capas de aplicación de la cadena de suministro desactivadas, ya que la observación está desacoplada de la aplicación. El lado de la aplicación de esto se documenta en Protección de la cadena de suministro. - Agregados de uso de tokens. Cada evento
llm.requestlleva el modelo, los recuentos de tokens de entrada y salida, y los recuentos de creación de caché y lectura de caché. Agregados en una flota, estos se convierten en informes de gasto por usuario, por espacio de trabajo y por modelo sin que jamás se cargue ningún contenido de prompt o respuesta. La contraparte local — la contabilidad de tokens por solicitud que puedes leer en tu propio Mac — está en Trazado.
La vista de flota
En el lado de bromure.io, cada Mac inscrito aparece como una fila en la página /agentic-coding/installs del espacio de trabajo, identificado por su ID de instalación y mostrando el nombre de dispositivo que estableciste, el usuario y una marca de tiempo de última visualización mantenida actualizada por el latido de 10 minutos. Desde ahí, un administrador revisa los metadatos de sesión transmitidos, el inventario de la cadena de suministro, los agregados de uso de tokens y las detecciones de inyección de prompts de toda la flota.
Esto es distinto de la noción de "flota" del cliente enriquecido — replicar varios anfitriones remotos a la vez a través de SSH — que se cubre en Acceso remoto. Las dos nunca comparten una raíz de confianza.
Gestión del consentimiento remoto
Cuando una sesión de espacio de trabajo se adjunta interactivamente a través de CLI o SSH — sin ninguna ventana de GUI delante — la app no puede mostrar un diálogo. En su lugar, los cuatro intermediarios de consentimiento de tipo hombre-en-el-medio presentan sus preguntas como menús numerados en el terminal del usuario adjunto:
| Prompt | Opciones |
|---|---|
Uso de credencial — Allow "<workspace>" to use <credential>? | Permitir durante 1 hora / Permitir durante 5 minutos / Permitir durante el resto de la sesión / No permitir |
Omisión de la cadena de suministro — Pass through <package> from workspace …? | Permitir durante 15 minutos / Permitir una vez / Permitir durante el resto de la sesión / No permitir |
Escritura con salvaguardas — Allow write on … from workspace …? | (las mismas cuatro que arriba) |
Inyección de prompts — Possible <detector> in … (muestra hasta 1.500 caracteres del texto marcado) | Bloquear esta solicitud / Permitir esta solicitud |
La propiedad crucial es dónde se presenta el prompt: en el lado del anfitrión de la bomba del terminal. La VM invitada solo ve el otro lado de la conexión, de modo que un invitado comprometido no puede ni leer el prompt ni inyectar una respuesta. Si varios clientes se adjuntan al mismo espacio de trabajo, la conexión interactiva más reciente recibe los prompts ("gana la conexión más reciente").
Advertencia: Estos prompts fallan de forma segura. Ninguna conexión activa, un tiempo de espera agotado (120 segundos por defecto), un descarte o una desconexión a mitad del prompt se resuelven todos como denegar — y, para la inyección de prompts, como bloquear. Una alerta de fallo de autenticación de registro se suprime a una línea de registro para las sesiones adjuntas interactivamente, ya que no hay GUI que la muestre. Las rutas de la GUI para estas mismas decisiones se cubren en Credenciales, Protección de la cadena de suministro y Protección contra la inyección de prompts.
Revocación, baja y cancelación de inscripción
Hay dos maneras en que una instalación abandona la flota, y hacen cosas diferentes.
Cancelar la inscripción (local). Haz clic en Cerrar sesión en el panel de estado de inscripción, o ejecuta bromure-cli unenroll. La CLI pregunta Sign out of <org> (<email>)? [y/N] a menos que pases --force, e imprime not enrolled — nothing to do (salida 0) cuando no hay nada que eliminar. Cerrar la sesión elimina todo el material de inscripción local — install.json, leaf.crt, ca.crt, leaf.serial y el archivo de estado —, elimina el token portador y todas las claves privadas de hoja del Llavero, purga la identidad mTLS en caché, descarta cualquier telemetría almacenada en búfer, y detiene las tareas de latido y de registro de IP. La app vuelve al estado No inscrito, y la ventana de estado vuelve al formulario de inscripción para que puedas volver a inscribirte de inmediato con un código diferente.
Revocar (del lado del servidor). Un administrador revoca la instalación en bromure.io. En el Mac, el siguiente latido muestra el banner Inscripción revocada y las cargas gestionadas se detienen.
Advertencia: El cierre de sesión es puramente local — no se realiza ninguna llamada al servidor. Un administrador que retire un dispositivo debería revocar la instalación del lado del servidor; de lo contrario, la fila de instalación (ahora inactiva) permanece en la página de la flota hasta que deje de enviar latidos. Para dar de baja por completo un Mac, revócalo en el espacio de trabajo y cierra la sesión en el dispositivo.
Referencia
El estado de inscripción reside en ~/Library/Application Support/BromureAC/managed/: install.json (ID de instalación, slug del espacio de trabajo, usuario, URL del servidor, nombre del dispositivo, fecha de inscripción), leaf.crt y ca.crt (PEM), leaf.serial (un puntero a la entrada del Llavero que contiene la clave de la hoja actual) y health (ok / tokenRejected / revoked). En el Llavero de macOS, el servicio io.bromure.agentic-coding.managed-install contiene el portador install-token y una entrada leaf-cert-key-<serialHex> por cada número de serie de certificado emitido (solo este dispositivo, cuando esté desbloqueado).
El cliente se pone en contacto con tres rutas del servidor gestionado y un punto final de ingesta:
POST {server}/v1/enroll (code redemption)
POST {server}/v1/installs/{installId}/heartbeat (Bearer)
POST {server}/v1/installs/{installId}/cert (Bearer + CSR PEM)
POST {ingest URL} {"events":[…]} (mTLS, no bearer)
| Intervalo / límite | Valor |
|---|---|
| Latido | cada 10 minutos |
| Registro de IP de salida | cada 60 segundos |
| Umbral de renovación de la hoja | 72 horas antes de la caducidad |
| Vaciado de eventos | cada 5 segundos (o a los 200 pendientes) |
| Máximo de eventos por lote | 500 |
| Renovación por inactividad de sesión | 20 minutos |
| Tiempo de espera del consentimiento remoto | 120 segundos |
| Límite del fragmento de inyección de prompts | 20.000 caracteres |
Las anulaciones de servidor y de punto final (sin GUI) son BROMURE_MANAGED_URL (o managed.serverURL, por defecto https://bromure.io/api), BROMURE_AC_INGEST_URL (o managed.acIngestURL, por defecto https://analytics.bromure.io/ac-ingest), y BROMURE_AC_REGISTER_IP_URL (o managed.acRegisterIPURL). La referencia completa de comandos está en Automatización y la CLI.